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