Switch to faster unordered_map/set
This commit is contained in:
@@ -279,6 +279,11 @@ enum class NetworkType {
|
||||
Stagenet,
|
||||
};
|
||||
|
||||
void* malloc_hook(size_t n) noexcept;
|
||||
void* realloc_hook(void* ptr, size_t size) noexcept;
|
||||
void* calloc_hook(size_t count, size_t size) noexcept;
|
||||
void free_hook(void* p) noexcept;
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
#include "util.h"
|
||||
|
||||
+2
-3
@@ -20,7 +20,6 @@
|
||||
#include "keccak.h"
|
||||
#include "uv_util.h"
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
|
||||
extern "C" {
|
||||
#include "crypto-ops.h"
|
||||
@@ -237,8 +236,8 @@ public:
|
||||
|
||||
private:
|
||||
uv_mutex_t m;
|
||||
std::unordered_map<std::array<uint8_t, HASH_SIZE * 2>, hash> derivations;
|
||||
std::unordered_map<std::array<uint8_t, HASH_SIZE * 2 + sizeof(size_t)>, hash> public_keys;
|
||||
unordered_map<std::array<uint8_t, HASH_SIZE * 2>, hash> derivations;
|
||||
unordered_map<std::array<uint8_t, HASH_SIZE * 2 + sizeof(size_t)>, hash> public_keys;
|
||||
};
|
||||
|
||||
static Cache* cache = nullptr;
|
||||
|
||||
+21
-12
@@ -120,7 +120,7 @@ FORCEINLINE static void remove_allocation(void* p)
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
FORCEINLINE static void* allocate_noexcept(size_t n) noexcept
|
||||
void* malloc_hook(size_t n) noexcept
|
||||
{
|
||||
void* p = malloc(n);
|
||||
if (p) {
|
||||
@@ -131,20 +131,20 @@ FORCEINLINE static void* allocate_noexcept(size_t n) noexcept
|
||||
|
||||
FORCEINLINE static void* allocate(size_t n)
|
||||
{
|
||||
void* p = allocate_noexcept(n);
|
||||
void* p = malloc_hook(n);
|
||||
if (!p) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
FORCEINLINE static void deallocate(void* p)
|
||||
void free_hook(void* p) noexcept
|
||||
{
|
||||
remove_allocation(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void* uv_realloc_hook(void* ptr, size_t size)
|
||||
void* realloc_hook(void* ptr, size_t size) noexcept
|
||||
{
|
||||
remove_allocation(ptr);
|
||||
|
||||
@@ -155,7 +155,7 @@ static void* uv_realloc_hook(void* ptr, size_t size)
|
||||
return p;
|
||||
}
|
||||
|
||||
static void* uv_calloc_hook(size_t count, size_t size)
|
||||
void* calloc_hook(size_t count, size_t size) noexcept
|
||||
{
|
||||
void* p = calloc(count, size);
|
||||
if (p) {
|
||||
@@ -170,7 +170,7 @@ void memory_tracking_start()
|
||||
{
|
||||
using namespace p2pool;
|
||||
|
||||
uv_replace_allocator(allocate_noexcept, uv_realloc_hook, uv_calloc_hook, deallocate);
|
||||
uv_replace_allocator(malloc_hook, realloc_hook, calloc_hook, free_hook);
|
||||
uv_mutex_init_checked(&allocation_lock);
|
||||
track_memory = true;
|
||||
}
|
||||
@@ -228,14 +228,23 @@ void memory_tracking_stop()
|
||||
|
||||
NOINLINE void* operator new(size_t n) { return p2pool::allocate(n); }
|
||||
NOINLINE void* operator new[](size_t n) { return p2pool::allocate(n); }
|
||||
NOINLINE void* operator new(size_t n, const std::nothrow_t&) noexcept { return p2pool::allocate_noexcept(n); }
|
||||
NOINLINE void* operator new[](size_t n, const std::nothrow_t&) noexcept { return p2pool::allocate_noexcept(n); }
|
||||
NOINLINE void operator delete(void* p) noexcept { p2pool::deallocate(p); }
|
||||
NOINLINE void operator delete[](void* p) noexcept { p2pool::deallocate(p); }
|
||||
NOINLINE void operator delete(void* p, size_t) noexcept { p2pool::deallocate(p); }
|
||||
NOINLINE void operator delete[](void* p, size_t) noexcept { p2pool::deallocate(p); }
|
||||
NOINLINE void* operator new(size_t n, const std::nothrow_t&) noexcept { return p2pool::malloc_hook(n); }
|
||||
NOINLINE void* operator new[](size_t n, const std::nothrow_t&) noexcept { return p2pool::malloc_hook(n); }
|
||||
NOINLINE void operator delete(void* p) noexcept { p2pool::free_hook(p); }
|
||||
NOINLINE void operator delete[](void* p) noexcept { p2pool::free_hook(p); }
|
||||
NOINLINE void operator delete(void* p, size_t) noexcept { p2pool::free_hook(p); }
|
||||
NOINLINE void operator delete[](void* p, size_t) noexcept { p2pool::free_hook(p); }
|
||||
|
||||
#else
|
||||
void memory_tracking_start() {}
|
||||
void memory_tracking_stop() {}
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
void* malloc_hook(size_t n) noexcept { return malloc(n); }
|
||||
void* realloc_hook(void* ptr, size_t size) noexcept { return realloc(ptr, size); }
|
||||
void* calloc_hook(size_t count, size_t size) noexcept { return calloc(count, size); }
|
||||
void free_hook(void* p) noexcept { free(p); }
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "uv_util.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -35,7 +34,7 @@ public:
|
||||
|
||||
public:
|
||||
mutable uv_rwlock_t m_lock;
|
||||
std::unordered_map<hash, TxMempoolData> m_transactions;
|
||||
unordered_map<hash, TxMempoolData> m_transactions;
|
||||
};
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
+1
-2
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "tcp_server.h"
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -132,7 +131,7 @@ private:
|
||||
std::string m_initialPeerList;
|
||||
|
||||
uv_rwlock_t m_cachedBlocksLock;
|
||||
std::unordered_map<hash, PoolBlock*> m_cachedBlocks;
|
||||
unordered_map<hash, PoolBlock*> m_cachedBlocks;
|
||||
|
||||
private:
|
||||
static void on_timer(uv_timer_t* timer) { reinterpret_cast<P2PServer*>(timer->data)->on_timer(); }
|
||||
|
||||
+1
-2
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "uv_util.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -104,7 +103,7 @@ private:
|
||||
|
||||
mutable uv_rwlock_t m_mainchainLock;
|
||||
std::map<uint64_t, ChainMain> m_mainchainByHeight;
|
||||
std::unordered_map<hash, ChainMain> m_mainchainByHash;
|
||||
unordered_map<hash, ChainMain> m_mainchainByHash;
|
||||
|
||||
enum { TIMESTAMP_WINDOW = 60 };
|
||||
bool get_timestamps(uint64_t (×tamps)[TIMESTAMP_WINDOW]) const;
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ void p2pool_api::dump_to_file_async_internal(const Category& category, const cha
|
||||
|
||||
void p2pool_api::dump_to_file()
|
||||
{
|
||||
std::unordered_map<std::string, std::vector<char>> data;
|
||||
unordered_map<std::string, std::vector<char>> data;
|
||||
{
|
||||
MutexLock lock(m_dumpDataLock);
|
||||
data = std::move(m_dumpData);
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "uv_util.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -84,7 +83,7 @@ private:
|
||||
std::string m_localPath;
|
||||
|
||||
uv_mutex_t m_dumpDataLock;
|
||||
std::unordered_map<std::string, std::vector<char>> m_dumpData;
|
||||
unordered_map<std::string, std::vector<char>> m_dumpData;
|
||||
|
||||
uv_async_t m_dumpToFileAsync;
|
||||
};
|
||||
|
||||
+3
-5
@@ -19,8 +19,6 @@
|
||||
|
||||
#include "uv_util.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -98,9 +96,9 @@ private:
|
||||
mutable uv_mutex_t m_sidechainLock;
|
||||
PoolBlock* m_chainTip;
|
||||
std::map<uint64_t, std::vector<PoolBlock*>> m_blocksByHeight;
|
||||
std::unordered_map<hash, PoolBlock*> m_blocksById;
|
||||
std::unordered_set<hash> m_seenBlocks;
|
||||
std::unordered_map<hash, time_t> m_seenWallets;
|
||||
unordered_map<hash, PoolBlock*> m_blocksById;
|
||||
unordered_set<hash> m_seenBlocks;
|
||||
unordered_map<hash, time_t> m_seenWallets;
|
||||
|
||||
std::vector<DifficultyData> m_difficultyData;
|
||||
|
||||
|
||||
+25
-12
@@ -17,6 +17,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 5027)
|
||||
#endif
|
||||
|
||||
#define ROBIN_HOOD_MALLOC(size) p2pool::malloc_hook(size)
|
||||
#define ROBIN_HOOD_CALLOC(count, size) p2pool::calloc_hook((count), (size))
|
||||
#define ROBIN_HOOD_FREE(ptr) p2pool::free_hook(ptr)
|
||||
|
||||
#include "robin_hood.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
extern const char* VERSION;
|
||||
@@ -122,20 +137,22 @@ extern thread_local bool is_main_thread;
|
||||
|
||||
bool resolve_host(std::string& host, bool& is_v6);
|
||||
|
||||
template <typename Key, typename T>
|
||||
using unordered_map = robin_hood::detail::Table<false, 80, Key, T, robin_hood::hash<Key>, std::equal_to<Key>>;
|
||||
|
||||
template <typename Key>
|
||||
using unordered_set = robin_hood::detail::Table<false, 80, Key, void, robin_hood::hash<Key>, std::equal_to<Key>>;
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
namespace std {
|
||||
namespace robin_hood {
|
||||
|
||||
template<>
|
||||
struct hash<p2pool::hash>
|
||||
{
|
||||
FORCEINLINE size_t operator()(const p2pool::hash& value) const noexcept
|
||||
{
|
||||
uint64_t result = 0xcbf29ce484222325ull;
|
||||
for (size_t i = 0; i < p2pool::HASH_SIZE; ++i) {
|
||||
result = (result ^ value.h[i]) * 0x100000001b3ull;
|
||||
}
|
||||
return static_cast<size_t>(result);
|
||||
return hash_bytes(value.h, p2pool::HASH_SIZE);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -144,12 +161,8 @@ struct hash<std::array<uint8_t, N>>
|
||||
{
|
||||
FORCEINLINE size_t operator()(const std::array<uint8_t, N>& value) const noexcept
|
||||
{
|
||||
uint64_t result = 0xcbf29ce484222325ull;
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
result = (result ^ value[i]) * 0x100000001b3ull;
|
||||
}
|
||||
return static_cast<size_t>(result);
|
||||
return hash_bytes(value.data(), N);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
} // namespace robin_hood
|
||||
|
||||
Reference in New Issue
Block a user