Browse Source

Fixed key comparator for kevacache.

cn
Jianping Wu 6 years ago
parent
commit
53d29e5690
  1. 29
      src/keva/common.cpp
  2. 18
      src/keva/common.h
  3. 31
      src/txdb.cpp

29
src/keva/common.cpp

@ -127,27 +127,38 @@ bool CCacheKeyIterator::next(valtype& key, CKevaData& data)
{ {
/* Exit early if no more data is available in either the cache /* Exit early if no more data is available in either the cache
nor the base iterator. */ nor the base iterator. */
if (!baseHasMore && cacheIter == cache.entries.end())
bool endOfCacheNamespace = false;
if (cacheIter != cache.entries.end()) {
valtype curNameSpace = std::get<0>(cacheIter->first);
if (curNameSpace != nameSpace) {
endOfCacheNamespace = true;
}
}
bool noMoreCache = (cacheIter == cache.entries.end()) || endOfCacheNamespace;
if (!baseHasMore && noMoreCache) {
return false; return false;
}
/* Determine which source to use for the next. */ /* Determine which source to use for the next. */
bool useBase; bool useBase = false;
if (!baseHasMore) if (!baseHasMore) {
useBase = false; useBase = false;
else if (cacheIter == cache.entries.end()) } else if (cacheIter == cache.entries.end()) {
useBase = true; useBase = true;
else { } else {
/* A special case is when both iterators are equal. In this case, if (baseKey == std::get<1>(cacheIter->first)) {
/* A special case is when both iterators are equal. In this case,
we want to use the cached version. We also have to advance we want to use the cached version. We also have to advance
the base iterator. */ the base iterator. */
if (baseKey == std::get<1>(cacheIter->first))
advanceBaseIterator (); advanceBaseIterator ();
}
/* Due to advancing the base iterator above, it may happen that /* Due to advancing the base iterator above, it may happen that
no more base entries are present. Handle this gracefully. */ no more base entries are present. Handle this gracefully. */
if (!baseHasMore) if (!baseHasMore) {
useBase = false; useBase = false;
else { } else {
assert(baseKey != std::get<1>(cacheIter->first)); assert(baseKey != std::get<1>(cacheIter->first));
CKevaCache::KeyComparator cmp; CKevaCache::KeyComparator cmp;

18
src/keva/common.h

@ -309,12 +309,20 @@ private:
inline bool operator() (const std::tuple<valtype, valtype> a, inline bool operator() (const std::tuple<valtype, valtype> a,
const std::tuple<valtype, valtype> b) const const std::tuple<valtype, valtype> b) const
{ {
unsigned int aSize = std::get<0>(a).size() + std::get<1>(a).size(); // This is how namespace/key pairs are sorted in database.
unsigned int bSize = std::get<0>(b).size() + std::get<1>(b).size(); auto nsA = std::get<0>(a);
if (aSize != bSize) { auto nsB = std::get<0>(b);
return aSize < bSize; if (nsA == nsB) {
auto aKey = std::get<1>(a);
auto bKey = std::get<1>(b);
uint32_t aKeySize = aKey.size();
uint32_t bKeySize = bKey.size();
if (aKeySize == bKeySize) {
return aKey < bKey;
}
return aKeySize < bKeySize;
} }
return a < b; return nsA < nsB;
} }
}; };

31
src/txdb.cpp

@ -157,36 +157,7 @@ bool CCoinsViewDB::GetName(const valtype &nameSpace, const valtype &key, CKevaDa
} }
bool CCoinsViewDB::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { bool CCoinsViewDB::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const {
names.clear(); return false;
#if 0
/* It seems that there are no "const iterators" for LevelDB. Since we
only need read operations on it, use a const-cast to get around
that restriction. */
boost::scoped_ptr<CDBIterator> pcursor(const_cast<CDBWrapper*>(&db)->NewIterator());
const CKevaCache::ExpireEntry seekEntry(nHeight, valtype ());
pcursor->Seek(std::make_pair(DB_NAME_EXPIRY, seekEntry));
for (; pcursor->Valid(); pcursor->Next())
{
std::pair<char, CKevaCache::ExpireEntry> key;
if (!pcursor->GetKey(key) || key.first != DB_NAME_EXPIRY)
break;
const CKevaCache::ExpireEntry& entry = key.second;
assert (entry.nHeight >= nHeight);
if (entry.nHeight > nHeight)
break;
const valtype& name = entry.name;
if (names.count(name) > 0) {
return error("%s : duplicate name '%s' in expire index",
__func__, ValtypeToString(name).c_str());
}
names.insert(name);
}
#endif
return true;
} }
bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) { bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) {

Loading…
Cancel
Save