Skip to main content

reifydb_core/
fingerprint.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::ops::Deref;
5
6use reifydb_runtime::hash::Hash128;
7use serde::{Deserialize, Serialize};
8
9/// Stable identity for a query pattern, independent of literal values.
10///
11/// Two executions of `FROM t FILTER {x == 1}` and
12/// `FROM t FILTER {x == 2}` produce the same fingerprint.
13#[repr(transparent)]
14#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
15#[serde(transparent)]
16pub struct StatementFingerprint(pub Hash128);
17
18impl Deref for StatementFingerprint {
19	type Target = u128;
20
21	fn deref(&self) -> &Self::Target {
22		&self.0.0
23	}
24}
25
26impl StatementFingerprint {
27	#[inline]
28	pub const fn new(value: u128) -> Self {
29		Self(Hash128(value))
30	}
31
32	#[inline]
33	pub const fn as_u128(&self) -> u128 {
34		self.0.0
35	}
36
37	#[inline]
38	pub const fn to_le_bytes(&self) -> [u8; 16] {
39		self.0.0.to_le_bytes()
40	}
41
42	#[inline]
43	pub const fn from_le_bytes(bytes: [u8; 16]) -> Self {
44		Self(Hash128(u128::from_le_bytes(bytes)))
45	}
46
47	#[inline]
48	pub fn to_hex(&self) -> String {
49		self.0.to_hex_string_prefixed()
50	}
51}
52
53impl From<Hash128> for StatementFingerprint {
54	fn from(hash: Hash128) -> Self {
55		Self(hash)
56	}
57}
58
59impl From<StatementFingerprint> for Hash128 {
60	fn from(fp: StatementFingerprint) -> Self {
61		fp.0
62	}
63}
64
65impl From<u128> for StatementFingerprint {
66	fn from(value: u128) -> Self {
67		Self(Hash128(value))
68	}
69}
70
71/// Stable identity for an entire request (batch of statements).
72///
73/// Computed by combining the fingerprints of all individual statements
74/// in the request, preserving order.
75#[repr(transparent)]
76#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
77#[serde(transparent)]
78pub struct RequestFingerprint(pub Hash128);
79
80impl Deref for RequestFingerprint {
81	type Target = u128;
82
83	fn deref(&self) -> &Self::Target {
84		&self.0.0
85	}
86}
87
88impl RequestFingerprint {
89	#[inline]
90	pub const fn new(value: u128) -> Self {
91		Self(Hash128(value))
92	}
93
94	#[inline]
95	pub const fn as_u128(&self) -> u128 {
96		self.0.0
97	}
98
99	#[inline]
100	pub const fn to_le_bytes(&self) -> [u8; 16] {
101		self.0.0.to_le_bytes()
102	}
103
104	#[inline]
105	pub const fn from_le_bytes(bytes: [u8; 16]) -> Self {
106		Self(Hash128(u128::from_le_bytes(bytes)))
107	}
108
109	#[inline]
110	pub fn to_hex(&self) -> String {
111		self.0.to_hex_string_prefixed()
112	}
113}
114
115impl From<Hash128> for RequestFingerprint {
116	fn from(hash: Hash128) -> Self {
117		Self(hash)
118	}
119}
120
121impl From<RequestFingerprint> for Hash128 {
122	fn from(fp: RequestFingerprint) -> Self {
123		fp.0
124	}
125}
126
127impl From<u128> for RequestFingerprint {
128	fn from(value: u128) -> Self {
129		Self(Hash128(value))
130	}
131}
132
133/// Stable identity for a compiled query, keyed by the raw source text.
134///
135/// Used as the cache key for compiled instruction sequences, allowing
136/// identical query strings to skip parsing and planning.
137#[repr(transparent)]
138#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
139#[serde(transparent)]
140pub struct CompilationFingerprint(pub Hash128);
141
142impl Deref for CompilationFingerprint {
143	type Target = u128;
144
145	fn deref(&self) -> &Self::Target {
146		&self.0.0
147	}
148}
149
150impl CompilationFingerprint {
151	#[inline]
152	pub const fn new(value: u128) -> Self {
153		Self(Hash128(value))
154	}
155
156	#[inline]
157	pub const fn as_u128(&self) -> u128 {
158		self.0.0
159	}
160
161	#[inline]
162	pub const fn to_le_bytes(&self) -> [u8; 16] {
163		self.0.0.to_le_bytes()
164	}
165
166	#[inline]
167	pub const fn from_le_bytes(bytes: [u8; 16]) -> Self {
168		Self(Hash128(u128::from_le_bytes(bytes)))
169	}
170
171	#[inline]
172	pub fn to_hex(&self) -> String {
173		self.0.to_hex_string_prefixed()
174	}
175}
176
177impl From<Hash128> for CompilationFingerprint {
178	fn from(hash: Hash128) -> Self {
179		Self(hash)
180	}
181}
182
183impl From<CompilationFingerprint> for Hash128 {
184	fn from(fp: CompilationFingerprint) -> Self {
185		fp.0
186	}
187}
188
189impl From<u128> for CompilationFingerprint {
190	fn from(value: u128) -> Self {
191		Self(Hash128(value))
192	}
193}