mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-24 13:05:53 +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;
|
||||
|
||||
std::size_t getHash() const;
|
||||
|
||||
virtual std::string getString() const;
|
||||
void dump() const;
|
||||
|
||||
@@ -72,6 +70,14 @@ public:
|
||||
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
|
||||
{ // an item stored in a SHAMap
|
||||
@@ -210,15 +216,6 @@ enum SHAMapException
|
||||
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
|
||||
{
|
||||
public:
|
||||
@@ -228,8 +225,7 @@ public:
|
||||
private:
|
||||
uint32 mSeq;
|
||||
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::shared_ptr<std::map<SHAMapNode, SHAMapLeafNode::pointer> > mDirtyLeafNodes;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#include "Serializer.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "SHAMap.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "Serializer.h"
|
||||
#include "BitcoinUtil.h"
|
||||
#include "SHAMap.h"
|
||||
std::string SHAMapNode::getString() const
|
||||
{
|
||||
std::string ret="NodeID(";
|
||||
@@ -83,17 +85,6 @@ uint256 SHAMapNode::getNodeID(int depth, const uint256& hash)
|
||||
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)
|
||||
{ // canonicalize the hash to a node ID for this depth
|
||||
assert(depth>=0 && depth<=leafDepth);
|
||||
@@ -101,15 +92,14 @@ SHAMapNode::SHAMapNode(int depth, const uint256 &hash) : mDepth(depth)
|
||||
}
|
||||
|
||||
SHAMapNode SHAMapNode::getChildNodeID(int m) const
|
||||
{
|
||||
{ // This can be optimized to avoid the << if needed
|
||||
assert(!isLeaf());
|
||||
assert((m>=0) && (m<32));
|
||||
|
||||
uint256 branch=m;
|
||||
branch<<=mDepth*8;
|
||||
|
||||
SHAMapNode ret(mDepth+1, mNodeID | branch);
|
||||
return ret;
|
||||
return SHAMapNode(mDepth+1, mNodeID | branch);
|
||||
}
|
||||
|
||||
int SHAMapNode::selectBranch(const uint256 &hash) const
|
||||
|
||||
@@ -443,7 +443,7 @@ bool SHAMap::syncTest()
|
||||
hashes.clear();
|
||||
|
||||
// get the list of nodes we know we need
|
||||
destination.getMissingNodes(nodeIDs, hashes, 512);
|
||||
destination.getMissingNodes(nodeIDs, hashes, 1024);
|
||||
if(!nodeIDs.size()) break;
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -469,6 +469,9 @@ bool SHAMap::syncTest()
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cerr << gotNodeIDs.size() << " found nodes" << std::endl;
|
||||
#endif
|
||||
for(nodeIDIterator=gotNodeIDs.begin(), rawNodeIterator=gotNodes.begin();
|
||||
nodeIDIterator!=gotNodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user