1use std::ptr;
5
6use reifydb_type::value::{
7 date::Date,
8 datetime::DateTime,
9 duration::Duration,
10 identity::IdentityId,
11 time::Time,
12 r#type::Type,
13 uuid::{Uuid4, Uuid7},
14};
15use uuid::Uuid;
16
17use crate::{
18 sort::SortDirection,
19 value::index::{encoded::EncodedIndexKey, shape::IndexShape},
20};
21
22impl IndexShape {
23 pub fn get_bool(&self, key: &EncodedIndexKey, index: usize) -> bool {
24 let field = &self.fields[index];
25 debug_assert_eq!(field.value, Type::Boolean);
26
27 let byte = unsafe { *key.as_ptr().add(field.offset) };
28
29 match field.direction {
30 SortDirection::Asc => byte != 0,
31 SortDirection::Desc => byte == 0,
32 }
33 }
34
35 pub fn get_f32(&self, key: &EncodedIndexKey, index: usize) -> f32 {
36 let field = &self.fields[index];
37 debug_assert_eq!(field.value, Type::Float4);
38
39 let mut bytes = [0u8; 4];
40 unsafe {
41 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 4);
42 }
43
44 if field.direction == SortDirection::Desc {
46 for b in bytes.iter_mut() {
47 *b = !*b;
48 }
49 }
50
51 if bytes[0] & 0x80 != 0 {
53 bytes[0] ^= 0x80;
54 } else {
55 for b in bytes.iter_mut() {
56 *b = !*b;
57 }
58 }
59
60 f32::from_bits(u32::from_be_bytes(bytes))
61 }
62
63 pub fn get_f64(&self, key: &EncodedIndexKey, index: usize) -> f64 {
64 let field = &self.fields[index];
65 debug_assert_eq!(field.value, Type::Float8);
66
67 let mut bytes = [0u8; 8];
68 unsafe {
69 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
70 }
71
72 if field.direction == SortDirection::Desc {
74 for b in bytes.iter_mut() {
75 *b = !*b;
76 }
77 }
78
79 if bytes[0] & 0x80 != 0 {
81 bytes[0] ^= 0x80;
82 } else {
83 for b in bytes.iter_mut() {
84 *b = !*b;
85 }
86 }
87
88 f64::from_bits(u64::from_be_bytes(bytes))
89 }
90
91 pub fn get_i8(&self, key: &EncodedIndexKey, index: usize) -> i8 {
92 let field = &self.fields[index];
93 debug_assert_eq!(field.value, Type::Int1);
94
95 let mut byte = unsafe { *key.as_ptr().add(field.offset) };
96
97 match field.direction {
98 SortDirection::Asc => {
99 byte ^= 0x80;
100 }
101 SortDirection::Desc => {
102 byte = !byte;
103 byte ^= 0x80;
104 }
105 }
106
107 i8::from_be_bytes([byte])
108 }
109
110 pub fn get_i16(&self, key: &EncodedIndexKey, index: usize) -> i16 {
111 let field = &self.fields[index];
112 debug_assert_eq!(field.value, Type::Int2);
113
114 let mut bytes = [0u8; 2];
115 unsafe {
116 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 2);
117 }
118
119 match field.direction {
120 SortDirection::Asc => {
121 bytes[0] ^= 0x80;
122 }
123 SortDirection::Desc => {
124 for b in bytes.iter_mut() {
125 *b = !*b;
126 }
127 bytes[0] ^= 0x80;
128 }
129 }
130
131 i16::from_be_bytes(bytes)
132 }
133
134 pub fn get_i32(&self, key: &EncodedIndexKey, index: usize) -> i32 {
135 let field = &self.fields[index];
136 debug_assert_eq!(field.value, Type::Int4);
137
138 let mut bytes = [0u8; 4];
139 unsafe {
140 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 4);
141 }
142
143 match field.direction {
144 SortDirection::Asc => {
145 bytes[0] ^= 0x80;
146 }
147 SortDirection::Desc => {
148 for b in bytes.iter_mut() {
149 *b = !*b;
150 }
151 bytes[0] ^= 0x80;
152 }
153 }
154
155 i32::from_be_bytes(bytes)
156 }
157
158 pub fn get_i64(&self, key: &EncodedIndexKey, index: usize) -> i64 {
159 let field = &self.fields[index];
160 debug_assert_eq!(field.value, Type::Int8);
161
162 let mut bytes = [0u8; 8];
163 unsafe {
164 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
165 }
166
167 match field.direction {
168 SortDirection::Asc => {
169 bytes[0] ^= 0x80;
170 }
171 SortDirection::Desc => {
172 for b in bytes.iter_mut() {
173 *b = !*b;
174 }
175 bytes[0] ^= 0x80;
176 }
177 }
178
179 i64::from_be_bytes(bytes)
180 }
181
182 pub fn get_i128(&self, key: &EncodedIndexKey, index: usize) -> i128 {
183 let field = &self.fields[index];
184 debug_assert_eq!(field.value, Type::Int16);
185
186 let mut bytes = [0u8; 16];
187 unsafe {
188 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
189 }
190
191 match field.direction {
192 SortDirection::Asc => {
193 bytes[0] ^= 0x80;
194 }
195 SortDirection::Desc => {
196 for b in bytes.iter_mut() {
197 *b = !*b;
198 }
199 bytes[0] ^= 0x80;
200 }
201 }
202
203 i128::from_be_bytes(bytes)
204 }
205
206 pub fn get_u8(&self, key: &EncodedIndexKey, index: usize) -> u8 {
207 let field = &self.fields[index];
208 debug_assert_eq!(field.value, Type::Uint1);
209
210 let byte = unsafe { *key.as_ptr().add(field.offset) };
211
212 match field.direction {
213 SortDirection::Asc => byte,
214 SortDirection::Desc => !byte,
215 }
216 }
217
218 pub fn get_u16(&self, key: &EncodedIndexKey, index: usize) -> u16 {
219 let field = &self.fields[index];
220 debug_assert_eq!(field.value, Type::Uint2);
221
222 let mut bytes = [0u8; 2];
223 unsafe {
224 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 2);
225 }
226
227 match field.direction {
228 SortDirection::Asc => u16::from_be_bytes(bytes),
229 SortDirection::Desc => !u16::from_be_bytes(bytes),
230 }
231 }
232
233 pub fn get_u32(&self, key: &EncodedIndexKey, index: usize) -> u32 {
234 let field = &self.fields[index];
235 debug_assert_eq!(field.value, Type::Uint4);
236
237 let mut bytes = [0u8; 4];
238 unsafe {
239 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 4);
240 }
241
242 match field.direction {
243 SortDirection::Asc => u32::from_be_bytes(bytes),
244 SortDirection::Desc => !u32::from_be_bytes(bytes),
245 }
246 }
247
248 pub fn get_u64(&self, key: &EncodedIndexKey, index: usize) -> u64 {
249 let field = &self.fields[index];
250 debug_assert_eq!(field.value, Type::Uint8);
251
252 let mut bytes = [0u8; 8];
253 unsafe {
254 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
255 }
256
257 match field.direction {
258 SortDirection::Asc => u64::from_be_bytes(bytes),
259 SortDirection::Desc => !u64::from_be_bytes(bytes),
260 }
261 }
262
263 pub fn get_u128(&self, key: &EncodedIndexKey, index: usize) -> u128 {
264 let field = &self.fields[index];
265 debug_assert_eq!(field.value, Type::Uint16);
266
267 let mut bytes = [0u8; 16];
268 unsafe {
269 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
270 }
271
272 match field.direction {
273 SortDirection::Asc => u128::from_be_bytes(bytes),
274 SortDirection::Desc => !u128::from_be_bytes(bytes),
275 }
276 }
277
278 pub fn get_row_number(&self, key: &EncodedIndexKey, index: usize) -> u64 {
279 let field = &self.fields[index];
280 debug_assert_eq!(field.value, Type::Uint8);
281
282 let mut bytes = [0u8; 8];
283 unsafe {
284 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
285 }
286
287 match field.direction {
288 SortDirection::Asc => u64::from_be_bytes(bytes),
289 SortDirection::Desc => !u64::from_be_bytes(bytes),
290 }
291 }
292
293 pub fn get_date(&self, key: &EncodedIndexKey, index: usize) -> Date {
294 let field = &self.fields[index];
295 debug_assert_eq!(field.value, Type::Date);
296
297 let mut bytes = [0u8; 4];
298 unsafe {
299 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 4);
300 }
301
302 match field.direction {
303 SortDirection::Asc => {
304 bytes[0] ^= 0x80;
305 }
306 SortDirection::Desc => {
307 for b in bytes.iter_mut() {
308 *b = !*b;
309 }
310 bytes[0] ^= 0x80;
311 }
312 }
313
314 let days = i32::from_be_bytes(bytes);
315 Date::from_days_since_epoch(days).unwrap()
316 }
317
318 pub fn get_datetime(&self, key: &EncodedIndexKey, index: usize) -> DateTime {
319 let field = &self.fields[index];
320 debug_assert_eq!(field.value, Type::DateTime);
321
322 let mut bytes = [0u8; 8];
323
324 unsafe {
325 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
326 }
327
328 let nanos = match field.direction {
329 SortDirection::Asc => u64::from_be_bytes(bytes),
330 SortDirection::Desc => !u64::from_be_bytes(bytes),
331 };
332
333 DateTime::from_nanos(nanos)
334 }
335
336 pub fn get_time(&self, key: &EncodedIndexKey, index: usize) -> Time {
337 let field = &self.fields[index];
338 debug_assert_eq!(field.value, Type::Time);
339
340 let mut bytes = [0u8; 8];
341 unsafe {
342 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
343 }
344
345 let nanos = match field.direction {
346 SortDirection::Asc => u64::from_be_bytes(bytes),
347 SortDirection::Desc => !u64::from_be_bytes(bytes),
348 };
349
350 Time::from_nanos_since_midnight(nanos).unwrap()
351 }
352
353 pub fn get_duration(&self, key: &EncodedIndexKey, index: usize) -> Duration {
354 let field = &self.fields[index];
355 debug_assert_eq!(field.value, Type::Duration);
356
357 let mut months_bytes = [0u8; 4];
358 let mut days_bytes = [0u8; 4];
359 let mut nanos_bytes = [0u8; 8];
360
361 unsafe {
362 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), months_bytes.as_mut_ptr(), 4);
363 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset + 4), days_bytes.as_mut_ptr(), 4);
364 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset + 8), nanos_bytes.as_mut_ptr(), 8);
365 }
366
367 match field.direction {
368 SortDirection::Asc => {
369 months_bytes[0] ^= 0x80;
370 days_bytes[0] ^= 0x80;
371 nanos_bytes[0] ^= 0x80;
372 }
373 SortDirection::Desc => {
374 for b in months_bytes.iter_mut() {
375 *b = !*b;
376 }
377 months_bytes[0] ^= 0x80;
378 for b in days_bytes.iter_mut() {
379 *b = !*b;
380 }
381 days_bytes[0] ^= 0x80;
382 for b in nanos_bytes.iter_mut() {
383 *b = !*b;
384 }
385 nanos_bytes[0] ^= 0x80;
386 }
387 }
388
389 let months = i32::from_be_bytes(months_bytes);
390 let days = i32::from_be_bytes(days_bytes);
391 let nanos = i64::from_be_bytes(nanos_bytes);
392 Duration::new(months, days, nanos).expect("stored duration must be valid")
393 }
394
395 pub fn get_uuid4(&self, key: &EncodedIndexKey, index: usize) -> Uuid4 {
396 let field = &self.fields[index];
397 debug_assert_eq!(field.value, Type::Uuid4);
398
399 let mut bytes = [0u8; 16];
400 unsafe {
401 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
402 }
403
404 if field.direction == SortDirection::Desc {
405 for b in bytes.iter_mut() {
406 *b = !*b;
407 }
408 }
409
410 let uuid = Uuid::from_bytes(bytes);
411 Uuid4::from(uuid)
412 }
413
414 pub fn get_uuid7(&self, key: &EncodedIndexKey, index: usize) -> Uuid7 {
415 let field = &self.fields[index];
416 debug_assert_eq!(field.value, Type::Uuid7);
417
418 let mut bytes = [0u8; 16];
419 unsafe {
420 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
421 }
422
423 if field.direction == SortDirection::Desc {
424 for b in bytes.iter_mut() {
425 *b = !*b;
426 }
427 }
428
429 let uuid = Uuid::from_bytes(bytes);
430 Uuid7::from(uuid)
431 }
432
433 pub fn get_identity_id(&self, key: &EncodedIndexKey, index: usize) -> IdentityId {
434 let field = &self.fields[index];
435 debug_assert_eq!(field.value, Type::IdentityId);
436
437 let mut bytes = [0u8; 16];
438 unsafe {
439 ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
440 }
441
442 if field.direction == SortDirection::Desc {
443 for b in bytes.iter_mut() {
444 *b = !*b;
445 }
446 }
447
448 let uuid = Uuid::from_bytes(bytes);
449 let uuid7 = Uuid7::from(uuid);
450 IdentityId::from(uuid7)
451 }
452}
453
454#[cfg(test)]
455pub mod tests {
456 use reifydb_type::value::r#type::Type;
457
458 use crate::{sort::SortDirection, value::index::shape::IndexShape};
459
460 mod bool {
461 use super::*;
462
463 #[test]
464 fn test_asc() {
465 let layout = IndexShape::new(&[Type::Boolean], &[SortDirection::Asc]).unwrap();
466 let mut key1 = layout.allocate_key();
467 let mut key2 = layout.allocate_key();
468
469 layout.set_bool(&mut key1, 0, false);
470 layout.set_bool(&mut key2, 0, true);
471
472 assert!(key1.as_slice() < key2.as_slice());
473 assert_eq!(layout.get_bool(&key1, 0), false);
474 assert_eq!(layout.get_bool(&key2, 0), true);
475 }
476
477 #[test]
478 fn test_desc() {
479 let layout = IndexShape::new(&[Type::Boolean], &[SortDirection::Desc]).unwrap();
480 let mut key1 = layout.allocate_key();
481 let mut key2 = layout.allocate_key();
482
483 layout.set_bool(&mut key1, 0, false);
484 layout.set_bool(&mut key2, 0, true);
485
486 assert!(key1.as_slice() > key2.as_slice());
487 assert_eq!(layout.get_bool(&key1, 0), false);
488 assert_eq!(layout.get_bool(&key2, 0), true);
489 }
490 }
491
492 mod i8 {
493 use reifydb_type::value::r#type::Type;
494
495 use crate::{sort::SortDirection, value::index::shape::IndexShape};
496
497 #[test]
498 fn test_asc() {
499 let layout = IndexShape::new(&[Type::Int1], &[SortDirection::Asc]).unwrap();
500 let mut key1 = layout.allocate_key();
501 let mut key2 = layout.allocate_key();
502 let mut key3 = layout.allocate_key();
503
504 layout.set_i8(&mut key1, 0, -10);
505 layout.set_i8(&mut key2, 0, 0);
506 layout.set_i8(&mut key3, 0, 10);
507
508 assert!(key1.as_slice() < key2.as_slice());
509 assert!(key2.as_slice() < key3.as_slice());
510 assert_eq!(layout.get_i8(&key1, 0), -10);
511 assert_eq!(layout.get_i8(&key2, 0), 0);
512 assert_eq!(layout.get_i8(&key3, 0), 10);
513 }
514
515 #[test]
516 fn test_desc() {
517 let layout = IndexShape::new(&[Type::Int1], &[SortDirection::Desc]).unwrap();
518 let mut key1 = layout.allocate_key();
519 let mut key2 = layout.allocate_key();
520 let mut key3 = layout.allocate_key();
521
522 layout.set_i8(&mut key1, 0, -10);
523 layout.set_i8(&mut key2, 0, 0);
524 layout.set_i8(&mut key3, 0, 10);
525
526 assert!(key1.as_slice() > key2.as_slice());
527 assert!(key2.as_slice() > key3.as_slice());
528 assert_eq!(layout.get_i8(&key1, 0), -10);
529 assert_eq!(layout.get_i8(&key2, 0), 0);
530 assert_eq!(layout.get_i8(&key3, 0), 10);
531 }
532 }
533
534 mod i32 {
535 use reifydb_type::value::r#type::Type;
536
537 use crate::{sort::SortDirection, value::index::shape::IndexShape};
538
539 #[test]
540 fn test_asc() {
541 let layout = IndexShape::new(&[Type::Int4], &[SortDirection::Asc]).unwrap();
542 let mut key1 = layout.allocate_key();
543 let mut key2 = layout.allocate_key();
544 let mut key3 = layout.allocate_key();
545
546 layout.set_i32(&mut key1, 0, -1000);
547 layout.set_i32(&mut key2, 0, 0);
548 layout.set_i32(&mut key3, 0, 1000);
549
550 assert!(key1.as_slice() < key2.as_slice());
551 assert!(key2.as_slice() < key3.as_slice());
552 assert_eq!(layout.get_i32(&key1, 0), -1000);
553 assert_eq!(layout.get_i32(&key2, 0), 0);
554 assert_eq!(layout.get_i32(&key3, 0), 1000);
555 }
556
557 #[test]
558 fn test_desc() {
559 let layout = IndexShape::new(&[Type::Int4], &[SortDirection::Desc]).unwrap();
560 let mut key1 = layout.allocate_key();
561 let mut key2 = layout.allocate_key();
562 let mut key3 = layout.allocate_key();
563
564 layout.set_i32(&mut key1, 0, -1000);
565 layout.set_i32(&mut key2, 0, 0);
566 layout.set_i32(&mut key3, 0, 1000);
567
568 assert!(key1.as_slice() > key2.as_slice());
569 assert!(key2.as_slice() > key3.as_slice());
570 assert_eq!(layout.get_i32(&key1, 0), -1000);
571 assert_eq!(layout.get_i32(&key2, 0), 0);
572 assert_eq!(layout.get_i32(&key3, 0), 1000);
573 }
574 }
575
576 mod i64 {
577 use reifydb_type::value::r#type::Type;
578
579 use crate::{sort::SortDirection, value::index::shape::IndexShape};
580
581 #[test]
582 fn test_asc() {
583 let layout = IndexShape::new(&[Type::Int8], &[SortDirection::Asc]).unwrap();
584 let mut key1 = layout.allocate_key();
585 let mut key2 = layout.allocate_key();
586 let mut key3 = layout.allocate_key();
587
588 layout.set_i64(&mut key1, 0, i64::MIN);
589 layout.set_i64(&mut key2, 0, 0);
590 layout.set_i64(&mut key3, 0, i64::MAX);
591
592 assert!(key1.as_slice() < key2.as_slice());
593 assert!(key2.as_slice() < key3.as_slice());
594 assert_eq!(layout.get_i64(&key1, 0), i64::MIN);
595 assert_eq!(layout.get_i64(&key2, 0), 0);
596 assert_eq!(layout.get_i64(&key3, 0), i64::MAX);
597 }
598
599 #[test]
600 fn test_desc() {
601 let layout = IndexShape::new(&[Type::Int8], &[SortDirection::Desc]).unwrap();
602 let mut key1 = layout.allocate_key();
603 let mut key2 = layout.allocate_key();
604 let mut key3 = layout.allocate_key();
605
606 layout.set_i64(&mut key1, 0, i64::MIN);
607 layout.set_i64(&mut key2, 0, 0);
608 layout.set_i64(&mut key3, 0, i64::MAX);
609
610 assert!(key1.as_slice() > key2.as_slice());
611 assert!(key2.as_slice() > key3.as_slice());
612 assert_eq!(layout.get_i64(&key1, 0), i64::MIN);
613 assert_eq!(layout.get_i64(&key2, 0), 0);
614 assert_eq!(layout.get_i64(&key3, 0), i64::MAX);
615 }
616 }
617
618 mod u8 {
619 use reifydb_type::value::r#type::Type;
620
621 use crate::{sort::SortDirection, value::index::shape::IndexShape};
622
623 #[test]
624 fn test_asc() {
625 let layout = IndexShape::new(&[Type::Uint1], &[SortDirection::Asc]).unwrap();
626 let mut key1 = layout.allocate_key();
627 let mut key2 = layout.allocate_key();
628 let mut key3 = layout.allocate_key();
629
630 layout.set_u8(&mut key1, 0, 0);
631 layout.set_u8(&mut key2, 0, 128);
632 layout.set_u8(&mut key3, 0, 255);
633
634 assert!(key1.as_slice() < key2.as_slice());
635 assert!(key2.as_slice() < key3.as_slice());
636 assert_eq!(layout.get_u8(&key1, 0), 0);
637 assert_eq!(layout.get_u8(&key2, 0), 128);
638 assert_eq!(layout.get_u8(&key3, 0), 255);
639 }
640
641 #[test]
642 fn test_desc() {
643 let layout = IndexShape::new(&[Type::Uint1], &[SortDirection::Desc]).unwrap();
644 let mut key1 = layout.allocate_key();
645 let mut key2 = layout.allocate_key();
646 let mut key3 = layout.allocate_key();
647
648 layout.set_u8(&mut key1, 0, 0);
649 layout.set_u8(&mut key2, 0, 128);
650 layout.set_u8(&mut key3, 0, 255);
651
652 assert!(key1.as_slice() > key2.as_slice());
653 assert!(key2.as_slice() > key3.as_slice());
654 assert_eq!(layout.get_u8(&key1, 0), 0);
655 assert_eq!(layout.get_u8(&key2, 0), 128);
656 assert_eq!(layout.get_u8(&key3, 0), 255);
657 }
658 }
659
660 mod u32 {
661 use reifydb_type::value::r#type::Type;
662
663 use crate::{sort::SortDirection, value::index::shape::IndexShape};
664
665 #[test]
666 fn test_asc() {
667 let layout = IndexShape::new(&[Type::Uint4], &[SortDirection::Asc]).unwrap();
668 let mut key1 = layout.allocate_key();
669 let mut key2 = layout.allocate_key();
670 let mut key3 = layout.allocate_key();
671
672 layout.set_u32(&mut key1, 0, 0u32);
673 layout.set_u32(&mut key2, 0, 1000000u32);
674 layout.set_u32(&mut key3, 0, u32::MAX);
675
676 assert!(key1.as_slice() < key2.as_slice());
677 assert!(key2.as_slice() < key3.as_slice());
678 assert_eq!(layout.get_u32(&key1, 0), 0);
679 assert_eq!(layout.get_u32(&key2, 0), 1000000);
680 assert_eq!(layout.get_u32(&key3, 0), u32::MAX);
681 }
682
683 #[test]
684 fn test_desc() {
685 let layout = IndexShape::new(&[Type::Uint4], &[SortDirection::Desc]).unwrap();
686 let mut key1 = layout.allocate_key();
687 let mut key2 = layout.allocate_key();
688 let mut key3 = layout.allocate_key();
689
690 layout.set_u32(&mut key1, 0, 0u32);
691 layout.set_u32(&mut key2, 0, 1000000u32);
692 layout.set_u32(&mut key3, 0, u32::MAX);
693
694 assert!(key1.as_slice() > key2.as_slice());
695 assert!(key2.as_slice() > key3.as_slice());
696 assert_eq!(layout.get_u32(&key1, 0), 0);
697 assert_eq!(layout.get_u32(&key2, 0), 1000000);
698 assert_eq!(layout.get_u32(&key3, 0), u32::MAX);
699 }
700 }
701
702 mod u64 {
703 use reifydb_type::value::r#type::Type;
704
705 use crate::{sort::SortDirection, value::index::shape::IndexShape};
706
707 #[test]
708 fn test_asc() {
709 let layout = IndexShape::new(&[Type::Uint8], &[SortDirection::Asc]).unwrap();
710 let mut key1 = layout.allocate_key();
711 let mut key2 = layout.allocate_key();
712 let mut key3 = layout.allocate_key();
713
714 layout.set_u64(&mut key1, 0, 0u64);
715 layout.set_u64(&mut key2, 0, 1_000_000_000u64);
716 layout.set_u64(&mut key3, 0, u64::MAX);
717
718 assert!(key1.as_slice() < key2.as_slice());
719 assert!(key2.as_slice() < key3.as_slice());
720 assert_eq!(layout.get_u64(&key1, 0), 0);
721 assert_eq!(layout.get_u64(&key2, 0), 1_000_000_000);
722 assert_eq!(layout.get_u64(&key3, 0), u64::MAX);
723 }
724
725 #[test]
726 fn test_desc() {
727 let layout = IndexShape::new(&[Type::Uint8], &[SortDirection::Desc]).unwrap();
728 let mut key1 = layout.allocate_key();
729 let mut key2 = layout.allocate_key();
730 let mut key3 = layout.allocate_key();
731
732 layout.set_u64(&mut key1, 0, 0u64);
733 layout.set_u64(&mut key2, 0, 1_000_000_000u64);
734 layout.set_u64(&mut key3, 0, u64::MAX);
735
736 assert!(key1.as_slice() > key2.as_slice());
737 assert!(key2.as_slice() > key3.as_slice());
738 assert_eq!(layout.get_u64(&key1, 0), 0);
739 assert_eq!(layout.get_u64(&key2, 0), 1_000_000_000);
740 assert_eq!(layout.get_u64(&key3, 0), u64::MAX);
741 }
742 }
743
744 mod f32 {
745 use reifydb_type::value::r#type::Type;
746
747 use crate::{sort::SortDirection, value::index::shape::IndexShape};
748
749 #[test]
750 fn test_asc() {
751 let layout = IndexShape::new(&[Type::Float4], &[SortDirection::Asc]).unwrap();
752 let mut key1 = layout.allocate_key();
753 let mut key2 = layout.allocate_key();
754 let mut key3 = layout.allocate_key();
755
756 layout.set_f32(&mut key1, 0, -100.5);
757 layout.set_f32(&mut key2, 0, 0.0);
758 layout.set_f32(&mut key3, 0, 100.5);
759
760 assert!(key1.as_slice() < key2.as_slice());
761 assert!(key2.as_slice() < key3.as_slice());
762 assert_eq!(layout.get_f32(&key1, 0), -100.5);
763 assert_eq!(layout.get_f32(&key2, 0), 0.0);
764 assert_eq!(layout.get_f32(&key3, 0), 100.5);
765 }
766
767 #[test]
768 fn test_desc() {
769 let layout = IndexShape::new(&[Type::Float4], &[SortDirection::Desc]).unwrap();
770 let mut key1 = layout.allocate_key();
771 let mut key2 = layout.allocate_key();
772 let mut key3 = layout.allocate_key();
773
774 layout.set_f32(&mut key1, 0, -100.5);
775 layout.set_f32(&mut key2, 0, 0.0);
776 layout.set_f32(&mut key3, 0, 100.5);
777
778 assert!(key1.as_slice() > key2.as_slice());
779 assert!(key2.as_slice() > key3.as_slice());
780 assert_eq!(layout.get_f32(&key1, 0), -100.5);
781 assert_eq!(layout.get_f32(&key2, 0), 0.0);
782 assert_eq!(layout.get_f32(&key3, 0), 100.5);
783 }
784 }
785
786 mod f64 {
787 use reifydb_type::value::r#type::Type;
788
789 use crate::{sort::SortDirection, value::index::shape::IndexShape};
790
791 #[test]
792 fn test_asc() {
793 let layout = IndexShape::new(&[Type::Float8], &[SortDirection::Asc]).unwrap();
794 let mut key1 = layout.allocate_key();
795 let mut key2 = layout.allocate_key();
796 let mut key3 = layout.allocate_key();
797
798 layout.set_f64(&mut key1, 0, -1000.123456);
799 layout.set_f64(&mut key2, 0, 0.0);
800 layout.set_f64(&mut key3, 0, 1000.123456);
801
802 assert!(key1.as_slice() < key2.as_slice());
803 assert!(key2.as_slice() < key3.as_slice());
804 assert_eq!(layout.get_f64(&key1, 0), -1000.123456);
805 assert_eq!(layout.get_f64(&key2, 0), 0.0);
806 assert_eq!(layout.get_f64(&key3, 0), 1000.123456);
807 }
808
809 #[test]
810 fn test_desc() {
811 let layout = IndexShape::new(&[Type::Float8], &[SortDirection::Desc]).unwrap();
812 let mut key1 = layout.allocate_key();
813 let mut key2 = layout.allocate_key();
814 let mut key3 = layout.allocate_key();
815
816 layout.set_f64(&mut key1, 0, -1000.123456);
817 layout.set_f64(&mut key2, 0, 0.0);
818 layout.set_f64(&mut key3, 0, 1000.123456);
819
820 assert!(key1.as_slice() > key2.as_slice());
821 assert!(key2.as_slice() > key3.as_slice());
822 assert_eq!(layout.get_f64(&key1, 0), -1000.123456);
823 assert_eq!(layout.get_f64(&key2, 0), 0.0);
824 assert_eq!(layout.get_f64(&key3, 0), 1000.123456);
825 }
826 }
827
828 mod date {
829 use reifydb_type::value::{date::Date, r#type::Type};
830
831 use crate::{sort::SortDirection, value::index::shape::IndexShape};
832
833 #[test]
834 fn test_asc() {
835 let layout = IndexShape::new(&[Type::Date], &[SortDirection::Asc]).unwrap();
836 let mut key1 = layout.allocate_key();
837 let mut key2 = layout.allocate_key();
838 let mut key3 = layout.allocate_key();
839
840 let date1 = Date::new(2020, 1, 1).unwrap();
841 let date2 = Date::new(2023, 6, 15).unwrap();
842 let date3 = Date::new(2025, 12, 31).unwrap();
843
844 layout.set_date(&mut key1, 0, date1.clone());
845 layout.set_date(&mut key2, 0, date2.clone());
846 layout.set_date(&mut key3, 0, date3.clone());
847
848 assert!(key1.as_slice() < key2.as_slice());
849 assert!(key2.as_slice() < key3.as_slice());
850 assert_eq!(layout.get_date(&key1, 0), date1);
851 assert_eq!(layout.get_date(&key2, 0), date2);
852 assert_eq!(layout.get_date(&key3, 0), date3);
853 }
854
855 #[test]
856 fn test_desc() {
857 let layout = IndexShape::new(&[Type::Date], &[SortDirection::Desc]).unwrap();
858 let mut key1 = layout.allocate_key();
859 let mut key2 = layout.allocate_key();
860 let mut key3 = layout.allocate_key();
861
862 let date1 = Date::new(2020, 1, 1).unwrap();
863 let date2 = Date::new(2023, 6, 15).unwrap();
864 let date3 = Date::new(2025, 12, 31).unwrap();
865
866 layout.set_date(&mut key1, 0, date1.clone());
867 layout.set_date(&mut key2, 0, date2.clone());
868 layout.set_date(&mut key3, 0, date3.clone());
869
870 assert!(key1.as_slice() > key2.as_slice());
871 assert!(key2.as_slice() > key3.as_slice());
872 assert_eq!(layout.get_date(&key1, 0), date1);
873 assert_eq!(layout.get_date(&key2, 0), date2);
874 assert_eq!(layout.get_date(&key3, 0), date3);
875 }
876 }
877
878 mod row_number {
879 use reifydb_type::value::r#type::Type;
880
881 use crate::{sort::SortDirection, value::index::shape::IndexShape};
882
883 #[test]
884 fn test_asc() {
885 let layout = IndexShape::new(&[Type::Uint8], &[SortDirection::Asc]).unwrap();
886 let mut key1 = layout.allocate_key();
887 let mut key2 = layout.allocate_key();
888 let mut key3 = layout.allocate_key();
889
890 layout.set_row_number(&mut key1, 0, 1u64);
891 layout.set_row_number(&mut key2, 0, 1000u64);
892 layout.set_row_number(&mut key3, 0, u64::MAX);
893
894 assert!(key1.as_slice() < key2.as_slice());
895 assert!(key2.as_slice() < key3.as_slice());
896 assert_eq!(layout.get_row_number(&key1, 0), 1);
897 assert_eq!(layout.get_row_number(&key2, 0), 1000);
898 assert_eq!(layout.get_row_number(&key3, 0), u64::MAX);
899 }
900
901 #[test]
902 fn test_desc() {
903 let layout = IndexShape::new(&[Type::Uint8], &[SortDirection::Desc]).unwrap();
904 let mut key1 = layout.allocate_key();
905 let mut key2 = layout.allocate_key();
906 let mut key3 = layout.allocate_key();
907
908 layout.set_row_number(&mut key1, 0, 1u64);
909 layout.set_row_number(&mut key2, 0, 1000u64);
910 layout.set_row_number(&mut key3, 0, u64::MAX);
911
912 assert!(key1.as_slice() > key2.as_slice());
913 assert!(key2.as_slice() > key3.as_slice());
914 assert_eq!(layout.get_row_number(&key1, 0), 1);
915 assert_eq!(layout.get_row_number(&key2, 0), 1000);
916 assert_eq!(layout.get_row_number(&key3, 0), u64::MAX);
917 }
918 }
919
920 mod identity_id {
921 use reifydb_runtime::context::{
922 clock::{Clock, MockClock},
923 rng::Rng,
924 };
925 use reifydb_type::value::{identity::IdentityId, r#type::Type};
926
927 use crate::{sort::SortDirection, value::index::shape::IndexShape};
928
929 fn test_clock_and_rng() -> (MockClock, Clock, Rng) {
930 let mock = MockClock::from_millis(1000);
931 let clock = Clock::Mock(mock.clone());
932 let rng = Rng::seeded(42);
933 (mock, clock, rng)
934 }
935
936 #[test]
937 fn test_asc() {
938 let (mock, clock, rng) = test_clock_and_rng();
939 let layout = IndexShape::new(&[Type::IdentityId], &[SortDirection::Asc]).unwrap();
940 let mut key1 = layout.allocate_key();
941 let mut key2 = layout.allocate_key();
942
943 let id1 = IdentityId::generate(&clock, &rng);
944 mock.advance_millis(10);
946 let id2 = IdentityId::generate(&clock, &rng);
947
948 layout.set_identity_id(&mut key1, 0, id1.clone());
949 layout.set_identity_id(&mut key2, 0, id2.clone());
950
951 assert!(key1.as_slice() < key2.as_slice());
953 assert_eq!(layout.get_identity_id(&key1, 0), id1);
955 assert_eq!(layout.get_identity_id(&key2, 0), id2);
956 }
957
958 #[test]
959 fn test_desc() {
960 let (mock, clock, rng) = test_clock_and_rng();
961 let layout = IndexShape::new(&[Type::IdentityId], &[SortDirection::Desc]).unwrap();
962 let mut key1 = layout.allocate_key();
963 let mut key2 = layout.allocate_key();
964
965 let id1 = IdentityId::generate(&clock, &rng);
966 mock.advance_millis(10);
968 let id2 = IdentityId::generate(&clock, &rng);
969
970 layout.set_identity_id(&mut key1, 0, id1.clone());
971 layout.set_identity_id(&mut key2, 0, id2.clone());
972
973 assert!(key1.as_slice() > key2.as_slice());
975 assert_eq!(layout.get_identity_id(&key1, 0), id1);
977 assert_eq!(layout.get_identity_id(&key2, 0), id2);
978 }
979
980 #[test]
981 fn test_roundtrip() {
982 let (_mock, clock, rng) = test_clock_and_rng();
983 let layout = IndexShape::new(&[Type::IdentityId], &[SortDirection::Asc]).unwrap();
984
985 let id = IdentityId::generate(&clock, &rng);
986 let mut key = layout.allocate_key();
987
988 layout.set_identity_id(&mut key, 0, id.clone());
990 let retrieved = layout.get_identity_id(&key, 0);
991 assert_eq!(retrieved, id);
992 }
993 }
994
995 mod composite {
996 use reifydb_type::value::r#type::Type;
997
998 use crate::{sort::SortDirection, value::index::shape::IndexShape};
999
1000 #[test]
1001 fn test_mixed_directions() {
1002 let layout = IndexShape::new(
1003 &[Type::Int4, Type::Uint8, Type::Uint8],
1004 &[SortDirection::Desc, SortDirection::Asc, SortDirection::Asc],
1005 )
1006 .unwrap();
1007
1008 let mut key1 = layout.allocate_key();
1009 let mut key2 = layout.allocate_key();
1010 let mut key3 = layout.allocate_key();
1011 let mut key4 = layout.allocate_key();
1012
1013 layout.set_i32(&mut key1, 0, 100);
1014 layout.set_u64(&mut key1, 1, 1u64);
1015 layout.set_row_number(&mut key1, 2, 1u64);
1016
1017 layout.set_i32(&mut key2, 0, 100);
1018 layout.set_u64(&mut key2, 1, 2u64);
1019 layout.set_row_number(&mut key2, 2, 1u64);
1020
1021 layout.set_i32(&mut key3, 0, 50);
1022 layout.set_u64(&mut key3, 1, 1u64);
1023 layout.set_row_number(&mut key3, 2, 1u64);
1024
1025 layout.set_i32(&mut key4, 0, 50);
1026 layout.set_u64(&mut key4, 1, 1u64);
1027 layout.set_row_number(&mut key4, 2, 2u64);
1028
1029 assert!(key1.as_slice() < key2.as_slice());
1032 assert!(key1.as_slice() < key3.as_slice());
1035 assert!(key3.as_slice() < key4.as_slice());
1038 }
1039 }
1040}