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