UUID has been updated to use a better hash and no unnecessary allocations (Big thanks to mosra!)
This commit is contained in:
@@ -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 <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
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<uint64_t[]> data = std::make_unique<uint64_t[]>(QWORDLength);
|
||||
uint64_t firstHalf = 0, secondHalf = 0;
|
||||
friend struct std::hash<Tourmaline::Type::UUID>;
|
||||
};
|
||||
} // namespace Tourmaline::Type
|
||||
@@ -40,10 +34,9 @@ private:
|
||||
namespace std {
|
||||
template <> struct hash<Tourmaline::Type::UUID> {
|
||||
size_t operator()(const Tourmaline::Type::UUID &uuid) const noexcept {
|
||||
const auto data = uuid.data.get();
|
||||
size_t h1 = std::hash<uint64_t>{}(data[0]),
|
||||
h2 = std::hash<uint64_t>{}(data[1]);
|
||||
return h1 ^ (h2 << 1);
|
||||
uint64_t hash = Xoshiro::splitmix64(uuid.firstHalf);
|
||||
hash += uuid.secondHalf;
|
||||
return Xoshiro::splitmix64(hash);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -13,57 +13,27 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user