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