From 86893487d15a8718e6867ec44c5008003d619126 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 5 Mar 2013 09:00:31 -0800 Subject: [PATCH] Speedups. --- src/cpp/ripple/SHAMap.cpp | 16 ++++++-------- src/cpp/ripple/SHAMap.h | 17 ++++++++------- src/cpp/ripple/SHAMapDiff.cpp | 4 ++-- src/cpp/ripple/SHAMapNodes.cpp | 40 +++++++++++++++++++--------------- 4 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/cpp/ripple/SHAMap.cpp b/src/cpp/ripple/SHAMap.cpp index 89874875af..bb2eed6084 100644 --- a/src/cpp/ripple/SHAMap.cpp +++ b/src/cpp/ripple/SHAMap.cpp @@ -94,13 +94,12 @@ std::stack SHAMap::getStack(const uint256& id, bool inc int branch = node->selectBranch(id); assert(branch >= 0); - uint256 hash = node->getChildHash(branch); - if (hash.isZero()) + if (node->isEmptyBranch(branch)) return stack; try { - node = getNode(node->getChildNodeID(branch), hash, false); + node = getNode(node->getChildNodeID(branch), node->getChildHash(branch), false); } catch (SHAMapMissingNode& mn) { @@ -165,14 +164,13 @@ SHAMapTreeNode::pointer SHAMap::walkTo(const uint256& id, bool modify) while (!inNode->isLeaf()) { int branch = inNode->selectBranch(id); - uint256 childHash = inNode->getChildHash(branch); - if (childHash.isZero()) + if (inNode->isEmptyBranch(branch)) return inNode; try { - inNode = getNode(inNode->getChildNodeID(branch), childHash, false); + inNode = getNode(inNode->getChildNodeID(branch), inNode->getChildHash(branch), false); } catch (SHAMapMissingNode& mn) { @@ -193,10 +191,10 @@ SHAMapTreeNode* SHAMap::walkToPointer(const uint256& id) while (!inNode->isLeaf()) { int branch = inNode->selectBranch(id); - const uint256& nextHash = inNode->getChildHash(branch); - if (nextHash.isZero()) + if (inNode->isEmptyBranch(branch)) return NULL; - inNode = getNodePointer(inNode->getChildNodeID(branch), nextHash); + + inNode = getNodePointer(inNode->getChildNodeID(branch), inNode->getChildHash(branch)); assert(inNode); } return (inNode->getTag() == id) ? inNode : NULL; diff --git a/src/cpp/ripple/SHAMap.h b/src/cpp/ripple/SHAMap.h index ff42121f0f..21ffc48db1 100644 --- a/src/cpp/ripple/SHAMap.h +++ b/src/cpp/ripple/SHAMap.h @@ -163,12 +163,13 @@ public: }; private: - uint256 mHash; - uint256 mHashes[16]; - SHAMapItem::pointer mItem; - uint32 mSeq, mAccessSeq; - TNType mType; - bool mFullBelow; + uint256 mHash; + uint256 mHashes[16]; + std::bitset<16> mIsBranch; + SHAMapItem::pointer mItem; + uint32 mSeq, mAccessSeq; + TNType mType; + bool mFullBelow; bool updateHash(); @@ -204,9 +205,9 @@ public: bool isAccountState() const { return mType == tnACCOUNT_STATE; } // inner node functions - bool isInnerNode() const { return !mItem; } + bool isInnerNode() const { return !mItem; } bool setChildHash(int m, const uint256& hash); - bool isEmptyBranch(int m) const { return mHashes[m].isZero(); } + bool isEmptyBranch(int m) const { return !mIsBranch.test(m); } bool isEmpty() const; int getBranchCount() const; void makeInner(); diff --git a/src/cpp/ripple/SHAMapDiff.cpp b/src/cpp/ripple/SHAMapDiff.cpp index dd47b8375c..9ab9121c43 100644 --- a/src/cpp/ripple/SHAMapDiff.cpp +++ b/src/cpp/ripple/SHAMapDiff.cpp @@ -162,13 +162,13 @@ bool SHAMap::compare(SHAMap::ref otherMap, SHAMapDiff& differences, int maxCount for (int i = 0; i < 16; ++i) if (ourNode->getChildHash(i) != otherNode->getChildHash(i) ) { - if (!otherNode->getChildHash(i)) + if (otherNode->isEmptyBranch(i)) { // We have a branch, the other tree does not SHAMapTreeNode* iNode = getNodePointer(ourNode->getChildNodeID(i), ourNode->getChildHash(i)); if (!walkBranch(iNode, SHAMapItem::pointer(), true, differences, maxCount)) return false; } - else if (!ourNode->getChildHash(i)) + else if (ourNode->isEmptyBranch(i)) { // The other tree has a branch, we do not SHAMapTreeNode* iNode = otherMap->getNodePointer(otherNode->getChildNodeID(i), otherNode->getChildHash(i)); diff --git a/src/cpp/ripple/SHAMapNodes.cpp b/src/cpp/ripple/SHAMapNodes.cpp index 35ad313c7a..ac9a2f98df 100644 --- a/src/cpp/ripple/SHAMapNodes.cpp +++ b/src/cpp/ripple/SHAMapNodes.cpp @@ -188,6 +188,10 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapTreeNode& node, uint32 seq) : SHAMapN mItem = boost::make_shared(*node.mItem); else memcpy(mHashes, node.mHashes, sizeof(mHashes)); + + for (int i = 0; i < 16; ++i) + if (mHashes[i].isNonZero()) + mIsBranch.set(i); } SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& node, SHAMapItem::ref item, TNType type, uint32 seq) : @@ -236,7 +240,11 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& id, const std::vector= 16)) throw std::runtime_error("invalid CI node"); s.get256(mHashes[pos], i * 33); } + for (int i = 0; i < 16; ++i) + if (mHashes[i].isNonZero()) + mIsBranch.set(i); mType = tnINNER; } else if (type == 4) @@ -301,7 +312,11 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& id, const std::vector(mHashes), sizeof(mHashes)); #ifdef PARANOID @@ -414,10 +422,10 @@ void SHAMapTreeNode::addRaw(Serializer& s, SHANodeFormat format) } else { - if (getBranchCount() < 12) + if (mIsBranch.count() < 12) { // compressed node for (int i = 0; i < 16; ++i) - if (mHashes[i].isNonZero()) + if (mIsBranch.test(i)) { s.add256(mHashes[i]); s.add8(i); @@ -497,24 +505,19 @@ SHAMapItem::pointer SHAMapTreeNode::getItem() const bool SHAMapTreeNode::isEmpty() const { - assert(isInner()); - for (int i = 0; i < 16; ++i) - if (mHashes[i].isNonZero()) return false; - return true; + return mIsBranch.none(); } int SHAMapTreeNode::getBranchCount() const { assert(isInner()); - int ret = 0; - for (int i = 0; i < 16; ++i) - if (mHashes[i].isNonZero()) ++ret; - return ret; + return mIsBranch.count(); } void SHAMapTreeNode::makeInner() { mItem.reset(); + mIsBranch.reset(); memset(mHashes, 0, sizeof(mHashes)); mType = tnINNER; mHash.zero(); @@ -571,6 +574,7 @@ bool SHAMapTreeNode::setChildHash(int m, const uint256 &hash) if(mHashes[m] == hash) return false; mHashes[m] = hash; + mIsBranch.set(m, hash.isNonZero()); return updateHash(); }