Some missing handlers. SHAMap traversal top-level code.

This commit is contained in:
JoelKatz
2011-11-23 14:57:11 -08:00
parent 5fc9233fb5
commit 51f3f4e1a4
3 changed files with 69 additions and 19 deletions

View File

@@ -56,11 +56,8 @@ SHAMapLeafNode::pointer SHAMap::walkToLeaf(const uint256& id, bool create,
for(int i=1; i<SHAMapNode::leafDepth; i++) for(int i=1; i<SHAMapNode::leafDepth; i++)
{ {
int branch=inNode->selectBranch(id); int branch=inNode->selectBranch(id);
if(branch<0) if(branch<0) // somehow we got on the wrong branch
{ // somehow we got on the wrong branch throw SHAMapException(InvalidNode);
assert(false);
return SHAMapLeafNode::pointer();
}
if(inNode->isEmptyBranch(branch)) if(inNode->isEmptyBranch(branch))
{ // no nodes below this one { // no nodes below this one
if(!create) return SHAMapLeafNode::pointer(); if(!create) return SHAMapLeafNode::pointer();
@@ -69,7 +66,7 @@ SHAMapLeafNode::pointer SHAMap::walkToLeaf(const uint256& id, bool create,
if(i!=(SHAMapNode::leafDepth)-1) if(i!=(SHAMapNode::leafDepth)-1)
{ // child is another inner node { // child is another inner node
inNode=getInner(inNode->getChildNodeID(branch), inNode->getChildHash(branch)); inNode=getInner(inNode->getChildNodeID(branch), inNode->getChildHash(branch));
if(inNode==NULL) return SHAMapLeafNode::pointer(); // we don't have the node if(inNode==NULL) throw SHAMapException(InvalidNode);
path.push_back(inNode); path.push_back(inNode);
} }
else // child is leaf node else // child is leaf node
@@ -142,13 +139,13 @@ SHAMapItem::SHAMapItem(const uint160& tag, const std::vector<unsigned char>& dat
: mTag(uint160to256(tag)), mData(data) : mTag(uint160to256(tag)), mData(data)
{ ; } { ; }
SHAMapItem::pointer SHAMap::firstItem() SHAMapItem::pointer SHAMap::peekFirstItem()
{ {
ScopedLock sl(mLock); ScopedLock sl(mLock);
return firstBelow(root); return firstBelow(root);
} }
SHAMapItem::pointer SHAMap::lastItem() SHAMapItem::pointer SHAMap::peekLastItem()
{ {
ScopedLock sl(mLock); ScopedLock sl(mLock);
return lastBelow(root); return lastBelow(root);
@@ -220,12 +217,50 @@ SHAMapItem::pointer SHAMap::lastBelow(SHAMapInnerNode::pointer Node)
} }
} }
SHAMapItem::pointer SHAMap::nextItem(const SHAMapItem &) SHAMapItem::pointer SHAMap::peekNextItem(const uint256& id)
{ { // Get a pointer to the next item in the tree after a given item - item must be in tree
// WRITEME ScopedLock sl(mLock);
std::vector<SHAMapInnerNode::pointer> path;
SHAMapLeafNode::pointer leaf=walkToLeaf(id, false, path);
if(!leaf) return SHAMapItem::pointer();
// is there another item in this leaf? (there almost never will be)
SHAMapItem::pointer next=leaf->nextItem(id);
if(next) return next;
for(std::vector<SHAMapInnerNode::pointer>::reverse_iterator rit=path.rbegin(); rit<path.rend(); ++rit)
{ // walk up the tree until we find a node with a subsequent child
SHAMapInnerNode::pointer& node=*rit;
for(int i=node->selectBranch(id)+1; i<32; i++)
if(!!node->getChildHash(i))
{ // node has a subsequent child
SHAMapNode nextNode=node->getChildNodeID(i);
uint256 nextHash=node->getChildHash(i);
if(nextNode.isLeaf())
{ // this is a terminal inner node
leaf=getLeaf(nextNode, nextHash);
if(!leaf) throw SHAMapException(MissingNode);
next=leaf->firstItem();
if(!next) throw SHAMapException(InvalidNode);
return next;
} }
SHAMapItem::pointer SHAMap::prevItem(const SHAMapItem &) // the next item is the first item below this node
SHAMapInnerNode::pointer inner=getInner(nextNode, nextHash);
if(!inner) throw SHAMapException(MissingNode);
next=firstBelow(inner);
if(!next) throw SHAMapException(InvalidNode);
return next;
}
}
// must be last item
return SHAMapItem::pointer();
}
SHAMapItem::pointer SHAMap::peekPrevItem(const uint256& id)
{ {
// WRITEME // WRITEME
} }

View File

@@ -133,7 +133,8 @@ public:
SHAMapItem::pointer findItem(const uint256& tag); SHAMapItem::pointer findItem(const uint256& tag);
SHAMapItem::pointer firstItem(); SHAMapItem::pointer firstItem();
SHAMapItem::pointer lastItem(); SHAMapItem::pointer lastItem();
SHAMapItem::pointer nextItem(SHAMapItem::pointer); SHAMapItem::pointer nextItem(const uint256& tag);
SHAMapItem::pointer prevItem(const uint256& tag);
virtual void dump(void); virtual void dump(void);
}; };
@@ -241,10 +242,13 @@ public:
SHAMapItem::pointer peekItem(const uint256& id); SHAMapItem::pointer peekItem(const uint256& id);
// traverse functions // traverse functions
SHAMapItem::pointer firstItem(); SHAMapItem::pointer peekFirstItem();
SHAMapItem::pointer lastItem(); SHAMapItem::pointer peekLastItem();
SHAMapItem::pointer nextItem(const SHAMapItem &); SHAMapItem::pointer peekNextItem(const uint256&);
SHAMapItem::pointer prevItem(const SHAMapItem &); SHAMapItem::pointer peekPrevItem(const uint256&);
SHAMapItem::pointer peekPrevItem(const uint160& u) { return peekPrevItem(uint160to256(u)); }
SHAMapItem::pointer peekNextItem(const uint160& u) { return peekNextItem(uint160to256(u)); }
// comparison/sync functions // comparison/sync functions
void getMissingNodes(std::vector<SHAMapNode>& nodeHashes, int max); void getMissingNodes(std::vector<SHAMapNode>& nodeHashes, int max);

View File

@@ -163,6 +163,17 @@ SHAMapItem::pointer SHAMapLeafNode::firstItem(void)
return *(mItems.begin()); return *(mItems.begin());
} }
SHAMapItem::pointer SHAMapLeafNode::nextItem(const uint256& tag)
{
bool found=false;
BOOST_FOREACH(SHAMapItem::pointer& it, mItems)
{
if(found) return it;
if(it->getTag() == tag) found=true;
}
return SHAMapItem::pointer();
}
SHAMapItem::pointer SHAMapLeafNode::lastItem(void) SHAMapItem::pointer SHAMapLeafNode::lastItem(void)
{ {
if(mItems.size()==0) return SHAMapItem::pointer(); if(mItems.size()==0) return SHAMapItem::pointer();