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