diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 872026d90..bcb893d54 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -271,7 +271,7 @@ bytesConstRef BlockChain::block(h256 _hash) const BlockDetails const& BlockChain::details(h256 _h) const { - std::map::const_iterator it; + BlockDetailsHash::const_iterator it; bool fetchRequired; { lock_guard l(m_lock); diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 9b77de24d..56906d32e 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -48,6 +48,8 @@ struct BlockDetails h256s children; }; +typedef std::hash_map BlockDetailsHash; + static const BlockDetails NullBlockDetails; static const h256s NullH256s; @@ -101,7 +103,7 @@ private: void checkConsistency(); /// Get fully populated from disk DB. - mutable std::map m_details; + mutable BlockDetailsHash m_details; mutable std::map m_cache; mutable std::mutex m_lock; diff --git a/libethereum/Common.h b/libethereum/Common.h index efdf825db..c8f15f599 100644 --- a/libethereum/Common.h +++ b/libethereum/Common.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -181,6 +182,43 @@ using HexMap = std::map; static const u256 Invalid256 = ~(u256)0; static const bytes NullBytes; +// This is the helper class for the std::hash_map lookup; it converts the input 256bit hash into a size_t sized hash value +// and does an exact comparison of two hash entries. +class H256Hash +{ +public: + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + + // Compute the size_t hash of this hash + size_t operator()(const h256 &index) const + { + const uint64_t *data = (const uint64_t *)index.data(); + uint64_t hash = data[0]; + hash ^= data[1]; + hash ^= data[2]; + hash ^= data[3]; + return (size_t)hash; + } + + // Return true if hash s1 is less than hash s2 + bool operator()(const h256 &s1, const h256 &s2) const + { + const uint64_t *hash1 = (const uint64_t *)s1.data(); + const uint64_t *hash2 = (const uint64_t *)s2.data(); + + if (hash1[0] < hash2[0]) return true; + if (hash1[0] > hash2[0]) return false; + + if (hash1[1] < hash2[1]) return true; + if (hash1[1] > hash2[1]) return false; + + if (hash1[2] < hash2[2]) return true; + if (hash1[2] > hash2[2]) return false; + + return hash1[3] < hash2[3]; + } +}; /// Logging class NullOutputStream