mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +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>
|
#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)
|
SHAMapLeafNode::pointer SHAMap::getLeaf(const SHAMapNode &id, const uint256& hash)
|
||||||
{ // retrieve a leaf whose node hash is known
|
{ // 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;
|
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;
|
if(!fetchNode(hash, id, rawNode)) return leaf;
|
||||||
|
|
||||||
|
Serializer s(rawNode);
|
||||||
leaf=SHAMapLeafNode::pointer(new SHAMapLeafNode(id));
|
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;
|
return leaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
SHAMap.h
12
SHAMap.h
@@ -106,13 +106,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint256 mHash;
|
uint256 mHash;
|
||||||
std::list<SHAMapItem> mItems;
|
std::list<SHAMapItem::pointer> mItems;
|
||||||
|
|
||||||
bool updateHash();
|
bool updateHash();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool addUpdateItem(const SHAMapItem&);
|
bool addUpdateItem(SHAMapItem::pointer);
|
||||||
bool delItem(const SHAMapItem& i) { delItem(i.getTag()); }
|
bool delItem(const SHAMapItem::pointer i) { delItem(i->getTag()); }
|
||||||
bool delItem(const uint256 &tag);
|
bool delItem(const uint256 &tag);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -120,7 +120,7 @@ public:
|
|||||||
|
|
||||||
virtual bool isPopulated(void) const { return true; }
|
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(); }
|
bool isEmpty() const { return mItems.empty(); }
|
||||||
int getItemCount() const { return mItems.size(); }
|
int getItemCount() const { return mItems.size(); }
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ public:
|
|||||||
typedef boost::shared_ptr<SHAMap> pointer;
|
typedef boost::shared_ptr<SHAMap> pointer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mLeafDataSize;
|
int mLeafDataSize, mLeafDataOffset;
|
||||||
mutable boost::recursive_mutex mLock;
|
mutable boost::recursive_mutex mLock;
|
||||||
std::map<SHAMapNode, SHAMapLeafNode::pointer> mLeafByID;
|
std::map<SHAMapNode, SHAMapLeafNode::pointer> mLeafByID;
|
||||||
std::map<SHAMapNode, SHAMapInnerNode::pointer> mInnerNodeByID;
|
std::map<SHAMapNode, SHAMapInnerNode::pointer> mInnerNodeByID;
|
||||||
@@ -195,7 +195,7 @@ protected:
|
|||||||
SHAMapItem::pointer lastBelow(SHAMapInnerNode::pointer);
|
SHAMapItem::pointer lastBelow(SHAMapInnerNode::pointer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHAMap(int leafDataSize);
|
SHAMap(int leafDataSize=32, int leafDataOffset=-1);
|
||||||
|
|
||||||
// hold the map stable across operations
|
// hold the map stable across operations
|
||||||
ScopedLock Lock() const { return ScopedLock(mLock); }
|
ScopedLock Lock() const { return ScopedLock(mLock); }
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ int SHAMapNode::selectBranch(const uint256 &hash)
|
|||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHAMapNode::dump()
|
||||||
|
{
|
||||||
|
std::cerr << "MapNode(" << mNodeID.GetHex() << ", " << mDepth << ")" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
SHAMapLeafNode::SHAMapLeafNode(const SHAMapNode& nodeID) : SHAMapNode(nodeID), mHash(0)
|
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
|
bool SHAMapLeafNode::hasItem(const uint256& item) const
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const SHAMapItem& nodeItem, mItems)
|
BOOST_FOREACH(SHAMapItem::pointer nodeItem, mItems)
|
||||||
if(nodeItem==item) return true;
|
if(nodeItem->getTag()==item) return true;
|
||||||
return false;
|
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
|
{ // 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++)
|
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
|
return false; // no change
|
||||||
it->updateData(item.peekData());
|
nodeItem.updateData(item->peekData());
|
||||||
return updateHash();
|
return updateHash();
|
||||||
}
|
}
|
||||||
if((*it)>item)
|
if(nodeItem.getTag()>item->getTag())
|
||||||
{
|
{
|
||||||
mItems.insert(it, item);
|
mItems.insert(it, item);
|
||||||
|
return updateHash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mItems.push_back(item);
|
mItems.push_back(item);
|
||||||
@@ -131,10 +138,10 @@ bool SHAMapLeafNode::addUpdateItem(const SHAMapItem& item)
|
|||||||
|
|
||||||
bool SHAMapLeafNode::delItem(const uint256& tag)
|
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++)
|
for(it=mItems.begin(); it!=mItems.end(); it++)
|
||||||
{
|
{
|
||||||
if(*it==tag)
|
if((*it)->getTag()==tag)
|
||||||
{
|
{
|
||||||
mItems.erase(it);
|
mItems.erase(it);
|
||||||
return updateHash();
|
return updateHash();
|
||||||
@@ -143,14 +150,27 @@ bool SHAMapLeafNode::delItem(const uint256& tag)
|
|||||||
return false;
|
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)
|
bool SHAMapLeafNode::updateHash(void)
|
||||||
{
|
{
|
||||||
uint256 nh;
|
uint256 nh;
|
||||||
if(mItems.size()!=0) nh=0;
|
if(mItems.size()!=0) nh=0;
|
||||||
{
|
{
|
||||||
Serializer s;
|
Serializer s;
|
||||||
BOOST_FOREACH(const SHAMapItem &mi, mItems)
|
BOOST_FOREACH(const SHAMapItem::pointer &mi, mItems)
|
||||||
s.addRaw(mi.peekData());
|
s.addRaw(mi->peekData());
|
||||||
nh=s.getSHA512Half();
|
nh=s.getSHA512Half();
|
||||||
}
|
}
|
||||||
if(nh==mHash) return false;
|
if(nh==mHash) return false;
|
||||||
|
|||||||
@@ -83,6 +83,14 @@ bool Serializer::get256(uint256& o, int offset) const
|
|||||||
return true;
|
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
|
bool Serializer::getRaw(std::vector<unsigned char>& o, int offset, int length) const
|
||||||
{
|
{
|
||||||
if((offset+length)>mData.size()) return false;
|
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;
|
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 Serializer::getRIPEMD160(int size) const
|
||||||
{
|
{
|
||||||
uint160 ret;
|
uint160 ret;
|
||||||
@@ -141,3 +157,8 @@ bool Serializer::addSignature(CKey& key)
|
|||||||
addRaw(signature);
|
addRaw(signature);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Serializer::TestSerializer(void)
|
||||||
|
{
|
||||||
|
Serializer s(64);
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ class Serializer
|
|||||||
bool get64(uint64&, int offset) const;
|
bool get64(uint64&, int offset) const;
|
||||||
bool get160(uint160&, int offset) const;
|
bool get160(uint160&, int offset) const;
|
||||||
bool get256(uint256&, 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;
|
bool getRaw(std::vector<unsigned char>&, int offset, int length) const;
|
||||||
|
std::vector<unsigned char> getRaw(int offset, int length) const;
|
||||||
|
|
||||||
// hash functions
|
// hash functions
|
||||||
uint160 getRIPEMD160(int size=0) const;
|
uint160 getRIPEMD160(int size=0) const;
|
||||||
@@ -44,7 +46,7 @@ class Serializer
|
|||||||
bool makeSignature(std::vector<unsigned char> &signature, CKey& rkey) const;
|
bool makeSignature(std::vector<unsigned char> &signature, CKey& rkey) const;
|
||||||
bool addSignature(CKey& rkey);
|
bool addSignature(CKey& rkey);
|
||||||
|
|
||||||
static void UnitTest(void);
|
static void TestSerializer(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user