1use std::{f64, 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 set_bool(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<bool>) {
28 let field = &self.fields[index];
29 reifydb_assertions! {
30 assert_eq!(field.value, ValueType::Boolean);
31 }
32 key.set_valid(index, true);
33
34 let byte_value = match field.direction {
35 SortDirection::Asc => {
36 if value.into() {
37 1u8
38 } else {
39 0u8
40 }
41 }
42 SortDirection::Desc => {
43 if value.into() {
44 0u8
45 } else {
46 1u8
47 }
48 }
49 };
50
51 unsafe { ptr::write_unaligned(key.make_mut().as_mut_ptr().add(field.offset), byte_value) }
52 }
53
54 pub fn set_f32(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<f32>) {
55 let field = &self.fields[index];
56 reifydb_assertions! {
57 assert_eq!(field.value, ValueType::Float4);
58 }
59 key.set_valid(index, true);
60
61 let v = value.into();
62 let mut bytes = v.to_bits().to_be_bytes();
63
64 if v.is_sign_negative() {
65 for b in bytes.iter_mut() {
66 *b = !*b;
67 }
68 } else {
69 bytes[0] ^= 0x80;
70 }
71
72 if field.direction == SortDirection::Desc {
73 for b in bytes.iter_mut() {
74 *b = !*b;
75 }
76 }
77
78 unsafe {
79 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 4);
80 }
81 }
82
83 pub fn set_f64(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<f64>) {
84 let field = &self.fields[index];
85 reifydb_assertions! {
86 assert_eq!(field.value, ValueType::Float8);
87 }
88 key.set_valid(index, true);
89
90 let v = value.into();
91 let mut bytes = v.to_bits().to_be_bytes();
92
93 if v.is_sign_negative() {
94 for b in bytes.iter_mut() {
95 *b = !*b;
96 }
97 } else {
98 bytes[0] ^= 0x80;
99 }
100
101 if field.direction == SortDirection::Desc {
102 for b in bytes.iter_mut() {
103 *b = !*b;
104 }
105 }
106
107 unsafe {
108 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 8);
109 }
110 }
111
112 pub fn set_i8(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<i8>) {
113 let field = &self.fields[index];
114 reifydb_assertions! {
115 assert_eq!(field.value, ValueType::Int1);
116 }
117 key.set_valid(index, true);
118
119 let mut bytes = value.into().to_be_bytes();
120
121 match field.direction {
122 SortDirection::Asc => {
123 bytes[0] ^= 0x80;
124 }
125 SortDirection::Desc => {
126 bytes[0] ^= 0x80;
127 for b in bytes.iter_mut() {
128 *b = !*b;
129 }
130 }
131 }
132
133 unsafe { ptr::write_unaligned(key.make_mut().as_mut_ptr().add(field.offset), bytes[0]) }
134 }
135
136 pub fn set_i16(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<i16>) {
137 let field = &self.fields[index];
138 reifydb_assertions! {
139 assert_eq!(field.value, ValueType::Int2);
140 }
141 key.set_valid(index, true);
142
143 let mut bytes = value.into().to_be_bytes();
144
145 match field.direction {
146 SortDirection::Asc => {
147 bytes[0] ^= 0x80;
148 }
149 SortDirection::Desc => {
150 bytes[0] ^= 0x80;
151 for b in bytes.iter_mut() {
152 *b = !*b;
153 }
154 }
155 }
156
157 unsafe {
158 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 2);
159 }
160 }
161
162 pub fn set_i32(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<i32>) {
163 let field = &self.fields[index];
164 reifydb_assertions! {
165 assert_eq!(field.value, ValueType::Int4);
166 }
167 key.set_valid(index, true);
168
169 let mut bytes = value.into().to_be_bytes();
170
171 match field.direction {
172 SortDirection::Asc => {
173 bytes[0] ^= 0x80;
174 }
175 SortDirection::Desc => {
176 bytes[0] ^= 0x80;
177 for b in bytes.iter_mut() {
178 *b = !*b;
179 }
180 }
181 }
182
183 unsafe {
184 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 4);
185 }
186 }
187
188 pub fn set_i64(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<i64>) {
189 let field = &self.fields[index];
190 reifydb_assertions! {
191 assert_eq!(field.value, ValueType::Int8);
192 }
193 key.set_valid(index, true);
194
195 let mut bytes = value.into().to_be_bytes();
196
197 match field.direction {
198 SortDirection::Asc => {
199 bytes[0] ^= 0x80;
200 }
201 SortDirection::Desc => {
202 bytes[0] ^= 0x80;
203 for b in bytes.iter_mut() {
204 *b = !*b;
205 }
206 }
207 }
208
209 unsafe {
210 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 8);
211 }
212 }
213
214 pub fn set_i128(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<i128>) {
215 let field = &self.fields[index];
216 reifydb_assertions! {
217 assert_eq!(field.value, ValueType::Int16);
218 }
219 key.set_valid(index, true);
220
221 let mut bytes = value.into().to_be_bytes();
222
223 match field.direction {
224 SortDirection::Asc => {
225 bytes[0] ^= 0x80;
226 }
227 SortDirection::Desc => {
228 bytes[0] ^= 0x80;
229 for b in bytes.iter_mut() {
230 *b = !*b;
231 }
232 }
233 }
234
235 unsafe {
236 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 16);
237 }
238 }
239
240 pub fn set_u8(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<u8>) {
241 let field = &self.fields[index];
242 reifydb_assertions! {
243 assert_eq!(field.value, ValueType::Uint1);
244 }
245 key.set_valid(index, true);
246
247 let byte = match field.direction {
248 SortDirection::Asc => value.into(),
249 SortDirection::Desc => !value.into(),
250 };
251
252 unsafe { ptr::write_unaligned(key.make_mut().as_mut_ptr().add(field.offset), byte) }
253 }
254
255 pub fn set_u16(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<u16>) {
256 let field = &self.fields[index];
257 reifydb_assertions! {
258 assert_eq!(field.value, ValueType::Uint2);
259 }
260 key.set_valid(index, true);
261
262 let bytes = match field.direction {
263 SortDirection::Asc => value.into().to_be_bytes(),
264 SortDirection::Desc => (!value.into()).to_be_bytes(),
265 };
266
267 unsafe {
268 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 2);
269 }
270 }
271
272 pub fn set_u32(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<u32>) {
273 let field = &self.fields[index];
274 reifydb_assertions! {
275 assert_eq!(field.value, ValueType::Uint4);
276 }
277 key.set_valid(index, true);
278
279 let bytes = match field.direction {
280 SortDirection::Asc => value.into().to_be_bytes(),
281 SortDirection::Desc => (!value.into()).to_be_bytes(),
282 };
283
284 unsafe {
285 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 4);
286 }
287 }
288
289 pub fn set_u64(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<u64>) {
290 let field = &self.fields[index];
291 reifydb_assertions! {
292 assert_eq!(field.value, ValueType::Uint8);
293 }
294 key.set_valid(index, true);
295
296 let bytes = match field.direction {
297 SortDirection::Asc => value.into().to_be_bytes(),
298 SortDirection::Desc => (!value.into()).to_be_bytes(),
299 };
300
301 unsafe {
302 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 8);
303 }
304 }
305
306 pub fn set_u128(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<u128>) {
307 let field = &self.fields[index];
308 reifydb_assertions! {
309 assert_eq!(field.value, ValueType::Uint16);
310 }
311 key.set_valid(index, true);
312
313 let bytes = match field.direction {
314 SortDirection::Asc => value.into().to_be_bytes(),
315 SortDirection::Desc => (!value.into()).to_be_bytes(),
316 };
317
318 unsafe {
319 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 16);
320 }
321 }
322
323 pub fn set_row_number(&self, key: &mut EncodedIndexKey, index: usize, value: impl Into<u64>) {
324 let field = &self.fields[index];
325 reifydb_assertions! {
326 assert_eq!(field.value, ValueType::Uint8);
327 }
328 key.set_valid(index, true);
329
330 let bytes = match field.direction {
331 SortDirection::Asc => value.into().to_be_bytes(),
332 SortDirection::Desc => (!value.into()).to_be_bytes(),
333 };
334
335 unsafe {
336 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 8);
337 }
338 }
339
340 pub fn set_date(&self, key: &mut EncodedIndexKey, index: usize, value: Date) {
341 let field = &self.fields[index];
342 reifydb_assertions! {
343 assert_eq!(field.value, ValueType::Date);
344 }
345 key.set_valid(index, true);
346
347 let days = value.to_days_since_epoch();
348 let mut bytes = days.to_be_bytes();
349
350 match field.direction {
351 SortDirection::Asc => {
352 bytes[0] ^= 0x80;
353 }
354 SortDirection::Desc => {
355 bytes[0] ^= 0x80;
356 for b in bytes.iter_mut() {
357 *b = !*b;
358 }
359 }
360 }
361
362 unsafe {
363 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 4);
364 }
365 }
366
367 pub fn set_datetime(&self, key: &mut EncodedIndexKey, index: usize, value: DateTime) {
368 let field = &self.fields[index];
369 reifydb_assertions! {
370 assert_eq!(field.value, ValueType::DateTime);
371 }
372 key.set_valid(index, true);
373
374 let nanos = value.to_nanos();
375 let bytes = match field.direction {
376 SortDirection::Asc => nanos.to_be_bytes(),
377 SortDirection::Desc => (!nanos).to_be_bytes(),
378 };
379
380 unsafe {
381 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 8);
382 }
383 }
384
385 pub fn set_time(&self, key: &mut EncodedIndexKey, index: usize, value: Time) {
386 let field = &self.fields[index];
387 reifydb_assertions! {
388 assert_eq!(field.value, ValueType::Time);
389 }
390 key.set_valid(index, true);
391
392 let nanos = value.to_nanos_since_midnight();
393 let bytes = match field.direction {
394 SortDirection::Asc => nanos.to_be_bytes(),
395 SortDirection::Desc => (!nanos).to_be_bytes(),
396 };
397
398 unsafe {
399 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 8);
400 }
401 }
402
403 pub fn set_duration(&self, key: &mut EncodedIndexKey, index: usize, value: Duration) {
404 let field = &self.fields[index];
405 reifydb_assertions! {
406 assert_eq!(field.value, ValueType::Duration);
407 }
408 key.set_valid(index, true);
409
410 let mut months_bytes = value.get_months().to_be_bytes();
411 let mut days_bytes = value.get_days().to_be_bytes();
412 let mut nanos_bytes = value.get_nanos().to_be_bytes();
413
414 match field.direction {
415 SortDirection::Asc => {
416 months_bytes[0] ^= 0x80;
417 days_bytes[0] ^= 0x80;
418 nanos_bytes[0] ^= 0x80;
419 }
420 SortDirection::Desc => {
421 months_bytes[0] ^= 0x80;
422 days_bytes[0] ^= 0x80;
423 nanos_bytes[0] ^= 0x80;
424 for b in months_bytes.iter_mut() {
425 *b = !*b;
426 }
427 for b in days_bytes.iter_mut() {
428 *b = !*b;
429 }
430 for b in nanos_bytes.iter_mut() {
431 *b = !*b;
432 }
433 }
434 }
435
436 unsafe {
437 ptr::copy_nonoverlapping(
438 months_bytes.as_ptr(),
439 key.make_mut().as_mut_ptr().add(field.offset),
440 4,
441 );
442 ptr::copy_nonoverlapping(
443 days_bytes.as_ptr(),
444 key.make_mut().as_mut_ptr().add(field.offset + 4),
445 4,
446 );
447 ptr::copy_nonoverlapping(
448 nanos_bytes.as_ptr(),
449 key.make_mut().as_mut_ptr().add(field.offset + 8),
450 8,
451 );
452 }
453 }
454
455 pub fn set_uuid4(&self, key: &mut EncodedIndexKey, index: usize, value: Uuid4) {
456 let field = &self.fields[index];
457 reifydb_assertions! {
458 assert_eq!(field.value, ValueType::Uuid4);
459 }
460 key.set_valid(index, true);
461
462 let uuid: Uuid = value.into();
463 let uuid_bytes = uuid.as_bytes();
464 let mut bytes = [0u8; 16];
465 bytes.copy_from_slice(uuid_bytes);
466
467 if field.direction == SortDirection::Desc {
468 for b in bytes.iter_mut() {
469 *b = !*b;
470 }
471 }
472
473 unsafe {
474 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 16);
475 }
476 }
477
478 pub fn set_uuid7(&self, key: &mut EncodedIndexKey, index: usize, value: Uuid7) {
479 let field = &self.fields[index];
480 reifydb_assertions! {
481 assert_eq!(field.value, ValueType::Uuid7);
482 }
483 key.set_valid(index, true);
484
485 let uuid: Uuid = value.into();
486 let uuid_bytes = uuid.as_bytes();
487 let mut bytes = [0u8; 16];
488 bytes.copy_from_slice(uuid_bytes);
489
490 if field.direction == SortDirection::Desc {
491 for b in bytes.iter_mut() {
492 *b = !*b;
493 }
494 }
495
496 unsafe {
497 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 16);
498 }
499 }
500
501 pub fn set_identity_id(&self, key: &mut EncodedIndexKey, index: usize, value: IdentityId) {
502 let field = &self.fields[index];
503 reifydb_assertions! {
504 assert_eq!(field.value, ValueType::IdentityId);
505 }
506 key.set_valid(index, true);
507
508 let uuid: Uuid = value.0.into();
509 let uuid_bytes = uuid.as_bytes();
510 let mut bytes = [0u8; 16];
511 bytes.copy_from_slice(uuid_bytes);
512
513 if field.direction == SortDirection::Desc {
514 for b in bytes.iter_mut() {
515 *b = !*b;
516 }
517 }
518
519 unsafe {
520 ptr::copy_nonoverlapping(bytes.as_ptr(), key.make_mut().as_mut_ptr().add(field.offset), 16);
521 }
522 }
523
524 pub fn set_none(&self, key: &mut EncodedIndexKey, index: usize) {
525 let field = &self.fields[index];
526 key.set_valid(index, false);
527
528 let buf = key.make_mut();
529 let start = field.offset;
530 let end = start + field.size;
531 buf[start..end].fill(0);
532 }
533}
534
535#[cfg(test)]
536pub mod tests {
537 use crate::{sort::SortDirection, value::index::shape::IndexShape};
538
539 mod bool {
540 use reifydb_value::value::value_type::ValueType;
541
542 use super::*;
543
544 #[test]
545 fn test_asc() {
546 let layout = IndexShape::new(&[ValueType::Boolean], &[SortDirection::Asc]).unwrap();
547 let mut key_false = layout.allocate_key();
548 let mut key_true = layout.allocate_key();
549
550 layout.set_bool(&mut key_false, 0, false);
551 layout.set_bool(&mut key_true, 0, true);
552
553 assert_eq!(key_false[0] & 0x01, 0x01);
555 assert_eq!(key_true[0] & 0x01, 0x01);
556
557 let offset = layout.fields[0].offset;
559 assert_eq!(key_false[offset], 0);
560 assert_eq!(key_true[offset], 1);
561
562 assert!(key_false.as_slice() < key_true.as_slice());
564 }
565
566 #[test]
567 fn test_desc() {
568 let layout = IndexShape::new(&[ValueType::Boolean], &[SortDirection::Desc]).unwrap();
569 let mut key_false = layout.allocate_key();
570 let mut key_true = layout.allocate_key();
571
572 layout.set_bool(&mut key_false, 0, false);
573 layout.set_bool(&mut key_true, 0, true);
574
575 let offset = layout.fields[0].offset;
577 assert_eq!(key_false[offset], 1); assert_eq!(key_true[offset], 0); assert!(key_false.as_slice() > key_true.as_slice());
582 }
583 }
584
585 mod i8 {
586 use reifydb_value::value::value_type::ValueType;
587
588 use crate::{sort::SortDirection, value::index::shape::IndexShape};
589
590 #[test]
591 fn test_asc() {
592 let layout = IndexShape::new(&[ValueType::Int1], &[SortDirection::Asc]).unwrap();
593 let mut key_neg = layout.allocate_key();
594 let mut key_zero = layout.allocate_key();
595 let mut key_pos = layout.allocate_key();
596
597 layout.set_i8(&mut key_neg, 0, -128i8);
598 layout.set_i8(&mut key_zero, 0, 0i8);
599 layout.set_i8(&mut key_pos, 0, 127i8);
600
601 let offset = layout.fields[0].offset;
602 assert_eq!(key_neg[offset], 0x00);
604 assert_eq!(key_zero[offset], 0x80);
606 assert_eq!(key_pos[offset], 0xFF);
608
609 assert!(key_neg.as_slice() < key_zero.as_slice());
611 assert!(key_zero.as_slice() < key_pos.as_slice());
612 }
613
614 #[test]
615 fn test_desc() {
616 let layout = IndexShape::new(&[ValueType::Int1], &[SortDirection::Desc]).unwrap();
617 let mut key_neg = layout.allocate_key();
618 let mut key_zero = layout.allocate_key();
619 let mut key_pos = layout.allocate_key();
620
621 layout.set_i8(&mut key_neg, 0, -128i8);
622 layout.set_i8(&mut key_zero, 0, 0i8);
623 layout.set_i8(&mut key_pos, 0, 127i8);
624
625 let offset = layout.fields[0].offset;
626 assert_eq!(key_neg[offset], 0xFF);
628 assert_eq!(key_zero[offset], 0x7F);
630 assert_eq!(key_pos[offset], 0x00);
632
633 assert!(key_neg.as_slice() > key_zero.as_slice());
635 assert!(key_zero.as_slice() > key_pos.as_slice());
636 }
637 }
638
639 mod i32 {
640 use reifydb_value::value::value_type::ValueType;
641
642 use crate::{sort::SortDirection, value::index::shape::IndexShape};
643
644 #[test]
645 fn test_asc() {
646 let layout = IndexShape::new(&[ValueType::Int4], &[SortDirection::Asc]).unwrap();
647 let mut key_neg = layout.allocate_key();
648 let mut key_zero = layout.allocate_key();
649 let mut key_pos = layout.allocate_key();
650
651 layout.set_i32(&mut key_neg, 0, i32::MIN);
652 layout.set_i32(&mut key_zero, 0, 0i32);
653 layout.set_i32(&mut key_pos, 0, i32::MAX);
654
655 let offset = layout.fields[0].offset;
656 assert_eq!(&key_neg[offset..offset + 4], &[0x00, 0x00, 0x00, 0x00]);
658 assert_eq!(&key_zero[offset..offset + 4], &[0x80, 0x00, 0x00, 0x00]);
660 assert_eq!(&key_pos[offset..offset + 4], &[0xFF, 0xFF, 0xFF, 0xFF]);
662
663 assert!(key_neg.as_slice() < key_zero.as_slice());
665 assert!(key_zero.as_slice() < key_pos.as_slice());
666 }
667
668 #[test]
669 fn test_desc() {
670 let layout = IndexShape::new(&[ValueType::Int4], &[SortDirection::Desc]).unwrap();
671 let mut key_neg = layout.allocate_key();
672 let mut key_zero = layout.allocate_key();
673 let mut key_pos = layout.allocate_key();
674
675 layout.set_i32(&mut key_neg, 0, i32::MIN);
676 layout.set_i32(&mut key_zero, 0, 0i32);
677 layout.set_i32(&mut key_pos, 0, i32::MAX);
678
679 let offset = layout.fields[0].offset;
680 assert_eq!(&key_neg[offset..offset + 4], &[0xFF, 0xFF, 0xFF, 0xFF]);
682 assert_eq!(&key_zero[offset..offset + 4], &[0x7F, 0xFF, 0xFF, 0xFF]);
684 assert_eq!(&key_pos[offset..offset + 4], &[0x00, 0x00, 0x00, 0x00]);
686
687 assert!(key_neg.as_slice() > key_zero.as_slice());
689 assert!(key_zero.as_slice() > key_pos.as_slice());
690 }
691 }
692
693 mod i64 {
694 use reifydb_value::value::value_type::ValueType;
695
696 use crate::{sort::SortDirection, value::index::shape::IndexShape};
697
698 #[test]
699 fn test_asc() {
700 let layout = IndexShape::new(&[ValueType::Int8], &[SortDirection::Asc]).unwrap();
701 let mut key = layout.allocate_key();
702
703 layout.set_i64(&mut key, 0, -1i64);
704
705 let offset = layout.fields[0].offset;
706 assert_eq!(&key[offset..offset + 8], &[0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
709 }
710
711 #[test]
712 fn test_desc() {
713 let layout = IndexShape::new(&[ValueType::Int8], &[SortDirection::Desc]).unwrap();
714 let mut key = layout.allocate_key();
715
716 layout.set_i64(&mut key, 0, -1i64);
717
718 let offset = layout.fields[0].offset;
719 assert_eq!(&key[offset..offset + 8], &[0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
721 }
722 }
723
724 mod u8 {
725 use reifydb_value::value::value_type::ValueType;
726
727 use crate::{sort::SortDirection, value::index::shape::IndexShape};
728
729 #[test]
730 fn test_asc() {
731 let layout = IndexShape::new(&[ValueType::Uint1], &[SortDirection::Asc]).unwrap();
732 let mut key_min = layout.allocate_key();
733 let mut key_mid = layout.allocate_key();
734 let mut key_max = layout.allocate_key();
735
736 layout.set_u8(&mut key_min, 0, 0u8);
737 layout.set_u8(&mut key_mid, 0, 128u8);
738 layout.set_u8(&mut key_max, 0, 255u8);
739
740 let offset = layout.fields[0].offset;
741 assert_eq!(key_min[offset], 0x00);
742 assert_eq!(key_mid[offset], 0x80);
743 assert_eq!(key_max[offset], 0xFF);
744
745 assert!(key_min.as_slice() < key_mid.as_slice());
747 assert!(key_mid.as_slice() < key_max.as_slice());
748 }
749
750 #[test]
751 fn test_desc() {
752 let layout = IndexShape::new(&[ValueType::Uint1], &[SortDirection::Desc]).unwrap();
753 let mut key_min = layout.allocate_key();
754 let mut key_mid = layout.allocate_key();
755 let mut key_max = layout.allocate_key();
756
757 layout.set_u8(&mut key_min, 0, 0u8);
758 layout.set_u8(&mut key_mid, 0, 128u8);
759 layout.set_u8(&mut key_max, 0, 255u8);
760
761 let offset = layout.fields[0].offset;
762 assert_eq!(key_min[offset], 0xFF);
764 assert_eq!(key_mid[offset], 0x7F);
765 assert_eq!(key_max[offset], 0x00);
766
767 assert!(key_min.as_slice() > key_mid.as_slice());
769 assert!(key_mid.as_slice() > key_max.as_slice());
770 }
771 }
772
773 mod u32 {
774 use reifydb_value::value::value_type::ValueType;
775
776 use crate::{sort::SortDirection, value::index::shape::IndexShape};
777
778 #[test]
779 fn test_asc() {
780 let layout = IndexShape::new(&[ValueType::Uint4], &[SortDirection::Asc]).unwrap();
781 let mut key = layout.allocate_key();
782
783 layout.set_u32(&mut key, 0, 0x12345678u32);
784
785 let offset = layout.fields[0].offset;
786 assert_eq!(&key[offset..offset + 4], &[0x12, 0x34, 0x56, 0x78]);
788 }
789
790 #[test]
791 fn test_desc() {
792 let layout = IndexShape::new(&[ValueType::Uint4], &[SortDirection::Desc]).unwrap();
793 let mut key = layout.allocate_key();
794
795 layout.set_u32(&mut key, 0, 0x12345678u32);
796
797 let offset = layout.fields[0].offset;
798 assert_eq!(&key[offset..offset + 4], &[0xED, 0xCB, 0xA9, 0x87]);
800 }
801 }
802
803 mod u64 {
804 use reifydb_value::value::value_type::ValueType;
805
806 use crate::{sort::SortDirection, value::index::shape::IndexShape};
807
808 #[test]
809 fn test_asc() {
810 let layout = IndexShape::new(&[ValueType::Uint8], &[SortDirection::Asc]).unwrap();
811 let mut key = layout.allocate_key();
812
813 layout.set_u64(&mut key, 0, u64::MAX);
814
815 let offset = layout.fields[0].offset;
816 assert_eq!(&key[offset..offset + 8], &[0xFF; 8]);
817 }
818
819 #[test]
820 fn test_desc() {
821 let layout = IndexShape::new(&[ValueType::Uint8], &[SortDirection::Desc]).unwrap();
822 let mut key = layout.allocate_key();
823
824 layout.set_u64(&mut key, 0, u64::MAX);
825
826 let offset = layout.fields[0].offset;
827 assert_eq!(&key[offset..offset + 8], &[0x00; 8]);
828 }
829 }
830
831 mod f32 {
832 use reifydb_value::value::value_type::ValueType;
833
834 use crate::{sort::SortDirection, value::index::shape::IndexShape};
835
836 #[test]
837 fn test_asc() {
838 let layout = IndexShape::new(&[ValueType::Float4], &[SortDirection::Asc]).unwrap();
839 let mut key_neg = layout.allocate_key();
840 let mut key_zero = layout.allocate_key();
841 let mut key_pos = layout.allocate_key();
842
843 layout.set_f32(&mut key_neg, 0, -1.0f32);
844 layout.set_f32(&mut key_zero, 0, 0.0f32);
845 layout.set_f32(&mut key_pos, 0, 1.0f32);
846
847 let offset = layout.fields[0].offset;
848
849 assert_eq!(&key_neg[offset..offset + 4], &[0x40, 0x7F, 0xFF, 0xFF]);
851 assert_eq!(&key_zero[offset..offset + 4], &[0x80, 0x00, 0x00, 0x00]);
853 assert_eq!(&key_pos[offset..offset + 4], &[0xBF, 0x80, 0x00, 0x00]);
855
856 assert!(key_neg.as_slice() < key_zero.as_slice());
858 assert!(key_zero.as_slice() < key_pos.as_slice());
859 }
860
861 #[test]
862 fn test_desc() {
863 let layout = IndexShape::new(&[ValueType::Float4], &[SortDirection::Desc]).unwrap();
864 let mut key_neg = layout.allocate_key();
865 let mut key_pos = layout.allocate_key();
866
867 layout.set_f32(&mut key_neg, 0, -1.0f32);
868 layout.set_f32(&mut key_pos, 0, 1.0f32);
869
870 let offset = layout.fields[0].offset;
871
872 assert_eq!(&key_neg[offset..offset + 4], &[0xBF, 0x80, 0x00, 0x00]);
874 assert_eq!(&key_pos[offset..offset + 4], &[0x40, 0x7F, 0xFF, 0xFF]);
876
877 assert!(key_neg.as_slice() > key_pos.as_slice());
879 }
880 }
881
882 mod f64 {
883 use std::f64::consts::PI;
884
885 use reifydb_value::value::value_type::ValueType;
886
887 use crate::{sort::SortDirection, value::index::shape::IndexShape};
888
889 #[test]
890 fn test_asc() {
891 let layout = IndexShape::new(&[ValueType::Float8], &[SortDirection::Asc]).unwrap();
892 let mut key = layout.allocate_key();
893
894 layout.set_f64(&mut key, 0, PI);
895
896 let offset = layout.fields[0].offset;
897 assert_eq!(&key[offset..offset + 8], &[0xC0, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18]);
899 }
900
901 #[test]
902 fn test_desc() {
903 let layout = IndexShape::new(&[ValueType::Float8], &[SortDirection::Desc]).unwrap();
904 let mut key = layout.allocate_key();
905
906 layout.set_f64(&mut key, 0, PI);
907
908 let offset = layout.fields[0].offset;
909 assert_eq!(&key[offset..offset + 8], &[0x3F, 0xF6, 0xDE, 0x04, 0xAB, 0xBB, 0xD2, 0xE7]);
911 }
912 }
913
914 mod row_number {
915 use reifydb_value::value::value_type::ValueType;
916
917 use crate::{sort::SortDirection, value::index::shape::IndexShape};
918
919 #[test]
920 fn test_asc() {
921 let layout = IndexShape::new(&[ValueType::Uint8], &[SortDirection::Asc]).unwrap();
922 let mut key = layout.allocate_key();
923
924 layout.set_row_number(&mut key, 0, 0x123456789ABCDEFu64);
925
926 let offset = layout.fields[0].offset;
927 assert_eq!(&key[offset..offset + 8], &[0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]);
928 }
929
930 #[test]
931 fn test_desc() {
932 let layout = IndexShape::new(&[ValueType::Uint8], &[SortDirection::Desc]).unwrap();
933 let mut key = layout.allocate_key();
934
935 layout.set_row_number(&mut key, 0, 0x123456789ABCDEFu64);
936
937 let offset = layout.fields[0].offset;
938 assert_eq!(&key[offset..offset + 8], &[0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10]);
940 }
941 }
942
943 mod date {
944 use reifydb_value::value::{date::Date, value_type::ValueType};
945
946 use crate::{sort::SortDirection, value::index::shape::IndexShape};
947
948 #[test]
949 fn test_asc() {
950 let layout = IndexShape::new(&[ValueType::Date], &[SortDirection::Asc]).unwrap();
951 let mut key = layout.allocate_key();
952
953 let date = Date::new(2025, 1, 1).unwrap();
954 layout.set_date(&mut key, 0, date);
955
956 let offset = layout.fields[0].offset;
957 let bytes = &key[offset..offset + 4];
960
961 let mut expected = date.to_days_since_epoch().to_be_bytes();
963 expected[0] ^= 0x80;
964 assert_eq!(bytes, expected);
965 }
966
967 #[test]
968 fn test_desc() {
969 let layout = IndexShape::new(&[ValueType::Date], &[SortDirection::Desc]).unwrap();
970 let mut key = layout.allocate_key();
971
972 let date = Date::new(2025, 1, 1).unwrap();
973 layout.set_date(&mut key, 0, date);
974
975 let offset = layout.fields[0].offset;
976 let bytes = &key[offset..offset + 4];
977
978 let mut expected = date.to_days_since_epoch().to_be_bytes();
980 expected[0] ^= 0x80;
981 for b in expected.iter_mut() {
982 *b = !*b;
983 }
984 assert_eq!(bytes, expected);
985 }
986 }
987
988 mod composite {
989 use reifydb_value::value::value_type::ValueType;
990
991 use crate::{sort::SortDirection, value::index::shape::IndexShape};
992
993 #[test]
994 fn test_mixed_directions() {
995 let layout = IndexShape::new(
996 &[ValueType::Int4, ValueType::Uint8],
997 &[SortDirection::Desc, SortDirection::Asc],
998 )
999 .unwrap();
1000
1001 let mut key = layout.allocate_key();
1002 layout.set_i32(&mut key, 0, 100);
1003 layout.set_u64(&mut key, 1, 200u64);
1004
1005 let offset1 = layout.fields[0].offset;
1007 let mut expected_i32 = 100i32.to_be_bytes();
1008 expected_i32[0] ^= 0x80;
1009 for b in expected_i32.iter_mut() {
1010 *b = !*b;
1011 }
1012 assert_eq!(&key[offset1..offset1 + 4], expected_i32);
1013
1014 let offset2 = layout.fields[1].offset;
1016 let expected_u64 = 200u64.to_be_bytes();
1017 assert_eq!(&key[offset2..offset2 + 8], expected_u64);
1018 }
1019 }
1020
1021 mod uuid4 {
1022 use reifydb_value::value::{uuid::Uuid4, value_type::ValueType};
1023
1024 use crate::{sort::SortDirection, value::index::shape::IndexShape};
1025
1026 #[test]
1027 fn test_asc() {
1028 let layout = IndexShape::new(&[ValueType::Uuid4], &[SortDirection::Asc]).unwrap();
1029 let mut key1 = layout.allocate_key();
1030 let mut key2 = layout.allocate_key();
1031
1032 let uuid1 = Uuid4::generate();
1033 let uuid2 = Uuid4::generate();
1034
1035 layout.set_uuid4(&mut key1, 0, uuid1.clone());
1036 layout.set_uuid4(&mut key2, 0, uuid2.clone());
1037
1038 assert!(key1.is_defined(0));
1040 assert!(key2.is_defined(0));
1041
1042 let offset = layout.fields[0].offset;
1044 let uuid1_bytes: Vec<u8> = uuid1.as_bytes().to_vec();
1045 let uuid2_bytes: Vec<u8> = uuid2.as_bytes().to_vec();
1046
1047 assert_eq!(&key1[offset..offset + 16], &uuid1_bytes[..]);
1048 assert_eq!(&key2[offset..offset + 16], &uuid2_bytes[..]);
1049 }
1050
1051 #[test]
1052 fn test_desc() {
1053 let layout = IndexShape::new(&[ValueType::Uuid4], &[SortDirection::Desc]).unwrap();
1054 let mut key = layout.allocate_key();
1055
1056 let uuid = Uuid4::generate();
1057 layout.set_uuid4(&mut key, 0, uuid.clone());
1058
1059 let offset = layout.fields[0].offset;
1061 let mut expected_bytes = uuid.as_bytes().to_vec();
1062 for b in expected_bytes.iter_mut() {
1063 *b = !*b;
1064 }
1065
1066 assert_eq!(&key[offset..offset + 16], &expected_bytes[..]);
1067 }
1068 }
1069
1070 mod uuid7 {
1071 use reifydb_runtime::context::{
1072 clock::{Clock, MockClock},
1073 rng::Rng,
1074 };
1075 use reifydb_value::value::{uuid::Uuid7, value_type::ValueType};
1076
1077 use crate::{sort::SortDirection, value::index::shape::IndexShape};
1078
1079 fn test_clock_and_rng() -> (MockClock, Clock, Rng) {
1080 let mock = MockClock::from_millis(1000);
1081 let clock = Clock::Mock(mock.clone());
1082 let rng = Rng::seeded(42);
1083 (mock, clock, rng)
1084 }
1085
1086 #[test]
1087 fn test_asc() {
1088 let (mock, clock, rng) = test_clock_and_rng();
1089 let layout = IndexShape::new(&[ValueType::Uuid7], &[SortDirection::Asc]).unwrap();
1090 let mut key1 = layout.allocate_key();
1091 let mut key2 = layout.allocate_key();
1092
1093 let uuid1 = Uuid7::generate(&clock, &rng);
1094 mock.advance_millis(10);
1096 let uuid2 = Uuid7::generate(&clock, &rng);
1097
1098 layout.set_uuid7(&mut key1, 0, uuid1.clone());
1099 layout.set_uuid7(&mut key2, 0, uuid2.clone());
1100
1101 assert!(key1.is_defined(0));
1103 assert!(key2.is_defined(0));
1104
1105 let offset = layout.fields[0].offset;
1107 let uuid1_bytes: Vec<u8> = uuid1.as_bytes().to_vec();
1108 let uuid2_bytes: Vec<u8> = uuid2.as_bytes().to_vec();
1109
1110 assert_eq!(&key1[offset..offset + 16], &uuid1_bytes[..]);
1111 assert_eq!(&key2[offset..offset + 16], &uuid2_bytes[..]);
1112
1113 assert!(key1.as_slice() < key2.as_slice());
1116 }
1117
1118 #[test]
1119 fn test_desc() {
1120 let (mock, clock, rng) = test_clock_and_rng();
1121 let layout = IndexShape::new(&[ValueType::Uuid7], &[SortDirection::Desc]).unwrap();
1122 let mut key1 = layout.allocate_key();
1123 let mut key2 = layout.allocate_key();
1124
1125 let uuid1 = Uuid7::generate(&clock, &rng);
1126 mock.advance_millis(10);
1128 let uuid2 = Uuid7::generate(&clock, &rng);
1129
1130 layout.set_uuid7(&mut key1, 0, uuid1.clone());
1131 layout.set_uuid7(&mut key2, 0, uuid2.clone());
1132
1133 let offset = layout.fields[0].offset;
1135 let mut expected_bytes1 = uuid1.as_bytes().to_vec();
1136 let mut expected_bytes2 = uuid2.as_bytes().to_vec();
1137 for b in expected_bytes1.iter_mut() {
1138 *b = !*b;
1139 }
1140 for b in expected_bytes2.iter_mut() {
1141 *b = !*b;
1142 }
1143
1144 assert_eq!(&key1[offset..offset + 16], &expected_bytes1[..]);
1145 assert_eq!(&key2[offset..offset + 16], &expected_bytes2[..]);
1146
1147 assert!(key1.as_slice() > key2.as_slice());
1149 }
1150 }
1151
1152 mod identity_id {
1153 use reifydb_runtime::context::{
1154 clock::{Clock, MockClock},
1155 rng::Rng,
1156 };
1157 use reifydb_value::value::{identity::IdentityId, uuid::Uuid7, value_type::ValueType};
1158
1159 use crate::{sort::SortDirection, value::index::shape::IndexShape};
1160
1161 fn test_clock_and_rng() -> (MockClock, Clock, Rng) {
1162 let mock = MockClock::from_millis(1000);
1163 let clock = Clock::Mock(mock.clone());
1164 let rng = Rng::seeded(42);
1165 (mock, clock, rng)
1166 }
1167
1168 #[test]
1169 fn test_asc() {
1170 let (mock, clock, rng) = test_clock_and_rng();
1171 let layout = IndexShape::new(&[ValueType::IdentityId], &[SortDirection::Asc]).unwrap();
1172 let mut key1 = layout.allocate_key();
1173 let mut key2 = layout.allocate_key();
1174
1175 let id1 = IdentityId::generate(&clock, &rng);
1176 mock.advance_millis(10);
1179 let id2 = IdentityId::generate(&clock, &rng);
1180
1181 layout.set_identity_id(&mut key1, 0, id1.clone());
1182 layout.set_identity_id(&mut key2, 0, id2.clone());
1183
1184 assert!(key1.is_defined(0));
1186 assert!(key2.is_defined(0));
1187
1188 let offset = layout.fields[0].offset;
1190 let uuid7_1: Uuid7 = id1.into();
1191 let uuid7_2: Uuid7 = id2.into();
1192 let id1_bytes: Vec<u8> = uuid7_1.as_bytes().to_vec();
1193 let id2_bytes: Vec<u8> = uuid7_2.as_bytes().to_vec();
1194
1195 assert_eq!(&key1[offset..offset + 16], &id1_bytes[..]);
1196 assert_eq!(&key2[offset..offset + 16], &id2_bytes[..]);
1197
1198 assert!(key1.as_slice() < key2.as_slice());
1201 }
1202
1203 #[test]
1204 fn test_desc() {
1205 let (mock, clock, rng) = test_clock_and_rng();
1206 let layout = IndexShape::new(&[ValueType::IdentityId], &[SortDirection::Desc]).unwrap();
1207 let mut key1 = layout.allocate_key();
1208 let mut key2 = layout.allocate_key();
1209
1210 let id1 = IdentityId::generate(&clock, &rng);
1211 mock.advance_millis(10);
1213 let id2 = IdentityId::generate(&clock, &rng);
1214
1215 layout.set_identity_id(&mut key1, 0, id1.clone());
1216 layout.set_identity_id(&mut key2, 0, id2.clone());
1217
1218 let offset = layout.fields[0].offset;
1220 let uuid7_1: Uuid7 = id1.into();
1221 let uuid7_2: Uuid7 = id2.into();
1222 let mut expected_bytes1 = uuid7_1.as_bytes().to_vec();
1223 let mut expected_bytes2 = uuid7_2.as_bytes().to_vec();
1224 for b in expected_bytes1.iter_mut() {
1225 *b = !*b;
1226 }
1227 for b in expected_bytes2.iter_mut() {
1228 *b = !*b;
1229 }
1230
1231 assert_eq!(&key1[offset..offset + 16], &expected_bytes1[..]);
1232 assert_eq!(&key2[offset..offset + 16], &expected_bytes2[..]);
1233
1234 assert!(key1.as_slice() > key2.as_slice());
1236 }
1237 }
1238
1239 mod undefined {
1240 use reifydb_value::value::value_type::ValueType;
1241
1242 use crate::{sort::SortDirection, value::index::shape::IndexShape};
1243
1244 #[test]
1245 fn test_undefined() {
1246 let layout = IndexShape::new(&[ValueType::Int4], &[SortDirection::Asc]).unwrap();
1247 let mut key = layout.allocate_key();
1248
1249 layout.set_i32(&mut key, 0, 42);
1251 assert!(key.is_defined(0));
1252
1253 layout.set_none(&mut key, 0);
1255 assert!(!key.is_defined(0));
1256
1257 let offset = layout.fields[0].offset;
1259 assert_eq!(&key[offset..offset + 4], &[0, 0, 0, 0]);
1260 }
1261 }
1262}