Some missing functions.

This commit is contained in:
JoelKatz
2011-11-25 21:52:54 -08:00
parent badf382903
commit fe3acce262
2 changed files with 68 additions and 5 deletions

View File

@@ -287,7 +287,51 @@ SHAMapItem::pointer SHAMap::peekNextItem(const uint256& id)
SHAMapItem::pointer SHAMap::peekPrevItem(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) SHAMapLeafNode::pointer SHAMap::createLeaf(const SHAMapInnerNode& lowestParent, const uint256& id)

View File

@@ -177,11 +177,30 @@ SHAMapItem::pointer SHAMapLeafNode::firstItem(void)
SHAMapItem::pointer SHAMapLeafNode::nextItem(const uint256& tag) SHAMapItem::pointer SHAMapLeafNode::nextItem(const uint256& tag)
{ {
bool found=false; std::list<SHAMapItem::pointer>::iterator it;
BOOST_FOREACH(SHAMapItem::pointer& it, mItems) for(it=mItems.begin(); it!=mItems.end(); ++it)
{ {
if(found) return it; if((*it)->getTag()==tag)
if(it->getTag() == tag) found=true; {
++it;
if(it==mItems.end()) return SHAMapItem::pointer();
return *it;
}
}
return SHAMapItem::pointer();
}
SHAMapItem::pointer SHAMapLeafNode::prevItem(const uint256& tag)
{
std::list<SHAMapItem::pointer>::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(); return SHAMapItem::pointer();
} }