Browse Source

Rename CCoinsCacheEntry::coins to coin

0.15
Pieter Wuille 8 years ago
parent
commit
73de2c1ff3
  1. 44
      src/coins.cpp
  2. 4
      src/coins.h
  3. 14
      src/test/coins_tests.cpp
  4. 4
      src/txdb.cpp

44
src/coins.cpp

@ -42,19 +42,19 @@ CCoinsMap::iterator CCoinsViewCache::FetchCoins(const COutPoint &outpoint) const
if (!base->GetCoins(outpoint, tmp)) if (!base->GetCoins(outpoint, tmp))
return cacheCoins.end(); return cacheCoins.end();
CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first; CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
if (ret->second.coins.IsPruned()) { if (ret->second.coin.IsPruned()) {
// The parent only has an empty entry for this outpoint; we can consider our // The parent only has an empty entry for this outpoint; we can consider our
// version as fresh. // version as fresh.
ret->second.flags = CCoinsCacheEntry::FRESH; ret->second.flags = CCoinsCacheEntry::FRESH;
} }
cachedCoinsUsage += ret->second.coins.DynamicMemoryUsage(); cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
return ret; return ret;
} }
bool CCoinsViewCache::GetCoins(const COutPoint &outpoint, Coin &coin) const { bool CCoinsViewCache::GetCoins(const COutPoint &outpoint, Coin &coin) const {
CCoinsMap::const_iterator it = FetchCoins(outpoint); CCoinsMap::const_iterator it = FetchCoins(outpoint);
if (it != cacheCoins.end()) { if (it != cacheCoins.end()) {
coin = it->second.coins; coin = it->second.coin;
return true; return true;
} }
return false; return false;
@ -68,17 +68,17 @@ void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possi
std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>()); std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>());
bool fresh = false; bool fresh = false;
if (!inserted) { if (!inserted) {
cachedCoinsUsage -= it->second.coins.DynamicMemoryUsage(); cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
} }
if (!possible_overwrite) { if (!possible_overwrite) {
if (!it->second.coins.IsPruned()) { if (!it->second.coin.IsPruned()) {
throw std::logic_error("Adding new coin that replaces non-pruned entry"); throw std::logic_error("Adding new coin that replaces non-pruned entry");
} }
fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY); fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY);
} }
it->second.coins = std::move(coin); it->second.coin = std::move(coin);
it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0); it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0);
cachedCoinsUsage += it->second.coins.DynamicMemoryUsage(); cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
} }
void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) { void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) {
@ -94,15 +94,15 @@ void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight) {
void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) { void CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
CCoinsMap::iterator it = FetchCoins(outpoint); CCoinsMap::iterator it = FetchCoins(outpoint);
if (it == cacheCoins.end()) return; if (it == cacheCoins.end()) return;
cachedCoinsUsage -= it->second.coins.DynamicMemoryUsage(); cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
if (moveout) { if (moveout) {
*moveout = std::move(it->second.coins); *moveout = std::move(it->second.coin);
} }
if (it->second.flags & CCoinsCacheEntry::FRESH) { if (it->second.flags & CCoinsCacheEntry::FRESH) {
cacheCoins.erase(it); cacheCoins.erase(it);
} else { } else {
it->second.flags |= CCoinsCacheEntry::DIRTY; it->second.flags |= CCoinsCacheEntry::DIRTY;
it->second.coins.Clear(); it->second.coin.Clear();
} }
} }
@ -113,13 +113,13 @@ const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
if (it == cacheCoins.end()) { if (it == cacheCoins.end()) {
return coinEmpty; return coinEmpty;
} else { } else {
return it->second.coins; return it->second.coin;
} }
} }
bool CCoinsViewCache::HaveCoins(const COutPoint &outpoint) const { bool CCoinsViewCache::HaveCoins(const COutPoint &outpoint) const {
CCoinsMap::const_iterator it = FetchCoins(outpoint); CCoinsMap::const_iterator it = FetchCoins(outpoint);
return (it != cacheCoins.end() && !it->second.coins.IsPruned()); return (it != cacheCoins.end() && !it->second.coin.IsPruned());
} }
bool CCoinsViewCache::HaveCoinsInCache(const COutPoint &outpoint) const { bool CCoinsViewCache::HaveCoinsInCache(const COutPoint &outpoint) const {
@ -144,12 +144,12 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
if (itUs == cacheCoins.end()) { if (itUs == cacheCoins.end()) {
// The parent cache does not have an entry, while the child does // The parent cache does not have an entry, while the child does
// We can ignore it if it's both FRESH and pruned in the child // We can ignore it if it's both FRESH and pruned in the child
if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coins.IsPruned())) { if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsPruned())) {
// Otherwise we will need to create it in the parent // Otherwise we will need to create it in the parent
// and move the data up and mark it as dirty // and move the data up and mark it as dirty
CCoinsCacheEntry& entry = cacheCoins[it->first]; CCoinsCacheEntry& entry = cacheCoins[it->first];
entry.coins = std::move(it->second.coins); entry.coin = std::move(it->second.coin);
cachedCoinsUsage += entry.coins.DynamicMemoryUsage(); cachedCoinsUsage += entry.coin.DynamicMemoryUsage();
entry.flags = CCoinsCacheEntry::DIRTY; entry.flags = CCoinsCacheEntry::DIRTY;
// We can mark it FRESH in the parent if it was FRESH in the child // We can mark it FRESH in the parent if it was FRESH in the child
// Otherwise it might have just been flushed from the parent's cache // Otherwise it might have just been flushed from the parent's cache
@ -162,21 +162,21 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn
// parent cache entry has unspent outputs. If this ever happens, // parent cache entry has unspent outputs. If this ever happens,
// it means the FRESH flag was misapplied and there is a logic // it means the FRESH flag was misapplied and there is a logic
// error in the calling code. // error in the calling code.
if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coins.IsPruned()) if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsPruned())
throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs"); throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
// Found the entry in the parent cache // Found the entry in the parent cache
if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) { if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsPruned()) {
// The grandparent does not have an entry, and the child is // The grandparent does not have an entry, and the child is
// modified and being pruned. This means we can just delete // modified and being pruned. This means we can just delete
// it from the parent. // it from the parent.
cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage(); cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
cacheCoins.erase(itUs); cacheCoins.erase(itUs);
} else { } else {
// A normal modification. // A normal modification.
cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage(); cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
itUs->second.coins = std::move(it->second.coins); itUs->second.coin = std::move(it->second.coin);
cachedCoinsUsage += itUs->second.coins.DynamicMemoryUsage(); cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
itUs->second.flags |= CCoinsCacheEntry::DIRTY; itUs->second.flags |= CCoinsCacheEntry::DIRTY;
// NOTE: It is possible the child has a FRESH flag here in // NOTE: It is possible the child has a FRESH flag here in
// the event the entry we found in the parent is pruned. But // the event the entry we found in the parent is pruned. But
@ -204,7 +204,7 @@ void CCoinsViewCache::Uncache(const COutPoint& hash)
{ {
CCoinsMap::iterator it = cacheCoins.find(hash); CCoinsMap::iterator it = cacheCoins.find(hash);
if (it != cacheCoins.end() && it->second.flags == 0) { if (it != cacheCoins.end() && it->second.flags == 0) {
cachedCoinsUsage -= it->second.coins.DynamicMemoryUsage(); cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
cacheCoins.erase(it); cacheCoins.erase(it);
} }
} }

4
src/coins.h

@ -103,7 +103,7 @@ public:
struct CCoinsCacheEntry struct CCoinsCacheEntry
{ {
Coin coins; // The actual cached data. Coin coin; // The actual cached data.
unsigned char flags; unsigned char flags;
enum Flags { enum Flags {
@ -117,7 +117,7 @@ struct CCoinsCacheEntry
}; };
CCoinsCacheEntry() : flags(0) {} CCoinsCacheEntry() : flags(0) {}
explicit CCoinsCacheEntry(Coin&& coin_) : coins(std::move(coin_)), flags(0) {} explicit CCoinsCacheEntry(Coin&& coin_) : coin(std::move(coin_)), flags(0) {}
}; };
typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap; typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap;

14
src/test/coins_tests.cpp

@ -64,8 +64,8 @@ public:
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); ) { for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); ) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) { if (it->second.flags & CCoinsCacheEntry::DIRTY) {
// Same optimization used in CCoinsViewDB is to only write dirty entries. // Same optimization used in CCoinsViewDB is to only write dirty entries.
map_[it->first] = it->second.coins; map_[it->first] = it->second.coin;
if (it->second.coins.IsPruned() && insecure_rand() % 3 == 0) { if (it->second.coin.IsPruned() && insecure_rand() % 3 == 0) {
// Randomly delete empty entries on write. // Randomly delete empty entries on write.
map_.erase(it->first); map_.erase(it->first);
} }
@ -89,7 +89,7 @@ public:
size_t ret = memusage::DynamicUsage(cacheCoins); size_t ret = memusage::DynamicUsage(cacheCoins);
size_t count = 0; size_t count = 0;
for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) { for (CCoinsMap::iterator it = cacheCoins.begin(); it != cacheCoins.end(); it++) {
ret += it->second.coins.DynamicMemoryUsage(); ret += it->second.coin.DynamicMemoryUsage();
++count; ++count;
} }
BOOST_CHECK_EQUAL(GetCacheSize(), count); BOOST_CHECK_EQUAL(GetCacheSize(), count);
@ -554,10 +554,10 @@ size_t InsertCoinsMapEntry(CCoinsMap& map, CAmount value, char flags)
assert(flags != NO_ENTRY); assert(flags != NO_ENTRY);
CCoinsCacheEntry entry; CCoinsCacheEntry entry;
entry.flags = flags; entry.flags = flags;
SetCoinsValue(value, entry.coins); SetCoinsValue(value, entry.coin);
auto inserted = map.emplace(OUTPOINT, std::move(entry)); auto inserted = map.emplace(OUTPOINT, std::move(entry));
assert(inserted.second); assert(inserted.second);
return inserted.first->second.coins.DynamicMemoryUsage(); return inserted.first->second.coin.DynamicMemoryUsage();
} }
void GetCoinsMapEntry(const CCoinsMap& map, CAmount& value, char& flags) void GetCoinsMapEntry(const CCoinsMap& map, CAmount& value, char& flags)
@ -567,10 +567,10 @@ void GetCoinsMapEntry(const CCoinsMap& map, CAmount& value, char& flags)
value = ABSENT; value = ABSENT;
flags = NO_ENTRY; flags = NO_ENTRY;
} else { } else {
if (it->second.coins.IsPruned()) { if (it->second.coin.IsPruned()) {
value = PRUNED; value = PRUNED;
} else { } else {
value = it->second.coins.out.nValue; value = it->second.coin.out.nValue;
} }
flags = it->second.flags; flags = it->second.flags;
assert(flags != NO_ENTRY); assert(flags != NO_ENTRY);

4
src/txdb.cpp

@ -75,10 +75,10 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
if (it->second.flags & CCoinsCacheEntry::DIRTY) { if (it->second.flags & CCoinsCacheEntry::DIRTY) {
CoinsEntry entry(&it->first); CoinsEntry entry(&it->first);
if (it->second.coins.IsPruned()) if (it->second.coin.IsPruned())
batch.Erase(entry); batch.Erase(entry);
else else
batch.Write(entry, it->second.coins); batch.Write(entry, it->second.coin);
changed++; changed++;
} }
count++; count++;

Loading…
Cancel
Save