diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index e68e2538e..2cf81cb77 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -64,6 +64,9 @@ public: /// Convert from the corresponding arithmetic type. FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); } + /// Convert from unsigned + explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); } + /// Explicitly construct, copying from a byte array. explicit FixedHash(bytes const& _b, ConstructFromHashType _t = FailIfDifferent) { if (_b.size() == N) memcpy(m_data.data(), _b.data(), std::min(_b.size(), N)); else { m_data.fill(0); if (_t != FailIfDifferent) { auto c = std::min(_b.size(), N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i]; } } } diff --git a/libdevcore/Guards.h b/libdevcore/Guards.h index 8d2e8961d..d060108ef 100644 --- a/libdevcore/Guards.h +++ b/libdevcore/Guards.h @@ -66,11 +66,11 @@ struct GenericUnguardSharedBool class SpinLock { public: - SpinLock() { lck.clear(); } - void lock() { while (lck.test_and_set(std::memory_order_acquire)) {} } - void unlock() { lck.clear(std::memory_order_release); } + SpinLock() { m_lock.clear(); } + void lock() { while (m_lock.test_and_set(std::memory_order_acquire)) {} } + void unlock() { m_lock.clear(std::memory_order_release); } private: - std::atomic_flag lck; + std::atomic_flag m_lock; }; using SpinGuard = std::lock_guard; diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index c51188506..204203c9d 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -293,13 +293,9 @@ LastHashes BlockChain::lastHashes(unsigned _n) const Guard l(x_lastLastHashes); if (m_lastLastHashesNumber != _n || m_lastLastHashes.empty()) { - LastHashes lastHashes(256); + m_lastLastHashes.resize(256); for (unsigned i = 0; i < 256; ++i) - { - size_t prevIndex = m_lastLastHashesNumber - _n + i; - lastHashes[i] = (prevIndex < m_lastLastHashes.size()) ? m_lastLastHashes[prevIndex] : (_n >= i ? numberHash(_n - i) : h256()); - } - m_lastLastHashes = std::move(lastHashes); + m_lastLastHashes[i] = _n >= i ? numberHash(_n - i) : h256(); m_lastLastHashesNumber = _n; } return m_lastLastHashes; @@ -613,6 +609,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import } clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << route; + noteCanonChanged(); StructuredLogger::chainNewHead( bi.headerHash(WithoutNonce).abridged(), @@ -770,7 +767,7 @@ void BlockChain::noteUsed(h256 const& _h, unsigned _extra) const m_inUse.insert(id); } -template static unsigned getHashSize(map const& _map) +template static unsigned getHashSize(unordered_map const& _map) { unsigned ret = 0; for (auto const& i: _map) @@ -858,7 +855,7 @@ void BlockChain::garbageCollect(bool _force) } } m_cacheUsage.pop_back(); - m_cacheUsage.push_front(std::set{}); + m_cacheUsage.push_front(std::unordered_set{}); } void BlockChain::checkConsistency() diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 5756d1811..f69f67a5d 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include #include @@ -40,6 +42,11 @@ #include "BlockQueue.h" namespace ldb = leveldb; +template <> struct std::hash> +{ + size_t operator()(const pair &x ) const { return std::hash()(x.first) ^ std::hash()(x.second); } +}; + namespace dev { @@ -66,7 +73,7 @@ std::map const& genesisState(); ldb::Slice toSlice(h256 const& _h, unsigned _sub = 0); -using BlocksHash = std::map; +using BlocksHash = std::unordered_map; using TransactionHashes = h256s; using UncleHashes = h256s; using ImportRoute = std::pair; @@ -144,7 +151,7 @@ public: UncleHashes uncleHashes() const { return uncleHashes(currentHash()); } /// Get the hash for a given block's number. - h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras(h256(u256(_i)), m_blockHashes, x_blockHashes, NullBlockHash).value; } + h256 numberHash(unsigned _i) const { if (!_i) return genesisHash(); return queryExtras(h256(_i), m_blockHashes, x_blockHashes, NullBlockHash).value; } /// Get the last N hashes for a given block. (N is determined by the LastHashes type.) LastHashes lastHashes() const { return lastHashes(number()); } @@ -251,7 +258,7 @@ private: void open(std::string const& _path, WithExisting _we = WithExisting::Trust); void close(); - template T queryExtras(h256 const& _h, std::map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const + template T queryExtras(h256 const& _h, std::unordered_map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const { { ReadGuard l(_x); @@ -295,11 +302,12 @@ private: using CacheID = std::pair; mutable Mutex x_cacheUsage; - mutable std::deque> m_cacheUsage; - mutable std::set m_inUse; + mutable std::deque> m_cacheUsage; + mutable std::unordered_set m_inUse; void noteUsed(h256 const& _h, unsigned _extra = (unsigned)-1) const; std::chrono::system_clock::time_point m_lastCollection; + void noteCanonChanged() const { Guard l(x_lastLastHashes); m_lastLastHashes.clear(); } mutable Mutex x_lastLastHashes; mutable LastHashes m_lastLastHashes; mutable unsigned m_lastLastHashesNumber = (unsigned)-1; diff --git a/libethereum/BlockDetails.h b/libethereum/BlockDetails.h index 0baacb4da..19e2c7c7a 100644 --- a/libethereum/BlockDetails.h +++ b/libethereum/BlockDetails.h @@ -21,6 +21,7 @@ #pragma once +#include #pragma warning(push) #pragma warning(disable: 4100 4267) #include @@ -114,12 +115,12 @@ struct TransactionAddress static const unsigned size = 67; }; -using BlockDetailsHash = std::map; -using BlockLogBloomsHash = std::map; -using BlockReceiptsHash = std::map; -using TransactionAddressHash = std::map; -using BlockHashHash = std::map; -using BlocksBloomsHash = std::map; +using BlockDetailsHash = std::unordered_map; +using BlockLogBloomsHash = std::unordered_map; +using BlockReceiptsHash = std::unordered_map; +using TransactionAddressHash = std::unordered_map; +using BlockHashHash = std::unordered_map; +using BlocksBloomsHash = std::unordered_map; static const BlockDetails NullBlockDetails; static const BlockLogBlooms NullBlockLogBlooms;