From 91dba8dcf3a537231bc743bac40332213bf1a6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Mon, 25 Sep 2023 15:35:53 +0200 Subject: [PATCH] Introduce `id_dispenser` class --- nano/lib/CMakeLists.txt | 1 + nano/lib/id_dispenser.hpp | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 nano/lib/id_dispenser.hpp diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index d0207325cb..1377a4416c 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -36,6 +36,7 @@ add_library( epoch.cpp errors.hpp errors.cpp + id_dispenser.hpp ipc.hpp ipc.cpp ipc_client.hpp diff --git a/nano/lib/id_dispenser.hpp b/nano/lib/id_dispenser.hpp new file mode 100644 index 0000000000..4b0cc53fe5 --- /dev/null +++ b/nano/lib/id_dispenser.hpp @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +namespace nano +{ +class id_dispenser +{ +public: + enum class mode + { + sequential, + random, + }; + + // Using pointer type for prettier and more concise output in logs (hex) + using id_t = void *; + +public: + explicit id_dispenser (mode mode = mode::random) : + mode_m{ mode } + { + } + + id_t next_id () + { + switch (mode_m) + { + case mode::sequential: + return reinterpret_cast (current_id_m.fetch_add (1)); + case mode::random: + auto value = get_dist () (get_rng ()); + if (value < min_m) + { + value += min_m; + } + return reinterpret_cast (value); + } + return 0; + } + +private: + // Avoid IDs with leading 0s for nicer output in logs + static constexpr uint64_t min_m{ 0x1000000000000000 }; + + mode mode_m; + std::atomic current_id_m{ min_m }; + + static std::mt19937 & get_rng () + { + static thread_local std::mt19937 rng{ std::random_device{}() }; + return rng; + } + + static std::uniform_int_distribution & get_dist () + { + static thread_local std::uniform_int_distribution dist; + return dist; + } +}; +} \ No newline at end of file