mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-25 13:35:54 +00:00
Unordered maps perform better than regular ones.
This commit is contained in:
22
SHAMap.h
22
SHAMap.h
@@ -63,8 +63,6 @@ public:
|
|||||||
bool operator<=(const SHAMapNode&) const;
|
bool operator<=(const SHAMapNode&) const;
|
||||||
bool operator>=(const SHAMapNode&) const;
|
bool operator>=(const SHAMapNode&) const;
|
||||||
|
|
||||||
std::size_t getHash() const;
|
|
||||||
|
|
||||||
virtual std::string getString() const;
|
virtual std::string getString() const;
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
@@ -72,6 +70,14 @@ public:
|
|||||||
static uint256 getNodeID(int depth, const uint256& hash);
|
static uint256 getNodeID(int depth, const uint256& hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class hash_SMN
|
||||||
|
{ // These must be randomized for release
|
||||||
|
public:
|
||||||
|
std::size_t operator() (const SHAMapNode& mn) const
|
||||||
|
{ return mn.getDepth() ^ static_cast<std::size_t>(mn.getNodeID().PeekAt(0)); }
|
||||||
|
std::size_t operator() (const uint256& u) const
|
||||||
|
{ return static_cast<std::size_t>(u.PeekAt(0)); }
|
||||||
|
};
|
||||||
|
|
||||||
class SHAMapItem
|
class SHAMapItem
|
||||||
{ // an item stored in a SHAMap
|
{ // an item stored in a SHAMap
|
||||||
@@ -210,15 +216,6 @@ enum SHAMapException
|
|||||||
InvalidNode=2
|
InvalidNode=2
|
||||||
};
|
};
|
||||||
|
|
||||||
class hash_SMN : std::unary_function<SHAMapNode, std::size_t>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::size_t operator() (const SHAMapNode& mn) const
|
|
||||||
{
|
|
||||||
return mn.getHash();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SHAMap
|
class SHAMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -228,8 +225,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
uint32 mSeq;
|
uint32 mSeq;
|
||||||
mutable boost::recursive_mutex mLock;
|
mutable boost::recursive_mutex mLock;
|
||||||
std::map<SHAMapNode, SHAMapLeafNode::pointer> mLeafByID;
|
boost::unordered_map<SHAMapNode, SHAMapLeafNode::pointer, hash_SMN> mLeafByID;
|
||||||
|
|
||||||
boost::unordered_map<SHAMapNode, SHAMapInnerNode::pointer, hash_SMN> mInnerNodeByID;
|
boost::unordered_map<SHAMapNode, SHAMapInnerNode::pointer, hash_SMN> mInnerNodeByID;
|
||||||
|
|
||||||
boost::shared_ptr<std::map<SHAMapNode, SHAMapLeafNode::pointer> > mDirtyLeafNodes;
|
boost::shared_ptr<std::map<SHAMapNode, SHAMapLeafNode::pointer> > mDirtyLeafNodes;
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
#include "Serializer.h"
|
|
||||||
#include "BitcoinUtil.h"
|
#include <cstring>
|
||||||
#include "SHAMap.h"
|
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
#include "Serializer.h"
|
||||||
|
#include "BitcoinUtil.h"
|
||||||
|
#include "SHAMap.h"
|
||||||
std::string SHAMapNode::getString() const
|
std::string SHAMapNode::getString() const
|
||||||
{
|
{
|
||||||
std::string ret="NodeID(";
|
std::string ret="NodeID(";
|
||||||
@@ -83,17 +85,6 @@ uint256 SHAMapNode::getNodeID(int depth, const uint256& hash)
|
|||||||
return hash & smMasks[depth];
|
return hash & smMasks[depth];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t SHAMapNode::getHash() const
|
|
||||||
{
|
|
||||||
std::size_t ret=mDepth;
|
|
||||||
for(int i=0; i<5; i++)
|
|
||||||
{
|
|
||||||
ret*=2654435761U;
|
|
||||||
ret^=mNodeID.PeekAt(i);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHAMapNode::SHAMapNode(int depth, const uint256 &hash) : mDepth(depth)
|
SHAMapNode::SHAMapNode(int depth, const uint256 &hash) : mDepth(depth)
|
||||||
{ // canonicalize the hash to a node ID for this depth
|
{ // canonicalize the hash to a node ID for this depth
|
||||||
assert(depth>=0 && depth<=leafDepth);
|
assert(depth>=0 && depth<=leafDepth);
|
||||||
@@ -101,15 +92,14 @@ SHAMapNode::SHAMapNode(int depth, const uint256 &hash) : mDepth(depth)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SHAMapNode SHAMapNode::getChildNodeID(int m) const
|
SHAMapNode SHAMapNode::getChildNodeID(int m) const
|
||||||
{
|
{ // This can be optimized to avoid the << if needed
|
||||||
assert(!isLeaf());
|
assert(!isLeaf());
|
||||||
assert((m>=0) && (m<32));
|
assert((m>=0) && (m<32));
|
||||||
|
|
||||||
uint256 branch=m;
|
uint256 branch=m;
|
||||||
branch<<=mDepth*8;
|
branch<<=mDepth*8;
|
||||||
|
|
||||||
SHAMapNode ret(mDepth+1, mNodeID | branch);
|
return SHAMapNode(mDepth+1, mNodeID | branch);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SHAMapNode::selectBranch(const uint256 &hash) const
|
int SHAMapNode::selectBranch(const uint256 &hash) const
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ bool SHAMap::syncTest()
|
|||||||
hashes.clear();
|
hashes.clear();
|
||||||
|
|
||||||
// get the list of nodes we know we need
|
// get the list of nodes we know we need
|
||||||
destination.getMissingNodes(nodeIDs, hashes, 512);
|
destination.getMissingNodes(nodeIDs, hashes, 1024);
|
||||||
if(!nodeIDs.size()) break;
|
if(!nodeIDs.size()) break;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -469,6 +469,9 @@ bool SHAMap::syncTest()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cerr << gotNodeIDs.size() << " found nodes" << std::endl;
|
||||||
|
#endif
|
||||||
for(nodeIDIterator=gotNodeIDs.begin(), rawNodeIterator=gotNodes.begin();
|
for(nodeIDIterator=gotNodeIDs.begin(), rawNodeIterator=gotNodes.begin();
|
||||||
nodeIDIterator!=gotNodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
|
nodeIDIterator!=gotNodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user