mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 14:35:52 +00:00
Continue fleshing out these classes.
This commit is contained in:
142
SHAMap.cpp
142
SHAMap.cpp
@@ -1,87 +1,131 @@
|
|||||||
#include "BitcoinUtil.h"
|
#include "BitcoinUtil.h"
|
||||||
#include "SHAMap.h"
|
#include "SHAMap.h"
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
bool SHAMapNodeID::operator<(const SHAMapNodeID &s) const
|
bool SHAMapNode::operator<(const SHAMapNode &s) const
|
||||||
{
|
{
|
||||||
if(s.mDepth<mDepth) return true;
|
if(s.mDepth<mDepth) return true;
|
||||||
if(s.mDepth>mDepth) return false;
|
if(s.mDepth>mDepth) return false;
|
||||||
return mNodeID<s.mNodeID;
|
return mNodeID<s.mNodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHAMapNodeID::operator>(const SHAMapNodeID &s) const
|
bool SHAMapNode::operator>(const SHAMapNode &s) const
|
||||||
{
|
{
|
||||||
if(s.mDepth<mDepth) return false;
|
if(s.mDepth<mDepth) return false;
|
||||||
if(s.mDepth>mDepth) return true;
|
if(s.mDepth>mDepth) return true;
|
||||||
return mNodeID>s.mNodeID;
|
return mNodeID>s.mNodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHAMapNodeID::operator<=(const SHAMapNodeID &s) const
|
bool SHAMapNode::operator<=(const SHAMapNode &s) const
|
||||||
{
|
{
|
||||||
if(s.mDepth<mDepth) return true;
|
if(s.mDepth<mDepth) return true;
|
||||||
if(s.mDepth>mDepth) return false;
|
if(s.mDepth>mDepth) return false;
|
||||||
return mNodeID<=s.mNodeID;
|
return mNodeID<=s.mNodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHAMapNodeID::operator>=(const SHAMapNodeID &s) const
|
bool SHAMapNode::operator>=(const SHAMapNode &s) const
|
||||||
{
|
{
|
||||||
if(s.mDepth<mDepth) return false;
|
if(s.mDepth<mDepth) return false;
|
||||||
if(s.mDepth>mDepth) return true;
|
if(s.mDepth>mDepth) return true;
|
||||||
return mNodeID>=s.mNodeID;
|
return mNodeID>=s.mNodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHAMapNodeID::operator==(const SHAMapNodeID &s) const
|
bool SHAMapNode::operator==(const SHAMapNode &s) const
|
||||||
{
|
{
|
||||||
return (s.mDepth==mDepth) && (s.mNodeID==mNodeID);
|
return (s.mDepth==mDepth) && (s.mNodeID==mNodeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHAMapNodeID::operator!=(const SHAMapNodeID &s) const
|
bool SHAMapNode::operator!=(const SHAMapNode &s) const
|
||||||
{
|
{
|
||||||
return (s.mDepth!=mDepth) || (s.mNodeID!=mNodeID);
|
return (s.mDepth!=mDepth) || (s.mNodeID!=mNodeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAMapNodeID::ClassInit()
|
void SHAMapNode::ClassInit()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char HexBuf[65];
|
char HexBuf[65];
|
||||||
|
|
||||||
for(i=0; i<64; i++) HexBuf[i]='0';
|
for(i=0; i<64; i++) HexBuf[i]='0';
|
||||||
HexBuf[64]=0;
|
HexBuf[64]=0;
|
||||||
for(i=0; i<leafDepth; i++)
|
for(i=0; i<leafDepth; i++)
|
||||||
{
|
{
|
||||||
smMasks[i].SetHex(HexBuf);
|
smMasks[i].SetHex(HexBuf);
|
||||||
HexBuf[2*i]='1';
|
HexBuf[2*i]='1';
|
||||||
HexBuf[2*i+1]='F';
|
HexBuf[2*i+1]='F';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAMapNodeID::SHAMapNodeID(int depth, const uint256 &hash)
|
SHAMapNode::SHAMapNode(int depth, const uint256 &hash)
|
||||||
{
|
{
|
||||||
assert(depth>=0 && depth<leafDepth);
|
assert(depth>=0 && depth<leafDepth);
|
||||||
mDepth=depth;
|
mDepth=depth;
|
||||||
mNodeID=getNodeID(depth, hash);
|
mNodeID=getNodeID(depth, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAMapNodeID SHAMapNodeID::getChildNodeID(int m)
|
SHAMapNode SHAMapNode::getChildNodeID(int m)
|
||||||
{
|
{
|
||||||
assert(!isLeaf());
|
assert(!isLeaf());
|
||||||
|
|
||||||
uint256 branch=m;
|
uint256 branch=m;
|
||||||
branch>>=(mDepth*8);
|
branch>>=(mDepth*8);
|
||||||
|
|
||||||
return SHAMapNodeID(mDepth+1, mNodeID | branch);
|
return SHAMapNode(mDepth+1, mNodeID | branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SHAMapNodeID::selectBranch(const uint256 &hash)
|
int SHAMapNode::selectBranch(const uint256 &hash)
|
||||||
{
|
{
|
||||||
if(isLeaf()) // no nodes under this node
|
if(isLeaf()) // no nodes under this node
|
||||||
return -1;
|
return -1;
|
||||||
if((hash&smMasks[mDepth])!=mNodeID)
|
if((hash&smMasks[mDepth])!=mNodeID)
|
||||||
return -1; // does not go under this node
|
return -1; // does not go under this node
|
||||||
|
|
||||||
uint256 selector=hash&smMasks[mDepth+1];
|
uint256 selector=hash&smMasks[mDepth+1];
|
||||||
int branch=*(selector.begin()+mDepth);
|
int branch=*(selector.begin()+mDepth);
|
||||||
|
|
||||||
assert(branch>=0 && branch<32);
|
assert(branch>=0 && branch<32);
|
||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHAMapLeafNode::SHAMapLeafNode(const SHAMapNode& nodeID) : SHAMapNode(nodeID), mHash(0)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAMapLeafNode::updateHash(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHAMapLeafNode::hasHash(const uint256& hash) const
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(const uint256& entry, mHashes)
|
||||||
|
if(entry==hash) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHAMapLeafNode::addHash(const uint256& hash)
|
||||||
|
{ // The node will almost never have more than one hash in it
|
||||||
|
std::list<uint256>::iterator it;
|
||||||
|
for(it=mHashes.begin(); it!=mHashes.end(); it++)
|
||||||
|
{
|
||||||
|
if(*it==hash) return false;
|
||||||
|
if(*it>hash) break;
|
||||||
|
}
|
||||||
|
mHashes.insert(it, hash);
|
||||||
|
updateHash();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHAMapLeafNode::delHash(const uint256& hash)
|
||||||
|
{
|
||||||
|
std::list<uint256>::iterator it;
|
||||||
|
for(it=mHashes.begin(); it!=mHashes.end(); it++)
|
||||||
|
{
|
||||||
|
if(*it==hash)
|
||||||
|
{
|
||||||
|
mHashes.erase(it);
|
||||||
|
updateHash();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
73
SHAMap.h
73
SHAMap.h
@@ -15,7 +15,7 @@ class SHAMap;
|
|||||||
// The trees are designed for rapid synchronization and compression of differences
|
// The trees are designed for rapid synchronization and compression of differences
|
||||||
|
|
||||||
|
|
||||||
class SHAMapNodeID
|
class SHAMapNode
|
||||||
{ // Identified a node in a SHA256 hash
|
{ // Identified a node in a SHA256 hash
|
||||||
private:
|
private:
|
||||||
static uint256 smMasks[11]; // AND with hash to get node id
|
static uint256 smMasks[11]; // AND with hash to get node id
|
||||||
@@ -29,32 +29,33 @@ public:
|
|||||||
static const int rootDepth=0;
|
static const int rootDepth=0;
|
||||||
static const int leafDepth=10;
|
static const int leafDepth=10;
|
||||||
|
|
||||||
SHAMapNodeID(int depth, const uint256 &hash);
|
SHAMapNode(int depth, const uint256 &hash);
|
||||||
int getDepth() { return mDepth; }
|
int getDepth() { return mDepth; }
|
||||||
const uint256 &getNodeID();
|
const uint256 &getNodeID();
|
||||||
|
|
||||||
bool isRoot() const { return mDepth==0; }
|
bool isRoot() const { return mDepth==0; }
|
||||||
bool isLeaf() const { return mDepth==leafDepth; }
|
bool isLeaf() const { return mDepth==leafDepth; }
|
||||||
bool isInner() const { return !isRoot() && !isLeaf(); }
|
bool isInner() const { return !isRoot() && !isLeaf(); }
|
||||||
SHAMapNodeID getParentNodeID() { return SHAMapNodeID(mDepth-1, mNodeID); }
|
virtual bool IsPopulated(void) const { return false; }
|
||||||
SHAMapNodeID getChildNodeID(int m);
|
SHAMapNode getParentNodeID() { return SHAMapNode(mDepth-1, mNodeID); }
|
||||||
|
SHAMapNode getChildNodeID(int m);
|
||||||
|
|
||||||
int selectBranch(const uint256 &hash);
|
int selectBranch(const uint256 &hash);
|
||||||
|
|
||||||
static uint256 getNodeID(int depth, const uint256 &hash);
|
static uint256 getNodeID(int depth, const uint256 &hash);
|
||||||
|
|
||||||
bool operator<(const SHAMapNodeID &) const;
|
bool operator<(const SHAMapNode &) const;
|
||||||
bool operator>(const SHAMapNodeID &) const;
|
bool operator>(const SHAMapNode &) const;
|
||||||
bool operator==(const SHAMapNodeID &) const;
|
bool operator==(const SHAMapNode &) const;
|
||||||
bool operator!=(const SHAMapNodeID &) const;
|
bool operator!=(const SHAMapNode &) const;
|
||||||
bool operator<=(const SHAMapNodeID &) const;
|
bool operator<=(const SHAMapNode &) const;
|
||||||
bool operator>=(const SHAMapNodeID &) const;
|
bool operator>=(const SHAMapNode &) const;
|
||||||
|
|
||||||
static void ClassInit(void);
|
static void ClassInit();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class SHAMapLeafNode
|
class SHAMapLeafNode : public SHAMapNode
|
||||||
{
|
{
|
||||||
friend class SHAMap;
|
friend class SHAMap;
|
||||||
|
|
||||||
@@ -62,26 +63,29 @@ public:
|
|||||||
typedef boost::shared_ptr<SHAMapLeafNode> pointer;
|
typedef boost::shared_ptr<SHAMapLeafNode> pointer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SHAMapNodeID mNodeID;
|
|
||||||
uint256 mHash;
|
uint256 mHash;
|
||||||
std::list<uint256> mHashes;
|
std::list<uint256> mHashes;
|
||||||
|
|
||||||
void updateHash(void);
|
void updateHash();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool hasHash(const uint256 &hash) const;
|
|
||||||
bool addHash(const uint256 &hash);
|
bool addHash(const uint256 &hash);
|
||||||
bool delHash(const uint256 &hash);
|
bool delHash(const uint256 &hash);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHAMapLeafNode(const uint256& NodeID);
|
SHAMapLeafNode(const SHAMapNode& nodeID);
|
||||||
|
|
||||||
|
virtual bool IsPopulated(void) const { return true; }
|
||||||
|
|
||||||
const SHAMapNodeID& GetNodeID(void) const { return mNodeID; }
|
|
||||||
const uint256& GetNodeHash() const { return mHash; }
|
const uint256& GetNodeHash() const { return mHash; }
|
||||||
|
bool isEmpty() const { return mHashes.empty(); }
|
||||||
|
int getHashCount() const { return mHashes.size(); }
|
||||||
|
const uint256& GetHash(int m) const;
|
||||||
|
bool hasHash(const uint256 &hash) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHAMapInnerNode
|
class SHAMapInnerNode : public SHAMapNode
|
||||||
{
|
{
|
||||||
friend class SHAMap;
|
friend class SHAMap;
|
||||||
|
|
||||||
@@ -89,20 +93,22 @@ public:
|
|||||||
typedef boost::shared_ptr<SHAMapInnerNode> pointer;
|
typedef boost::shared_ptr<SHAMapInnerNode> pointer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SHAMapNodeID mNodeID;
|
|
||||||
uint256 mHash;
|
uint256 mHash;
|
||||||
uint256 mHashes[32];
|
uint256 mHashes[32];
|
||||||
|
|
||||||
void updateHash(void);
|
void updateHash();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetChildHash(int m, const uint256 &hash);
|
void SetChildHash(int m, const uint256 &hash);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHAMapInnerNode(int Depth, const uint256 &NodeID);
|
SHAMapInnerNode(int Depth, const uint256 &NodeID);
|
||||||
const SHAMapNodeID& GetNodeID() const { return mNodeID; }
|
|
||||||
|
|
||||||
|
virtual bool IsPopulated(void) const { return true; }
|
||||||
const uint256& GetNodeHash() const { return mHash; }
|
const uint256& GetNodeHash() const { return mHash; }
|
||||||
const uint256& GetChildHash(int m) const;
|
const uint256& GetChildHash(int m) const;
|
||||||
|
bool isEmpty() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -114,8 +120,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
mutable boost::mutex mLock;
|
mutable boost::mutex mLock;
|
||||||
std::map<SHAMapNodeID, SHAMapLeafNode> mLeaves;
|
std::map<SHAMapNode, SHAMapLeafNode> mLeafByID;
|
||||||
std::multimap<SHAMapNodeID, SHAMapInnerNode> mInnerNodes;
|
std::map<SHAMapNode, SHAMapInnerNode> mInnerNodeByID;
|
||||||
|
std::map<uint256, SHAMapNode> mNodeByHash; // includes nodes not present
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHAMap();
|
SHAMap();
|
||||||
@@ -123,18 +130,18 @@ public:
|
|||||||
ScopedLock Lock() const { return ScopedLock(mLock); }
|
ScopedLock Lock() const { return ScopedLock(mLock); }
|
||||||
|
|
||||||
// inner node access functions
|
// inner node access functions
|
||||||
bool HasInnerNode(const SHAMapNodeID &id);
|
bool HasInnerNode(const SHAMapNode &id);
|
||||||
bool GiveInnerNode(SHAMapInnerNode::pointer);
|
bool GiveInnerNode(SHAMapInnerNode::pointer);
|
||||||
SHAMapInnerNode::pointer GetInnerNode(const SHAMapNodeID &);
|
SHAMapInnerNode::pointer GetInnerNode(const SHAMapNode &);
|
||||||
|
|
||||||
// leaf node access functions
|
// leaf node access functions
|
||||||
bool HasLeafNode(const SHAMapNodeID &id);
|
bool HasLeafNode(const SHAMapNode &id);
|
||||||
bool GiveLeafNode(SHAMapLeafNode::pointer);
|
bool GiveLeafNode(SHAMapLeafNode::pointer);
|
||||||
SHAMapLeafNode::pointer GetLeafNode(const SHAMapNodeID &);
|
SHAMapLeafNode::pointer GetLeafNode(const SHAMapNode &);
|
||||||
|
|
||||||
// generic node functions
|
// generic node functions
|
||||||
std::vector<unsigned char> getRawNode(const SHAMapNodeID &id);
|
std::vector<unsigned char> getRawNode(const SHAMapNode &id);
|
||||||
bool addRawNode(const SHAMapNodeID& nodeID, std::vector<unsigned char> rawNode);
|
bool addRawNode(const SHAMapNode& nodeID, std::vector<unsigned char> rawNode);
|
||||||
|
|
||||||
// normal hash access functions
|
// normal hash access functions
|
||||||
bool hasHash(const uint256 &hash);
|
bool hasHash(const uint256 &hash);
|
||||||
@@ -145,9 +152,15 @@ public:
|
|||||||
bool nextHash(uint256 &hash);
|
bool nextHash(uint256 &hash);
|
||||||
bool prevHash(uint256 &hash);
|
bool prevHash(uint256 &hash);
|
||||||
|
|
||||||
// special overloads for backed maps
|
// comparison/sync functions
|
||||||
|
void getMissingNodes(std::vector<SHAMapNode> &nodeHashes, int max);
|
||||||
|
void getMissingObjects(std::vector<uint256> &objectHashes, int max);
|
||||||
|
bool addKnownNode(const std::vector<unsigned char>& rawNode);
|
||||||
|
|
||||||
|
// overloads for backed maps
|
||||||
virtual bool fetchNode(const uint256 &hash, std::vector<unsigned char>& rawNode);
|
virtual bool fetchNode(const uint256 &hash, std::vector<unsigned char>& rawNode);
|
||||||
virtual bool writeNode(const uint256 &hash, const std::vector<unsigned char>& rawNode);
|
virtual bool writeNode(const uint256 &hash, const std::vector<unsigned char>& rawNode);
|
||||||
|
virtual bool haveObject(const uint256 &hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user