More SHA map work.

This commit is contained in:
JoelKatz
2011-11-17 19:57:19 -08:00
parent 477b2df276
commit 76b7b3c68e
3 changed files with 68 additions and 19 deletions

View File

@@ -4,11 +4,6 @@
#include <boost/foreach.hpp>
SHAMapItem::SHAMapItem(const uint256 &tag) : mTag(tag)
{
mData.insert(mData.end(), tag.begin(), tag.end());
}
SHAMap::SHAMap(int leafDataSize, int leafDataOffset) : mLeafDataSize(leafDataSize), mLeafDataOffset(leafDataOffset)
{
;
@@ -67,7 +62,7 @@ SHAMapLeafNode::pointer SHAMap::walkToLeaf(const uint256& id, bool create,
if(inNode->isEmptyBranch(branch))
{ // no nodes below this one
if(!create) return SHAMapLeafNode::pointer();
return createLeaf(*inNode, id);
return createLeaf(*inNode, id, path);
}
if(i!=(SHAMapNode::leafDepth)-1)
{ // child is another inner node
@@ -81,7 +76,7 @@ SHAMapLeafNode::pointer SHAMap::walkToLeaf(const uint256& id, bool create,
if(ln==NULL)
{
if(!create) return SHAMapLeafNode::pointer();
return createLeaf(*inNode, id);
return createLeaf(*inNode, id, path);
}
}
}
@@ -111,9 +106,10 @@ SHAMapLeafNode::pointer SHAMap::getLeaf(const SHAMapNode &id, const uint256& has
tag=inner.getSHA512Half();
}
else tag=s.get256(i+mLeafDataOffset);
leaf->addUpdateItem(SHAMapItem(tag, s.getRaw(i, mLeafDataSize)));
leaf->addUpdateItem(SHAMapItem::pointer(new SHAMapItem(tag, s.getRaw(i, mLeafDataSize))));
}
leaf->updateHash();
mLeafByID[*leaf]=leaf;
assert(leaf->getNodeHash()==hash);
return leaf;
}
@@ -132,11 +128,18 @@ SHAMapInnerNode::pointer SHAMap::getInner(const SHAMapNode &id, const uint256& h
badNode(hash, id);
return SHAMapInnerNode::pointer();
}
mInnerNodeByID[id]=node;
return node;
}
SHAMapItem::SHAMapItem(const uint256& tag) : mTag(tag)
{
mData.insert(mData.end(), tag.begin(), tag.end());
}
SHAMapItem::SHAMapItem(const uint256& tag, const std::vector<unsigned char>& data) : mTag(tag), mData(data)
{ ; }
SHAMapItem::pointer SHAMap::firstItem()
{
ScopedLock sl(mLock);
@@ -225,6 +228,22 @@ SHAMapItem::pointer SHAMap::prevItem(const SHAMapItem &)
// WRITEME
}
SHAMapLeafNode::pointer SHAMap::createLeaf(const SHAMapInnerNode& lowestParent, const uint256& id,
std::vector<SHAMapInnerNode::pointer>& path)
{
int depth=lowestParent.getDepth();
for(int depth=lowestParent.getDepth(); depth<SHAMapNode::leafDepth; depth++)
{
SHAMapInnerNode::pointer newNode(new SHAMapInnerNode(SHAMapNode(++depth, id)));
mInnerNodeByID[*newNode]=newNode;
path.push_back(newNode);
}
SHAMapLeafNode::pointer newLeaf(new SHAMapLeafNode(SHAMapNode(SHAMapNode::leafDepth, id)));
mLeafByID[*newLeaf]=newLeaf;
return newLeaf;
}
bool SHAMap::hasItem(const uint256& id)
{ // does the tree have an item with this ID
ScopedLock sl(mLock);
@@ -245,14 +264,23 @@ bool SHAMap::delItem(const uint256& id)
dirtyUp(id, path);
}
bool SHAMap::addItem(const SHAMapItem& item)
bool SHAMap::addItem(SHAMapItem::pointer item)
{ // add the specified item
ScopedLock sl(mLock);
std::vector<SHAMapInnerNode::pointer> path;
SHAMapLeafNode::pointer leaf=walkToLeaf(item.getTag(), true, path);
SHAMapLeafNode::pointer leaf=walkToLeaf(item->getTag(), true, path);
if(leaf == SHAMapLeafNode::pointer()) return false;
if(!leaf->addUpdateItem(item)) return false;
dirtyUp(item.getTag(), path);
dirtyUp(item->getTag(), path);
}
void SHAMapItem::dump()
{
std::cerr << "SHAMapItem(" << mTag.GetHex() << ") " << mData.size() << "bytes" << std::endl;
}
void SHAMap::dump()
{
}
void TestSHAMap()

