reifydb_core/value/encoded/
uuid7.rs1use std::ptr;
5
6use reifydb_type::{Type, Uuid7};
7use uuid::Uuid;
8
9use crate::value::encoded::{EncodedValues, EncodedValuesLayout};
10
11impl EncodedValuesLayout {
12 pub fn set_uuid7(&self, row: &mut EncodedValues, index: usize, value: Uuid7) {
13 let field = &self.fields[index];
14 debug_assert!(row.len() >= self.total_static_size());
15 debug_assert_eq!(field.r#type, Type::Uuid7);
16 row.set_valid(index, true);
17 unsafe {
18 ptr::write_unaligned(
20 row.make_mut().as_mut_ptr().add(field.offset) as *mut [u8; 16],
21 *value.as_bytes(),
22 );
23 }
24 }
25
26 pub fn get_uuid7(&self, row: &EncodedValues, index: usize) -> Uuid7 {
27 let field = &self.fields[index];
28 debug_assert!(row.len() >= self.total_static_size());
29 debug_assert_eq!(field.r#type, Type::Uuid7);
30 unsafe {
31 let bytes: [u8; 16] = ptr::read_unaligned(row.as_ptr().add(field.offset) as *const [u8; 16]);
33 Uuid7::from(Uuid::from_bytes(bytes))
34 }
35 }
36
37 pub fn try_get_uuid7(&self, row: &EncodedValues, index: usize) -> Option<Uuid7> {
38 if row.is_defined(index) {
39 Some(self.get_uuid7(row, index))
40 } else {
41 None
42 }
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use reifydb_type::{Type, Uuid7};
49
50 use crate::value::encoded::EncodedValuesLayout;
51
52 #[test]
53 fn test_set_get_uuid7() {
54 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
55 let mut row = layout.allocate();
56
57 let uuid = Uuid7::generate();
58 layout.set_uuid7(&mut row, 0, uuid.clone());
59 assert_eq!(layout.get_uuid7(&row, 0), uuid);
60 }
61
62 #[test]
63 fn test_try_get_uuid7() {
64 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
65 let mut row = layout.allocate();
66
67 assert_eq!(layout.try_get_uuid7(&row, 0), None);
68
69 let uuid = Uuid7::generate();
70 layout.set_uuid7(&mut row, 0, uuid.clone());
71 assert_eq!(layout.try_get_uuid7(&row, 0), Some(uuid));
72 }
73
74 #[test]
75 fn test_multiple_generations() {
76 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
77
78 let mut uuids = Vec::new();
80 for _ in 0..10 {
81 let mut row = layout.allocate();
82 let uuid = Uuid7::generate();
83 layout.set_uuid7(&mut row, 0, uuid.clone());
84 let retrieved = layout.get_uuid7(&row, 0);
85 assert_eq!(retrieved, uuid);
86 uuids.push(uuid);
87 }
88
89 for i in 0..uuids.len() {
91 for j in (i + 1)..uuids.len() {
92 assert_ne!(uuids[i], uuids[j], "UUIDs should be unique");
93 }
94 }
95 }
96
97 #[test]
98 fn test_version_check() {
99 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
100 let mut row = layout.allocate();
101
102 let uuid = Uuid7::generate();
103 layout.set_uuid7(&mut row, 0, uuid.clone());
104 let retrieved = layout.get_uuid7(&row, 0);
105
106 assert_eq!(retrieved.get_version_num(), 7);
108 }
109
110 #[test]
111 fn test_timestamp_ordering() {
112 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
113
114 let mut uuids = Vec::new();
117 for _ in 0..5 {
118 let mut row = layout.allocate();
119 let uuid = Uuid7::generate();
120 layout.set_uuid7(&mut row, 0, uuid.clone());
121 let retrieved = layout.get_uuid7(&row, 0);
122 assert_eq!(retrieved, uuid);
123 uuids.push(uuid);
124
125 std::thread::sleep(std::time::Duration::from_millis(1));
127 }
128
129 for i in 1..uuids.len() {
131 assert!(uuids[i].as_bytes() >= uuids[i - 1].as_bytes(), "UUID7s should be timestamp-ordered");
132 }
133 }
134
135 #[test]
136 fn test_mixed_with_other_types() {
137 let layout = EncodedValuesLayout::new(&[Type::Uuid7, Type::Boolean, Type::Uuid7, Type::Int4]);
138 let mut row = layout.allocate();
139
140 let uuid1 = Uuid7::generate();
141 let uuid2 = Uuid7::generate();
142
143 layout.set_uuid7(&mut row, 0, uuid1.clone());
144 layout.set_bool(&mut row, 1, true);
145 layout.set_uuid7(&mut row, 2, uuid2.clone());
146 layout.set_i32(&mut row, 3, 42);
147
148 assert_eq!(layout.get_uuid7(&row, 0), uuid1);
149 assert_eq!(layout.get_bool(&row, 1), true);
150 assert_eq!(layout.get_uuid7(&row, 2), uuid2);
151 assert_eq!(layout.get_i32(&row, 3), 42);
152 }
153
154 #[test]
155 fn test_undefined_handling() {
156 let layout = EncodedValuesLayout::new(&[Type::Uuid7, Type::Uuid7]);
157 let mut row = layout.allocate();
158
159 let uuid = Uuid7::generate();
160 layout.set_uuid7(&mut row, 0, uuid.clone());
161
162 assert_eq!(layout.try_get_uuid7(&row, 0), Some(uuid));
163 assert_eq!(layout.try_get_uuid7(&row, 1), None);
164
165 layout.set_undefined(&mut row, 0);
166 assert_eq!(layout.try_get_uuid7(&row, 0), None);
167 }
168
169 #[test]
170 fn test_persistence() {
171 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
172 let mut row = layout.allocate();
173
174 let uuid = Uuid7::generate();
175 let uuid_string = uuid.to_string();
176
177 layout.set_uuid7(&mut row, 0, uuid.clone());
178 let retrieved = layout.get_uuid7(&row, 0);
179
180 assert_eq!(retrieved, uuid);
181 assert_eq!(retrieved.to_string(), uuid_string);
182 assert_eq!(retrieved.as_bytes(), uuid.as_bytes());
183 }
184
185 #[test]
186 fn test_clone_consistency() {
187 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
188 let mut row = layout.allocate();
189
190 let original_uuid = Uuid7::generate();
191 layout.set_uuid7(&mut row, 0, original_uuid.clone());
192
193 let retrieved_uuid = layout.get_uuid7(&row, 0);
194 assert_eq!(retrieved_uuid, original_uuid);
195
196 assert_eq!(retrieved_uuid.as_bytes(), original_uuid.as_bytes());
198 }
199
200 #[test]
201 fn test_multiple_fields() {
202 let layout = EncodedValuesLayout::new(&[Type::Uuid7, Type::Uuid7, Type::Uuid7]);
203 let mut row = layout.allocate();
204
205 let uuid1 = Uuid7::generate();
206 let uuid2 = Uuid7::generate();
207 let uuid3 = Uuid7::generate();
208
209 layout.set_uuid7(&mut row, 0, uuid1.clone());
210 layout.set_uuid7(&mut row, 1, uuid2.clone());
211 layout.set_uuid7(&mut row, 2, uuid3.clone());
212
213 assert_eq!(layout.get_uuid7(&row, 0), uuid1);
214 assert_eq!(layout.get_uuid7(&row, 1), uuid2);
215 assert_eq!(layout.get_uuid7(&row, 2), uuid3);
216
217 assert_ne!(uuid1, uuid2);
219 assert_ne!(uuid1, uuid3);
220 assert_ne!(uuid2, uuid3);
221 }
222
223 #[test]
224 fn test_format_consistency() {
225 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
226 let mut row = layout.allocate();
227
228 let uuid = Uuid7::generate();
229 let original_string = uuid.to_string();
230
231 layout.set_uuid7(&mut row, 0, uuid.clone());
232 let retrieved = layout.get_uuid7(&row, 0);
233 let retrieved_string = retrieved.to_string();
234
235 assert_eq!(original_string, retrieved_string);
236
237 assert_eq!(original_string.len(), 36);
239 assert_eq!(original_string.matches('-').count(), 4);
240 }
241
242 #[test]
243 fn test_byte_level_storage() {
244 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
245 let mut row = layout.allocate();
246
247 let uuid = Uuid7::generate();
248 let original_bytes = *uuid.as_bytes();
249
250 layout.set_uuid7(&mut row, 0, uuid.clone());
251 let retrieved = layout.get_uuid7(&row, 0);
252 let retrieved_bytes = *retrieved.as_bytes();
253
254 assert_eq!(original_bytes, retrieved_bytes);
255
256 assert_eq!(original_bytes.len(), 16);
258 assert_eq!(retrieved_bytes.len(), 16);
259 }
260
261 #[test]
262 fn test_time_based_properties() {
263 let layout = EncodedValuesLayout::new(&[Type::Uuid7]);
264
265 let uuid1 = Uuid7::generate();
267 std::thread::sleep(std::time::Duration::from_millis(2));
268 let uuid2 = Uuid7::generate();
269
270 let mut row1 = layout.allocate();
271 let mut row2 = layout.allocate();
272
273 layout.set_uuid7(&mut row1, 0, uuid1.clone());
274 layout.set_uuid7(&mut row2, 0, uuid2.clone());
275
276 let retrieved1 = layout.get_uuid7(&row1, 0);
277 let retrieved2 = layout.get_uuid7(&row2, 0);
278
279 assert!(retrieved2.as_bytes() > retrieved1.as_bytes());
281 }
282}