Everett
Loading...
Searching...
No Matches
fingerprint.h
Go to the documentation of this file.
1
13#pragma once
14
15#include <cstdint>
16#include <optional>
17#include <string_view>
18
19namespace everett {
20 // A legitimate ring choice, Z/(2^64). Unsigned overflow is intentional.
21 // Other policies need zero(), lift(u64), add(), subtract(), and multiply().
23 using element = std::uint64_t;
24 static constexpr element zero() noexcept { return 0; }
25 static constexpr element lift(std::uint64_t x) noexcept { return x; }
26 static constexpr element add(element x, element y) noexcept { return x + y; }
27 static constexpr element subtract(element x, element y) noexcept { return x - y; }
28 static constexpr element multiply(element x, element y) noexcept { return x * y; }
29 };
30
31 // Stable byte hashing for the reference u64-valued store. This is a sanity
32 // fingerprint, neither an authentication mechanism nor a physical file ID.
34 static constexpr std::uint64_t mix(std::uint64_t x) noexcept {
35 x ^= x >> 30;
36 x *= 0xbf58476d1ce4e5b9ULL;
37 x ^= x >> 27;
38 x *= 0x94d049bb133111ebULL;
39 return x ^ (x >> 31);
40 }
41
42 std::uint64_t key(std::string_view text) const noexcept {
43 std::uint64_t result = 0xcbf29ce484222325ULL;
44 for (unsigned char c : text) {
45 result ^= c;
46 result *= 0x100000001b3ULL;
47 }
48 return mix(result);
49 }
50
51 std::uint64_t value(std::uint64_t x) const noexcept {
52 return mix(x ^ 0xd6e8feb86659fd93ULL);
53 }
54 };
55
56 template <class A = wrapping_fingerprint_algebra> struct table_fingerprint {
57 using element = typename A::element;
58
59 template <class V, class H>
60 static element binding(std::string_view key, std::optional<V> const & value,
61 H const & hash) {
62 // h_V(Nothing) = 0 independently of the supplied value hash.
63 return value ? A::multiply(A::lift(hash.key(key)), A::lift(hash.value(*value)))
64 : A::zero();
65 }
66
67 template <class V, class H>
68 static element delta(std::string_view key, std::optional<V> const & before,
69 std::optional<V> const & after, H const & hash) {
70 auto old_hash = before ? A::lift(hash.value(*before)) : A::zero();
71 auto new_hash = after ? A::lift(hash.value(*after)) : A::zero();
72 return A::multiply(A::lift(hash.key(key)), A::subtract(new_hash, old_hash));
73 }
74 };
75}
Definition active_engine.h:18
Definition fingerprint.h:56
typename A::element element
Definition fingerprint.h:57
static element delta(std::string_view key, std::optional< V > const &before, std::optional< V > const &after, H const &hash)
Definition fingerprint.h:68
static element binding(std::string_view key, std::optional< V > const &value, H const &hash)
Definition fingerprint.h:60
Definition fingerprint.h:33
std::uint64_t value(std::uint64_t x) const noexcept
Definition fingerprint.h:51
std::uint64_t key(std::string_view text) const noexcept
Definition fingerprint.h:42
static constexpr std::uint64_t mix(std::uint64_t x) noexcept
Definition fingerprint.h:34
Definition fingerprint.h:22
static constexpr element multiply(element x, element y) noexcept
Definition fingerprint.h:28
static constexpr element subtract(element x, element y) noexcept
Definition fingerprint.h:27
static constexpr element add(element x, element y) noexcept
Definition fingerprint.h:26
static constexpr element zero() noexcept
Definition fingerprint.h:24
std::uint64_t element
Definition fingerprint.h:23
static constexpr element lift(std::uint64_t x) noexcept
Definition fingerprint.h:25