View File

@@ -34,8 +34,8 @@ public:
static const int leafDepth=10;
SHAMapNode(int depth, const uint256 &hash);
int getDepth() { return mDepth; }
const uint256 &getNodeID() { return mNodeID; }
int getDepth() const { return mDepth; }
const uint256 &getNodeID() { return mNodeID; }
bool isRoot() const { return mDepth==0; }
bool isLeaf() const { return mDepth==leafDepth; }
@@ -148,11 +148,11 @@ private:
bool updateHash();
protected:
bool setChildHash(int m, const uint256 &hash);
bool setChildHash(int m, const uint256& hash);
public:
SHAMapInnerNode(int Depth, const uint256 &NodeID);
SHAMapInnerNode(const SHAMapNode &id, const std::vector<unsigned char> &contents);
SHAMapInnerNode(const SHAMapNode& id);
SHAMapInnerNode(const SHAMapNode& id, const std::vector<unsigned char> &contents);
virtual bool isPopulated(void) const { return true; }
@@ -183,7 +183,8 @@ private:
protected:
void dirtyUp(const uint256& id, const std::vector<SHAMapInnerNode::pointer>& path);
SHAMapLeafNode::pointer createLeaf(const SHAMapInnerNode& lowestParent, const uint256 &id);
SHAMapLeafNode::pointer createLeaf(const SHAMapInnerNode& lowestParent, const uint256& id,
std::vector<SHAMapInnerNode::pointer>& path);
SHAMapLeafNode::pointer checkCacheLeaf(const SHAMapNode &);
SHAMapLeafNode::pointer walkToLeaf(const uint256& id, bool create,
std::vector<SHAMapInnerNode::pointer>& path);
@@ -217,7 +218,7 @@ public:
// normal hash access functions
bool hasItem(const uint256& id);
bool delItem(const uint256& id);
bool addItem(const SHAMapItem& item);
bool addItem(SHAMapItem::pointer item);
SHAMapItem::pointer getItem(const uint256 &id);
// traverse functions

View File

@@ -150,6 +150,13 @@ bool SHAMapLeafNode::delItem(const uint256& tag)
return false;
}
SHAMapItem::pointer SHAMapLeafNode::findItem(const uint256& tag)
{
BOOST_FOREACH(SHAMapItem::pointer& it, mItems)
if(it->getTag() == tag) return it;
return SHAMapItem::pointer();
}
SHAMapItem::pointer SHAMapLeafNode::firstItem(void)
{
if(mItems.size()==0) return SHAMapItem::pointer();
@@ -178,6 +185,19 @@ bool SHAMapLeafNode::updateHash(void)
return true;
}
SHAMapInnerNode::SHAMapInnerNode(const SHAMapNode& id) : SHAMapNode(id)
{
;
}
SHAMapInnerNode::SHAMapInnerNode(const SHAMapNode& id, const std::vector<unsigned char>& contents)
: SHAMapNode(id)
{
Serializer s(contents);
for(int i=0; i<32; i++)
mHashes[i]=s.get256(i*32);
}
bool SHAMapInnerNode::setChildHash(int m, const uint256 &hash)
{
assert( (m>=0) && (m<32) );