From edb00552246d4a9daa2f628d2cb57ed5696f095a Mon Sep 17 00:00:00 2001 From: cat Date: Sat, 31 Jan 2026 13:45:15 +0200 Subject: [PATCH] UUID has been updated to use a better hash and no unnecessary allocations (Big thanks to mosra!) --- headers/Types.hpp | 25 +++++++++-------------- source/Types/UUID.cpp | 46 ++++++++----------------------------------- 2 files changed, 17 insertions(+), 54 deletions(-) diff --git a/headers/Types.hpp b/headers/Types.hpp index 0dccc0b..7cc87ef 100644 --- a/headers/Types.hpp +++ b/headers/Types.hpp @@ -6,18 +6,18 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. */ + #ifndef GUARD_TOURMALINE_TYPES_H #define GUARD_TOURMALINE_TYPES_H + +#include "TourmalineExternal/random/xoshiro.h" #include #include -#include +#include + namespace Tourmaline::Type { class UUID { public: - constexpr static uint8_t BitLength = 128; - constexpr static uint8_t QWORDLength = BitLength / 64; - constexpr static uint8_t ByteLength = BitLength / 8; - [[nodiscard]] std::string asString() const; bool operator==(const UUID &rhs) const; @@ -25,14 +25,8 @@ public: UUID(uint64_t firstHalf, uint64_t secondHalf); UUID(const std::string &uuid); - UUID(const UUID &uuid); - UUID(UUID &&uuid) noexcept; - UUID &operator=(const UUID &uuid); - UUID &operator=(UUID &&uuid); - ~UUID() = default; - private: - std::unique_ptr data = std::make_unique(QWORDLength); + uint64_t firstHalf = 0, secondHalf = 0; friend struct std::hash; }; } // namespace Tourmaline::Type @@ -40,10 +34,9 @@ private: namespace std { template <> struct hash { size_t operator()(const Tourmaline::Type::UUID &uuid) const noexcept { - const auto data = uuid.data.get(); - size_t h1 = std::hash{}(data[0]), - h2 = std::hash{}(data[1]); - return h1 ^ (h2 << 1); + uint64_t hash = Xoshiro::splitmix64(uuid.firstHalf); + hash += uuid.secondHalf; + return Xoshiro::splitmix64(hash); } }; diff --git a/source/Types/UUID.cpp b/source/Types/UUID.cpp index eae8754..e027a8c 100644 --- a/source/Types/UUID.cpp +++ b/source/Types/UUID.cpp @@ -13,57 +13,27 @@ #include #include #include -#include #include using namespace Tourmaline::Type; std::string UUID::asString() const { - return std::format("{:016X}{:016X}", data[0], data[1]); + return std::format("{:016X}{:016X}", firstHalf, secondHalf); } bool UUID::operator==(const UUID &rhs) const { // Since size may be increased - for (uint8_t index = 0; index < QWORDLength; index++) { - if (this->data[index] != rhs.data[index]) { - return false; - } - } - return true; + return firstHalf == rhs.firstHalf && secondHalf == rhs.secondHalf; } -UUID::UUID(const UUID &uuid) { - std::memcpy(data.get(), uuid.data.get(), UUID::ByteLength); -} - -UUID &UUID::operator=(const UUID &uuid) { - if (this != &uuid) [[likely]] { - std::memcpy(data.get(), uuid.data.get(), UUID::ByteLength); - } - - return *this; -} - -UUID &UUID::operator=(UUID &&uuid) { - if (this != &uuid) [[likely]] { - data.swap(uuid.data); - } - - return *this; -} - -UUID::UUID(UUID &&uuid) noexcept { data.swap(uuid.data); } - -UUID::UUID(uint64_t firstHalf, uint64_t secondHalf) { - data[0] = firstHalf; - data[1] = secondHalf; -} +UUID::UUID(uint64_t firstHalf, uint64_t secondHalf) + : firstHalf(firstHalf), secondHalf(secondHalf) {} UUID::UUID(const std::string &uuid) { // We are assuming that it is a valid UUID, if not then somewhere else this // UUID should cause an error - auto start = uuid.c_str(), half = start + ByteLength, - tail = half + ByteLength; // Each UUID element is 16 characters padded + auto start = uuid.c_str(), half = start + 16, + tail = half + 16; // Each UUID element is 16 characters padded - std::from_chars(start, half, data[0], 16); - std::from_chars(half, tail, data[1], 16); + std::from_chars(start, half, firstHalf, 16); + std::from_chars(half, tail, secondHalf, 16); }