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> #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) 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)) if(inNode->isEmptyBranch(branch))
{ // no nodes below this one { // no nodes below this one
if(!create) return SHAMapLeafNode::pointer(); if(!create) return SHAMapLeafNode::pointer();
return createLeaf(*inNode, id); return createLeaf(*inNode, id, path);
} }
if(i!=(SHAMapNode::leafDepth)-1) if(i!=(SHAMapNode::leafDepth)-1)
{ // child is another inner node { // child is another inner node
@@ -81,7 +76,7 @@ SHAMapLeafNode::pointer SHAMap::walkToLeaf(const uint256& id, bool create,
if(ln==NULL) if(ln==NULL)
{ {
if(!create) return SHAMapLeafNode::pointer(); 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(); tag=inner.getSHA512Half();
} }
else tag=s.get256(i+mLeafDataOffset); 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(); leaf->updateHash();
mLeafByID[*leaf]=leaf;
assert(leaf->getNodeHash()==hash); assert(leaf->getNodeHash()==hash);
return leaf; return leaf;
} }
@@ -132,11 +128,18 @@ SHAMapInnerNode::pointer SHAMap::getInner(const SHAMapNode &id, const uint256& h
badNode(hash, id); badNode(hash, id);
return SHAMapInnerNode::pointer(); return SHAMapInnerNode::pointer();
} }
mInnerNodeByID[id]=node; mInnerNodeByID[id]=node;
return 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() SHAMapItem::pointer SHAMap::firstItem()
{ {
ScopedLock sl(mLock); ScopedLock sl(mLock);
@@ -225,6 +228,22 @@ SHAMapItem::pointer SHAMap::prevItem(const SHAMapItem &)
// WRITEME // 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) bool SHAMap::hasItem(const uint256& id)
{ // does the tree have an item with this ID { // does the tree have an item with this ID
ScopedLock sl(mLock); ScopedLock sl(mLock);
@@ -245,14 +264,23 @@ bool SHAMap::delItem(const uint256& id)
dirtyUp(id, path); dirtyUp(id, path);
} }
bool SHAMap::addItem(const SHAMapItem& item) bool SHAMap::addItem(SHAMapItem::pointer item)
{ // add the specified item { // add the specified item
ScopedLock sl(mLock); ScopedLock sl(mLock);
std::vector<SHAMapInnerNode::pointer> path; 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 == SHAMapLeafNode::pointer()) return false;
if(!leaf->addUpdateItem(item)) 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() void TestSHAMap()

View File

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

View File

@@ -150,6 +150,13 @@ bool SHAMapLeafNode::delItem(const uint256& tag)
return false; 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) SHAMapItem::pointer SHAMapLeafNode::firstItem(void)
{ {
if(mItems.size()==0) return SHAMapItem::pointer(); if(mItems.size()==0) return SHAMapItem::pointer();
@@ -178,6 +185,19 @@ bool SHAMapLeafNode::updateHash(void)
return true; 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) bool SHAMapInnerNode::setChildHash(int m, const uint256 &hash)
{ {
assert( (m>=0) && (m<32) ); assert( (m>=0) && (m<32) );