diff --git a/SHAMap.cpp b/SHAMap.cpp index 7ccd8e83cd..024b743c89 100644 --- a/SHAMap.cpp +++ b/SHAMap.cpp @@ -4,7 +4,12 @@ #include -SHAMap::SHAMap(int leafDataSize) : mLeafDataSize(leafDataSize) +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) { ; } @@ -86,14 +91,30 @@ SHAMapLeafNode::pointer SHAMap::walkToLeaf(const uint256& id, bool create, SHAMapLeafNode::pointer SHAMap::getLeaf(const SHAMapNode &id, const uint256& hash) { // retrieve a leaf whose node hash is known - SHAMapLeafNode::pointer leaf=mLeafByID[id]; + assert(!!hash); + SHAMapLeafNode::pointer leaf=mLeafByID[id]; // is the leaf in memory if(leaf != SHAMapLeafNode::pointer()) return leaf; - std::vector rawNode; + std::vector rawNode; // is it in backing store if(!fetchNode(hash, id, rawNode)) return leaf; - + + Serializer s(rawNode); leaf=SHAMapLeafNode::pointer(new SHAMapLeafNode(id)); - // construct leaf WRITEME + + for(int i=0; iaddUpdateItem(SHAMapItem(tag, s.getRaw(i, mLeafDataSize))); + } + leaf->updateHash(); + assert(leaf->getNodeHash()==hash); return leaf; } diff --git a/SHAMap.h b/SHAMap.h index 332a612cb3..44f24507b0 100644 --- a/SHAMap.h +++ b/SHAMap.h @@ -106,13 +106,13 @@ public: private: uint256 mHash; - std::list mItems; + std::list mItems; bool updateHash(); protected: - bool addUpdateItem(const SHAMapItem&); - bool delItem(const SHAMapItem& i) { delItem(i.getTag()); } + bool addUpdateItem(SHAMapItem::pointer); + bool delItem(const SHAMapItem::pointer i) { delItem(i->getTag()); } bool delItem(const uint256 &tag); public: @@ -120,7 +120,7 @@ public: virtual bool isPopulated(void) const { return true; } - const uint256& GetNodeHash() const { return mHash; } + const uint256& getNodeHash() const { return mHash; } bool isEmpty() const { return mItems.empty(); } int getItemCount() const { return mItems.size(); } @@ -171,7 +171,7 @@ public: typedef boost::shared_ptr pointer; private: - int mLeafDataSize; + int mLeafDataSize, mLeafDataOffset; mutable boost::recursive_mutex mLock; std::map mLeafByID; std::map mInnerNodeByID; @@ -195,7 +195,7 @@ protected: SHAMapItem::pointer lastBelow(SHAMapInnerNode::pointer); public: - SHAMap(int leafDataSize); + SHAMap(int leafDataSize=32, int leafDataOffset=-1); // hold the map stable across operations ScopedLock Lock() const { return ScopedLock(mLock); } diff --git a/SHAMapNodes.cpp b/SHAMapNodes.cpp index 02d762a372..722249cab1 100644 --- a/SHAMapNodes.cpp +++ b/SHAMapNodes.cpp @@ -96,6 +96,11 @@ int SHAMapNode::selectBranch(const uint256 &hash) return branch; } +void SHAMapNode::dump() +{ + std::cerr << "MapNode(" << mNodeID.GetHex() << ", " << mDepth << ")" << std::endl; +} + SHAMapLeafNode::SHAMapLeafNode(const SHAMapNode& nodeID) : SHAMapNode(nodeID), mHash(0) { ; @@ -103,26 +108,28 @@ SHAMapLeafNode::SHAMapLeafNode(const SHAMapNode& nodeID) : SHAMapNode(nodeID), m bool SHAMapLeafNode::hasItem(const uint256& item) const { - BOOST_FOREACH(const SHAMapItem& nodeItem, mItems) - if(nodeItem==item) return true; + BOOST_FOREACH(SHAMapItem::pointer nodeItem, mItems) + if(nodeItem->getTag()==item) return true; return false; } -bool SHAMapLeafNode::addUpdateItem(const SHAMapItem& item) +bool SHAMapLeafNode::addUpdateItem(SHAMapItem::pointer item) { // The node will almost never have more than one item in it - std::list::iterator it; + std::list::iterator it; for(it=mItems.begin(); it!=mItems.end(); it++) { - if(*it==item) + SHAMapItem &nodeItem=**it; + if(nodeItem.getTag()==item->getTag()) { - if(it->peekData()==item.peekData()) + if(nodeItem.peekData()==item->peekData()) return false; // no change - it->updateData(item.peekData()); + nodeItem.updateData(item->peekData()); return updateHash(); } - if((*it)>item) + if(nodeItem.getTag()>item->getTag()) { mItems.insert(it, item); + return updateHash(); } } mItems.push_back(item); @@ -131,10 +138,10 @@ bool SHAMapLeafNode::addUpdateItem(const SHAMapItem& item) bool SHAMapLeafNode::delItem(const uint256& tag) { - std::list::iterator it; + std::list::iterator it; for(it=mItems.begin(); it!=mItems.end(); it++) { - if(*it==tag) + if((*it)->getTag()==tag) { mItems.erase(it); return updateHash(); @@ -143,14 +150,27 @@ bool SHAMapLeafNode::delItem(const uint256& tag) return false; } +SHAMapItem::pointer SHAMapLeafNode::firstItem(void) +{ + if(mItems.size()==0) return SHAMapItem::pointer(); + return *(mItems.begin()); +} + +SHAMapItem::pointer SHAMapLeafNode::lastItem(void) +{ + if(mItems.size()==0) return SHAMapItem::pointer(); + return *(mItems.rbegin()); +} + + bool SHAMapLeafNode::updateHash(void) { uint256 nh; if(mItems.size()!=0) nh=0; { Serializer s; - BOOST_FOREACH(const SHAMapItem &mi, mItems) - s.addRaw(mi.peekData()); + BOOST_FOREACH(const SHAMapItem::pointer &mi, mItems) + s.addRaw(mi->peekData()); nh=s.getSHA512Half(); } if(nh==mHash) return false; diff --git a/Serializer.cpp b/Serializer.cpp index 39775144fb..d592ef2763 100644 --- a/Serializer.cpp +++ b/Serializer.cpp @@ -83,6 +83,14 @@ bool Serializer::get256(uint256& o, int offset) const return true; } +uint256 Serializer::get256(int offset) const +{ + uint256 ret; + if((offset+sizeof(ret))>mData.size()) return ret; + memcpy(&ret, &(mData.front())+offset, sizeof(ret)); + return ret; +} + bool Serializer::getRaw(std::vector& o, int offset, int length) const { if((offset+length)>mData.size()) return false; @@ -90,6 +98,14 @@ bool Serializer::getRaw(std::vector& o, int offset, int length) c return true; } +std::vector Serializer::getRaw(int offset, int length) const +{ + std::vector o; + if((offset+length)>mData.size()) return o; + o.assign(mData.begin()+offset, mData.begin()+offset+length); + return o; +} + uint160 Serializer::getRIPEMD160(int size) const { uint160 ret; @@ -141,3 +157,8 @@ bool Serializer::addSignature(CKey& key) addRaw(signature); return true; } + +void Serializer::TestSerializer(void) +{ + Serializer s(64); +} diff --git a/Serializer.h b/Serializer.h index b5f5c85dfc..623148d448 100644 --- a/Serializer.h +++ b/Serializer.h @@ -26,7 +26,9 @@ class Serializer bool get64(uint64&, int offset) const; bool get160(uint160&, int offset) const; bool get256(uint256&, int offset) const; + uint256 get256(int offset) const; bool getRaw(std::vector&, int offset, int length) const; + std::vector getRaw(int offset, int length) const; // hash functions uint160 getRIPEMD160(int size=0) const; @@ -44,7 +46,7 @@ class Serializer bool makeSignature(std::vector &signature, CKey& rkey) const; bool addSignature(CKey& rkey); - static void UnitTest(void); + static void TestSerializer(void); }; #endif