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