From fe3acce2621938c033829de66c12c9d0be3a864f Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 25 Nov 2011 21:52:54 -0800 Subject: [PATCH] Some missing functions. --- SHAMap.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++- SHAMapNodes.cpp | 27 +++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/SHAMap.cpp b/SHAMap.cpp index 63c2e37808..7b37a04c31 100644 --- a/SHAMap.cpp +++ b/SHAMap.cpp @@ -287,7 +287,51 @@ SHAMapItem::pointer SHAMap::peekNextItem(const uint256& id) SHAMapItem::pointer SHAMap::peekPrevItem(const uint256& id) { - // WRITEME + ScopedLock sl(mLock); + + SHAMapLeafNode::pointer leaf=walkToLeaf(id, false, false); + if(!leaf) return SHAMapItem::pointer(); + + // is there another item in this leaf? (there almost never will be) + SHAMapItem::pointer prev=leaf->prevItem(id); + if(prev) return prev; + + for(int depth=SHAMapNode::leafDepth-1; depth>=0; depth--) + { // walk up the tree until we find a node with a previous child + SHAMapInnerNode::pointer node=mInnerNodeByID[SHAMapNode(depth, id)]; + if(!node) + { +#ifdef DEBUG + std::cerr << "InnerNode missing: " << SHAMapNode(depth,id).getString() << std::endl; +#endif + throw SHAMapException(MissingNode); + } + for(int i=node->selectBranch(id)-1; i>=0; i--) + if(!!node->getChildHash(i)) + { // node has a subsequent child + SHAMapNode prevNode(node->getChildNodeID(i)); + const uint256& prevHash(node->getChildHash(i)); + + if(prevNode.isLeaf()) + { // this is a terminal inner node + leaf=getLeaf(prevNode, prevHash, false); + if(!leaf) throw SHAMapException(MissingNode); + prev=leaf->firstItem(); + if(!prev) throw SHAMapException(InvalidNode); + return prev; + } + + // the next item is the first item below this node + SHAMapInnerNode::pointer inner=getInner(prevNode, prevHash, false); + if(!inner) throw SHAMapException(MissingNode); + prev=lastBelow(inner); + if(!prev) throw SHAMapException(InvalidNode); + return prev; + } + } + + // must be last item + return SHAMapItem::pointer(); } SHAMapLeafNode::pointer SHAMap::createLeaf(const SHAMapInnerNode& lowestParent, const uint256& id) diff --git a/SHAMapNodes.cpp b/SHAMapNodes.cpp index fab65c2eb1..5f0806338c 100644 --- a/SHAMapNodes.cpp +++ b/SHAMapNodes.cpp @@ -177,11 +177,30 @@ SHAMapItem::pointer SHAMapLeafNode::firstItem(void) SHAMapItem::pointer SHAMapLeafNode::nextItem(const uint256& tag) { - bool found=false; - BOOST_FOREACH(SHAMapItem::pointer& it, mItems) + std::list::iterator it; + for(it=mItems.begin(); it!=mItems.end(); ++it) { - if(found) return it; - if(it->getTag() == tag) found=true; + if((*it)->getTag()==tag) + { + ++it; + if(it==mItems.end()) return SHAMapItem::pointer(); + return *it; + } + } + return SHAMapItem::pointer(); +} + +SHAMapItem::pointer SHAMapLeafNode::prevItem(const uint256& tag) +{ + std::list::reverse_iterator it; + for(it=mItems.rbegin(); it!=mItems.rend(); ++it) + { + if((*it)->getTag()==tag) + { + ++it; + if(it==mItems.rend()) return SHAMapItem::pointer(); + return *it; + } } return SHAMapItem::pointer(); }