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++)
{
int branch=inNode->selectBranch(id);
if(branch<0)
{ // somehow we got on the wrong branch
assert(false);
return SHAMapLeafNode::pointer();
}
if(branch<0) // somehow we got on the wrong branch
throw SHAMapException(InvalidNode);
if(inNode->isEmptyBranch(branch))
{ // no nodes below this one
if(!create) return SHAMapLeafNode::pointer();
@@ -69,7 +66,7 @@ SHAMapLeafNode::pointer SHAMap::walkToLeaf(const uint256& id, bool create,
if(i!=(SHAMapNode::leafDepth)-1)
{ // child is another inner node
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);
}
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)
{ ; }
SHAMapItem::pointer SHAMap::firstItem()
SHAMapItem::pointer SHAMap::peekFirstItem()
{
ScopedLock sl(mLock);
return firstBelow(root);
}
SHAMapItem::pointer SHAMap::lastItem()
SHAMapItem::pointer SHAMap::peekLastItem()
{
ScopedLock sl(mLock);
return lastBelow(root);
@@ -220,12 +217,50 @@ SHAMapItem::pointer SHAMap::lastBelow(SHAMapInnerNode::pointer Node)
}
}
SHAMapItem::pointer SHAMap::nextItem(const SHAMapItem &)
{
// WRITEME
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
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;
}
// 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::prevItem(const SHAMapItem &)
SHAMapItem::pointer SHAMap::peekPrevItem(const uint256& id)
{
// WRITEME
}
@@ -257,7 +292,7 @@ SHAMapItem::pointer SHAMap::peekItem(const uint256& id)
bool SHAMap::hasItem(const uint256& id)
{ // does the tree have an item with this ID
ScopedLock sl(mLock);
ScopedLock sl(mLock);
std::vector<SHAMapInnerNode::pointer> path;
SHAMapLeafNode::pointer leaf=walkToLeaf(id, false, path);
if(!leaf) return false;

View File

@@ -17,7 +17,7 @@ class SHAMap;
// The trees are designed for rapid synchronization and compression of differences
class SHAMapNode
class SHAMapNode
{ // Identifies a node in a SHA256 hash
public:
typedef boost::shared_ptr<SHAMapNode> pointer;
@@ -133,7 +133,8 @@ public:
SHAMapItem::pointer findItem(const uint256& tag);
SHAMapItem::pointer firstItem();
SHAMapItem::pointer lastItem();
SHAMapItem::pointer nextItem(SHAMapItem::pointer);
SHAMapItem::pointer nextItem(const uint256& tag);
SHAMapItem::pointer prevItem(const uint256& tag);
virtual void dump(void);
};
@@ -241,10 +242,13 @@ public:
SHAMapItem::pointer peekItem(const uint256& id);
// traverse functions
SHAMapItem::pointer firstItem();
SHAMapItem::pointer lastItem();
SHAMapItem::pointer nextItem(const SHAMapItem &);
SHAMapItem::pointer prevItem(const SHAMapItem &);
SHAMapItem::pointer peekFirstItem();
SHAMapItem::pointer peekLastItem();
SHAMapItem::pointer peekNextItem(const uint256&);
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
void getMissingNodes(std::vector<SHAMapNode>& nodeHashes, int max);

View File

@@ -163,6 +163,17 @@ SHAMapItem::pointer SHAMapLeafNode::firstItem(void)
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)
{
if(mItems.size()==0) return SHAMapItem::pointer();