Unordered maps perform better than regular ones.

This commit is contained in:
JoelKatz
2012-02-02 16:14:11 -08:00
parent 9b804c0c61
commit fca8d4f8e9
3 changed files with 20 additions and 31 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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)
{