mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 10:35:50 +00:00
More work on the SHAMap/Serialize classes.
This commit is contained in:
31
SHAMap.cpp
31
SHAMap.cpp
@@ -4,7 +4,12 @@
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
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<unsigned char> rawNode;
|
||||
std::vector<unsigned char> 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; i<s.getLength(); i+=mLeafDataSize)
|
||||
{
|
||||
uint256 tag;
|
||||
if(mLeafDataOffset<0)
|
||||
{
|
||||
Serializer inner;
|
||||
inner.addRaw(s.getRaw(i, mLeafDataSize));
|
||||
tag=inner.getSHA512Half();
|
||||
}
|
||||
else tag=s.get256(i+mLeafDataOffset);
|
||||
leaf->addUpdateItem(SHAMapItem(tag, s.getRaw(i, mLeafDataSize)));
|
||||
}
|
||||
leaf->updateHash();
|
||||
assert(leaf->getNodeHash()==hash);
|
||||
return leaf;
|
||||
}
|
||||
|
||||
|
||||
12
SHAMap.h
12
SHAMap.h
@@ -106,13 +106,13 @@ public:
|
||||
|
||||
private:
|
||||
uint256 mHash;
|
||||
std::list<SHAMapItem> mItems;
|
||||
std::list<SHAMapItem::pointer> 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<SHAMap> pointer;
|
||||
|
||||
private:
|
||||
int mLeafDataSize;
|
||||
int mLeafDataSize, mLeafDataOffset;
|
||||
mutable boost::recursive_mutex mLock;
|
||||
std::map<SHAMapNode, SHAMapLeafNode::pointer> mLeafByID;
|
||||
std::map<SHAMapNode, SHAMapInnerNode::pointer> 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); }
|
||||
|
||||
@@ -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<SHAMapItem>::iterator it;
|
||||
std::list<SHAMapItem::pointer>::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<SHAMapItem>::iterator it;
|
||||
std::list<SHAMapItem::pointer>::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;
|
||||
|
||||
@@ -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<unsigned char>& o, int offset, int length) const
|
||||
{
|
||||
if((offset+length)>mData.size()) return false;
|
||||
@@ -90,6 +98,14 @@ bool Serializer::getRaw(std::vector<unsigned char>& o, int offset, int length) c
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> Serializer::getRaw(int offset, int length) const
|
||||
{
|
||||
std::vector<unsigned char> 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);
|
||||
}
|
||||
|
||||
@@ -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<unsigned char>&, int offset, int length) const;
|
||||
std::vector<unsigned char> getRaw(int offset, int length) const;
|
||||
|
||||
// hash functions
|
||||
uint160 getRIPEMD160(int size=0) const;
|
||||
@@ -44,7 +46,7 @@ class Serializer
|
||||
bool makeSignature(std::vector<unsigned char> &signature, CKey& rkey) const;
|
||||
bool addSignature(CKey& rkey);
|
||||
|
||||
static void UnitTest(void);
|
||||
static void TestSerializer(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user