optimized a little
This commit is contained in:
parent
7b5ae24bea
commit
c6e267e970
2 changed files with 26 additions and 21 deletions
|
@ -222,6 +222,7 @@ bool CClaimTrieCacheBase::haveClaim(const std::string& name, const COutPoint& ou
|
||||||
if (it || nodesToDelete.count(name))
|
if (it || nodesToDelete.count(name))
|
||||||
return false;
|
return false;
|
||||||
CClaimTrieDataNode node;
|
CClaimTrieDataNode node;
|
||||||
|
node.childrenSerialization = false;
|
||||||
return base->find(name, node) && node.data.haveClaim(outPoint);
|
return base->find(name, node) && node.data.haveClaim(outPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,6 +331,7 @@ bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& c
|
||||||
if (it || nodesToDelete.count(name))
|
if (it || nodesToDelete.count(name))
|
||||||
return false;
|
return false;
|
||||||
CClaimTrieDataNode node;
|
CClaimTrieDataNode node;
|
||||||
|
node.childrenSerialization = false;
|
||||||
return base->find(name, node) && node.data.getBestClaim(claim);
|
return base->find(name, node) && node.data.getBestClaim(claim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,6 +342,7 @@ CClaimsForNameType CClaimTrieCacheBase::getClaimsForName(const std::string& name
|
||||||
auto supports = getSupportsForName(name);
|
auto supports = getSupportsForName(name);
|
||||||
|
|
||||||
CClaimTrieDataNode node;
|
CClaimTrieDataNode node;
|
||||||
|
node.childrenSerialization = false;
|
||||||
if (auto it = nodesToAddOrUpdate.find(name)) {
|
if (auto it = nodesToAddOrUpdate.find(name)) {
|
||||||
claims = it->claims;
|
claims = it->claims;
|
||||||
nLastTakeoverHeight = it->nHeightOfLastTakeover;
|
nLastTakeoverHeight = it->nHeightOfLastTakeover;
|
||||||
|
@ -423,7 +426,11 @@ bool CClaimTrie::checkConsistency(const uint256& rootHash) const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
recurseAllHashedNodes("", node, [&success](const std::string& name, const CClaimTrieDataNode& node) {
|
recurseAllHashedNodes("", node, [&success, this](const std::string& name, const CClaimTrieDataNode& node) {
|
||||||
|
if (!success) return;
|
||||||
|
|
||||||
|
success &= contains(name);
|
||||||
|
|
||||||
std::vector<uint8_t> vchToHash;
|
std::vector<uint8_t> vchToHash;
|
||||||
const auto pos = name.size();
|
const auto pos = name.size();
|
||||||
for (auto& child : node.children) {
|
for (auto& child : node.children) {
|
||||||
|
@ -459,7 +466,8 @@ std::vector<std::pair<std::string, CClaimTrieDataNode>> CClaimTrie::nodes(const
|
||||||
std::string partialKey = key;
|
std::string partialKey = key;
|
||||||
|
|
||||||
while (!node.children.empty()) {
|
while (!node.children.empty()) {
|
||||||
auto it = node.children.lower_bound(partialKey);
|
// auto it = node.children.lower_bound(partialKey); // for using a std::map
|
||||||
|
auto it = std::lower_bound(node.children.begin(), node.children.end(), std::make_pair(partialKey, uint256()));
|
||||||
if (it != node.children.end() && it->first == partialKey) {
|
if (it != node.children.end() && it->first == partialKey) {
|
||||||
// we're completely done
|
// we're completely done
|
||||||
if (find(it->second, node))
|
if (find(it->second, node))
|
||||||
|
@ -565,8 +573,8 @@ bool CClaimTrieCacheBase::flush()
|
||||||
|
|
||||||
CClaimTrieDataNode node;
|
CClaimTrieDataNode node;
|
||||||
node.data = it.data();
|
node.data = it.data();
|
||||||
for (auto &child: it.children())
|
for (auto &child: it.children()) // ordering here is important
|
||||||
node.children.emplace(child.key().substr(it.key().size()), child->hash);
|
node.children.emplace_back(child.key().substr(it.key().size()), child->hash);
|
||||||
|
|
||||||
batch.Write(std::make_pair(TRIE_NODE_BY_HASH, it->hash), node);
|
batch.Write(std::make_pair(TRIE_NODE_BY_HASH, it->hash), node);
|
||||||
batch.Write(std::make_pair(TRIE_NODE_BY_NAME, it.key()), it->hash);
|
batch.Write(std::make_pair(TRIE_NODE_BY_NAME, it.key()), it->hash);
|
||||||
|
@ -651,6 +659,7 @@ uint256 CClaimTrieCacheBase::getMerkleHash()
|
||||||
return recursiveComputeMerkleHash(it);
|
return recursiveComputeMerkleHash(it);
|
||||||
if (nodesToDelete.empty() && nodesAlreadyCached.empty()) {
|
if (nodesToDelete.empty() && nodesAlreadyCached.empty()) {
|
||||||
CClaimTrieDataNode node;
|
CClaimTrieDataNode node;
|
||||||
|
node.childrenSerialization = false;
|
||||||
if (base->find("", node))
|
if (base->find("", node))
|
||||||
return node.data.hash; // it may be valuable to have base cache its current root hash
|
return node.data.hash; // it may be valuable to have base cache its current root hash
|
||||||
}
|
}
|
||||||
|
@ -678,15 +687,15 @@ CClaimPrefixTrie::iterator CClaimTrieCacheBase::cacheData(const std::string& nam
|
||||||
// to calculate merkle hash
|
// to calculate merkle hash
|
||||||
auto nodes = base->nodes(name);
|
auto nodes = base->nodes(name);
|
||||||
for (auto& node: nodes) {
|
for (auto& node: nodes) {
|
||||||
if (!nodesAlreadyCached.count(node.first)) {
|
if (nodesAlreadyCached.insert(node.first).second) {
|
||||||
// do not insert nodes that are already present
|
// do not insert nodes that are already present
|
||||||
nodesAlreadyCached.insert(node.first);
|
|
||||||
nodesToAddOrUpdate.insert(node.first, node.second.data);
|
nodesToAddOrUpdate.insert(node.first, node.second.data);
|
||||||
}
|
}
|
||||||
for (auto& child : node.second.children) {
|
for (auto& child : node.second.children) {
|
||||||
auto childKey = node.first + child.first;
|
auto childKey = node.first + child.first;
|
||||||
if (!nodesAlreadyCached.count(childKey)) {
|
if (nodesAlreadyCached.insert(childKey).second) {
|
||||||
CClaimTrieDataNode childNode;
|
CClaimTrieDataNode childNode;
|
||||||
|
childNode.childrenSerialization = false;
|
||||||
if (base->find(child.second, childNode)) {
|
if (base->find(child.second, childNode)) {
|
||||||
nodesToAddOrUpdate.insert(childKey, childNode.data);
|
nodesToAddOrUpdate.insert(childKey, childNode.data);
|
||||||
}
|
}
|
||||||
|
@ -718,6 +727,7 @@ bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint16
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
CClaimTrieDataNode data;
|
CClaimTrieDataNode data;
|
||||||
|
data.childrenSerialization = false;
|
||||||
if (base->find(name, data)) {
|
if (base->find(name, data)) {
|
||||||
takeoverHeight = data.data.nHeightOfLastTakeover;
|
takeoverHeight = data.data.nHeightOfLastTakeover;
|
||||||
CClaimValue claim;
|
CClaimValue claim;
|
||||||
|
@ -1012,6 +1022,7 @@ void CClaimTrieCacheBase::dumpToLog(CClaimPrefixTrie::const_iterator it, bool di
|
||||||
|
|
||||||
if (diffFromBase) {
|
if (diffFromBase) {
|
||||||
CClaimTrieDataNode node;
|
CClaimTrieDataNode node;
|
||||||
|
node.childrenSerialization = false;
|
||||||
if (base->find(it.key(), node) && node.data.hash == it->hash)
|
if (base->find(it.key(), node) && node.data.hash == it->hash)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1332,6 +1343,7 @@ int CClaimTrieCacheBase::getNumBlocksOfContinuousOwnership(const std::string& na
|
||||||
if (it) // we specifically ignore deleted nodes here to allow this to fall into the base lookup in that scenario
|
if (it) // we specifically ignore deleted nodes here to allow this to fall into the base lookup in that scenario
|
||||||
return 0;
|
return 0;
|
||||||
CClaimTrieDataNode node;
|
CClaimTrieDataNode node;
|
||||||
|
node.childrenSerialization = false;
|
||||||
if (base->find(name, node) && !node.data.empty())
|
if (base->find(name, node) && !node.data.empty())
|
||||||
return nNextHeight - node.data.nHeightOfLastTakeover;
|
return nNextHeight - node.data.nHeightOfLastTakeover;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -160,17 +160,6 @@ struct CClaimTrieData
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||||
{
|
{
|
||||||
READWRITE(hash);
|
READWRITE(hash);
|
||||||
|
|
||||||
if (ser_action.ForRead()) {
|
|
||||||
if (s.eof()) {
|
|
||||||
claims.clear();
|
|
||||||
nHeightOfLastTakeover = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (claims.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
READWRITE(claims);
|
READWRITE(claims);
|
||||||
READWRITE(nHeightOfLastTakeover);
|
READWRITE(nHeightOfLastTakeover);
|
||||||
}
|
}
|
||||||
|
@ -193,7 +182,10 @@ struct CClaimTrieData
|
||||||
|
|
||||||
struct CClaimTrieDataNode {
|
struct CClaimTrieDataNode {
|
||||||
CClaimTrieData data;
|
CClaimTrieData data;
|
||||||
std::map<std::string, uint256> children;
|
// we're using a vector to avoid RAM thrashing and for faster serialization ops.
|
||||||
|
// We're assuming its data is inserted in order and never modified.
|
||||||
|
std::vector<std::pair<std::string, uint256>> children;
|
||||||
|
bool childrenSerialization = true;
|
||||||
|
|
||||||
CClaimTrieDataNode() = default;
|
CClaimTrieDataNode() = default;
|
||||||
CClaimTrieDataNode(CClaimTrieDataNode&&) = default;
|
CClaimTrieDataNode(CClaimTrieDataNode&&) = default;
|
||||||
|
@ -206,8 +198,9 @@ struct CClaimTrieDataNode {
|
||||||
template <typename Stream, typename Operation>
|
template <typename Stream, typename Operation>
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||||
{
|
{
|
||||||
READWRITE(children);
|
READWRITE(data);
|
||||||
READWRITE(data); // keep item using "s.eof" last
|
if (childrenSerialization) // wanting constexpr but hoping the compiler is smart enough anyway
|
||||||
|
READWRITE(children);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue