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