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