Skip to main content

reifydb_core/value/index/
get.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use std::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, layout::EncodedIndexLayout},
20};
21
22impl EncodedIndexLayout {
23	pub fn get_bool(&self, key: &EncodedIndexKey, index: usize) -> bool {
24		let field = &self.fields[index];
25		debug_assert_eq!(field.value, Type::Boolean);
26
27		let byte = unsafe { *key.as_ptr().add(field.offset) };
28
29		match field.direction {
30			SortDirection::Asc => byte != 0,
31			SortDirection::Desc => byte == 0,
32		}
33	}
34
35	pub fn get_f32(&self, key: &EncodedIndexKey, index: usize) -> f32 {
36		let field = &self.fields[index];
37		debug_assert_eq!(field.value, Type::Float4);
38
39		let mut bytes = [0u8; 4];
40		unsafe {
41			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 4);
42		}
43
44		// For DESC, undo the inversion first
45		if field.direction == SortDirection::Desc {
46			for b in bytes.iter_mut() {
47				*b = !*b;
48			}
49		}
50
51		// Now undo the ASC encoding
52		if bytes[0] & 0x80 != 0 {
53			bytes[0] ^= 0x80;
54		} else {
55			for b in bytes.iter_mut() {
56				*b = !*b;
57			}
58		}
59
60		f32::from_bits(u32::from_be_bytes(bytes))
61	}
62
63	pub fn get_f64(&self, key: &EncodedIndexKey, index: usize) -> f64 {
64		let field = &self.fields[index];
65		debug_assert_eq!(field.value, Type::Float8);
66
67		let mut bytes = [0u8; 8];
68		unsafe {
69			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
70		}
71
72		// For DESC, undo the inversion first
73		if field.direction == SortDirection::Desc {
74			for b in bytes.iter_mut() {
75				*b = !*b;
76			}
77		}
78
79		// Now undo the ASC encoding
80		if bytes[0] & 0x80 != 0 {
81			bytes[0] ^= 0x80;
82		} else {
83			for b in bytes.iter_mut() {
84				*b = !*b;
85			}
86		}
87
88		f64::from_bits(u64::from_be_bytes(bytes))
89	}
90
91	pub fn get_i8(&self, key: &EncodedIndexKey, index: usize) -> i8 {
92		let field = &self.fields[index];
93		debug_assert_eq!(field.value, Type::Int1);
94
95		let mut byte = unsafe { *key.as_ptr().add(field.offset) };
96
97		match field.direction {
98			SortDirection::Asc => {
99				byte ^= 0x80;
100			}
101			SortDirection::Desc => {
102				byte = !byte;
103				byte ^= 0x80;
104			}
105		}
106
107		i8::from_be_bytes([byte])
108	}
109
110	pub fn get_i16(&self, key: &EncodedIndexKey, index: usize) -> i16 {
111		let field = &self.fields[index];
112		debug_assert_eq!(field.value, Type::Int2);
113
114		let mut bytes = [0u8; 2];
115		unsafe {
116			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 2);
117		}
118
119		match field.direction {
120			SortDirection::Asc => {
121				bytes[0] ^= 0x80;
122			}
123			SortDirection::Desc => {
124				for b in bytes.iter_mut() {
125					*b = !*b;
126				}
127				bytes[0] ^= 0x80;
128			}
129		}
130
131		i16::from_be_bytes(bytes)
132	}
133
134	pub fn get_i32(&self, key: &EncodedIndexKey, index: usize) -> i32 {
135		let field = &self.fields[index];
136		debug_assert_eq!(field.value, Type::Int4);
137
138		let mut bytes = [0u8; 4];
139		unsafe {
140			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 4);
141		}
142
143		match field.direction {
144			SortDirection::Asc => {
145				bytes[0] ^= 0x80;
146			}
147			SortDirection::Desc => {
148				for b in bytes.iter_mut() {
149					*b = !*b;
150				}
151				bytes[0] ^= 0x80;
152			}
153		}
154
155		i32::from_be_bytes(bytes)
156	}
157
158	pub fn get_i64(&self, key: &EncodedIndexKey, index: usize) -> i64 {
159		let field = &self.fields[index];
160		debug_assert_eq!(field.value, Type::Int8);
161
162		let mut bytes = [0u8; 8];
163		unsafe {
164			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
165		}
166
167		match field.direction {
168			SortDirection::Asc => {
169				bytes[0] ^= 0x80;
170			}
171			SortDirection::Desc => {
172				for b in bytes.iter_mut() {
173					*b = !*b;
174				}
175				bytes[0] ^= 0x80;
176			}
177		}
178
179		i64::from_be_bytes(bytes)
180	}
181
182	pub fn get_i128(&self, key: &EncodedIndexKey, index: usize) -> i128 {
183		let field = &self.fields[index];
184		debug_assert_eq!(field.value, Type::Int16);
185
186		let mut bytes = [0u8; 16];
187		unsafe {
188			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
189		}
190
191		match field.direction {
192			SortDirection::Asc => {
193				bytes[0] ^= 0x80;
194			}
195			SortDirection::Desc => {
196				for b in bytes.iter_mut() {
197					*b = !*b;
198				}
199				bytes[0] ^= 0x80;
200			}
201		}
202
203		i128::from_be_bytes(bytes)
204	}
205
206	pub fn get_u8(&self, key: &EncodedIndexKey, index: usize) -> u8 {
207		let field = &self.fields[index];
208		debug_assert_eq!(field.value, Type::Uint1);
209
210		let byte = unsafe { *key.as_ptr().add(field.offset) };
211
212		match field.direction {
213			SortDirection::Asc => byte,
214			SortDirection::Desc => !byte,
215		}
216	}
217
218	pub fn get_u16(&self, key: &EncodedIndexKey, index: usize) -> u16 {
219		let field = &self.fields[index];
220		debug_assert_eq!(field.value, Type::Uint2);
221
222		let mut bytes = [0u8; 2];
223		unsafe {
224			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 2);
225		}
226
227		match field.direction {
228			SortDirection::Asc => u16::from_be_bytes(bytes),
229			SortDirection::Desc => !u16::from_be_bytes(bytes),
230		}
231	}
232
233	pub fn get_u32(&self, key: &EncodedIndexKey, index: usize) -> u32 {
234		let field = &self.fields[index];
235		debug_assert_eq!(field.value, Type::Uint4);
236
237		let mut bytes = [0u8; 4];
238		unsafe {
239			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 4);
240		}
241
242		match field.direction {
243			SortDirection::Asc => u32::from_be_bytes(bytes),
244			SortDirection::Desc => !u32::from_be_bytes(bytes),
245		}
246	}
247
248	pub fn get_u64(&self, key: &EncodedIndexKey, index: usize) -> u64 {
249		let field = &self.fields[index];
250		debug_assert_eq!(field.value, Type::Uint8);
251
252		let mut bytes = [0u8; 8];
253		unsafe {
254			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
255		}
256
257		match field.direction {
258			SortDirection::Asc => u64::from_be_bytes(bytes),
259			SortDirection::Desc => !u64::from_be_bytes(bytes),
260		}
261	}
262
263	pub fn get_u128(&self, key: &EncodedIndexKey, index: usize) -> u128 {
264		let field = &self.fields[index];
265		debug_assert_eq!(field.value, Type::Uint16);
266
267		let mut bytes = [0u8; 16];
268		unsafe {
269			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
270		}
271
272		match field.direction {
273			SortDirection::Asc => u128::from_be_bytes(bytes),
274			SortDirection::Desc => !u128::from_be_bytes(bytes),
275		}
276	}
277
278	pub fn get_row_number(&self, key: &EncodedIndexKey, index: usize) -> u64 {
279		let field = &self.fields[index];
280		debug_assert_eq!(field.value, Type::Uint8);
281
282		let mut bytes = [0u8; 8];
283		unsafe {
284			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
285		}
286
287		match field.direction {
288			SortDirection::Asc => u64::from_be_bytes(bytes),
289			SortDirection::Desc => !u64::from_be_bytes(bytes),
290		}
291	}
292
293	pub fn get_date(&self, key: &EncodedIndexKey, index: usize) -> Date {
294		let field = &self.fields[index];
295		debug_assert_eq!(field.value, Type::Date);
296
297		let mut bytes = [0u8; 4];
298		unsafe {
299			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 4);
300		}
301
302		match field.direction {
303			SortDirection::Asc => {
304				bytes[0] ^= 0x80;
305			}
306			SortDirection::Desc => {
307				for b in bytes.iter_mut() {
308					*b = !*b;
309				}
310				bytes[0] ^= 0x80;
311			}
312		}
313
314		let days = i32::from_be_bytes(bytes);
315		Date::from_days_since_epoch(days).unwrap()
316	}
317
318	pub fn get_datetime(&self, key: &EncodedIndexKey, index: usize) -> DateTime {
319		let field = &self.fields[index];
320		debug_assert_eq!(field.value, Type::DateTime);
321
322		let mut sec_bytes = [0u8; 8];
323		let mut nano_bytes = [0u8; 4];
324
325		unsafe {
326			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), sec_bytes.as_mut_ptr(), 8);
327			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset + 8), nano_bytes.as_mut_ptr(), 4);
328		}
329
330		match field.direction {
331			SortDirection::Asc => {
332				sec_bytes[0] ^= 0x80;
333			}
334			SortDirection::Desc => {
335				for b in sec_bytes.iter_mut() {
336					*b = !*b;
337				}
338				sec_bytes[0] ^= 0x80;
339				for b in nano_bytes.iter_mut() {
340					*b = !*b;
341				}
342			}
343		}
344
345		let seconds = i64::from_be_bytes(sec_bytes);
346		let nanos = u32::from_be_bytes(nano_bytes);
347		DateTime::from_parts(seconds, nanos).unwrap()
348	}
349
350	pub fn get_time(&self, key: &EncodedIndexKey, index: usize) -> Time {
351		let field = &self.fields[index];
352		debug_assert_eq!(field.value, Type::Time);
353
354		let mut bytes = [0u8; 8];
355		unsafe {
356			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 8);
357		}
358
359		let nanos = match field.direction {
360			SortDirection::Asc => u64::from_be_bytes(bytes),
361			SortDirection::Desc => !u64::from_be_bytes(bytes),
362		};
363
364		Time::from_nanos_since_midnight(nanos).unwrap()
365	}
366
367	pub fn get_duration(&self, key: &EncodedIndexKey, index: usize) -> Duration {
368		let field = &self.fields[index];
369		debug_assert_eq!(field.value, Type::Duration);
370
371		let mut months_bytes = [0u8; 4];
372		let mut days_bytes = [0u8; 4];
373		let mut nanos_bytes = [0u8; 8];
374
375		unsafe {
376			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), months_bytes.as_mut_ptr(), 4);
377			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset + 4), days_bytes.as_mut_ptr(), 4);
378			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset + 8), nanos_bytes.as_mut_ptr(), 8);
379		}
380
381		match field.direction {
382			SortDirection::Asc => {
383				months_bytes[0] ^= 0x80;
384				days_bytes[0] ^= 0x80;
385				nanos_bytes[0] ^= 0x80;
386			}
387			SortDirection::Desc => {
388				for b in months_bytes.iter_mut() {
389					*b = !*b;
390				}
391				months_bytes[0] ^= 0x80;
392				for b in days_bytes.iter_mut() {
393					*b = !*b;
394				}
395				days_bytes[0] ^= 0x80;
396				for b in nanos_bytes.iter_mut() {
397					*b = !*b;
398				}
399				nanos_bytes[0] ^= 0x80;
400			}
401		}
402
403		let months = i32::from_be_bytes(months_bytes);
404		let days = i32::from_be_bytes(days_bytes);
405		let nanos = i64::from_be_bytes(nanos_bytes);
406		Duration::new(months, days, nanos)
407	}
408
409	pub fn get_uuid4(&self, key: &EncodedIndexKey, index: usize) -> Uuid4 {
410		let field = &self.fields[index];
411		debug_assert_eq!(field.value, Type::Uuid4);
412
413		let mut bytes = [0u8; 16];
414		unsafe {
415			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
416		}
417
418		if field.direction == SortDirection::Desc {
419			for b in bytes.iter_mut() {
420				*b = !*b;
421			}
422		}
423
424		let uuid = Uuid::from_bytes(bytes);
425		Uuid4::from(uuid)
426	}
427
428	pub fn get_uuid7(&self, key: &EncodedIndexKey, index: usize) -> Uuid7 {
429		let field = &self.fields[index];
430		debug_assert_eq!(field.value, Type::Uuid7);
431
432		let mut bytes = [0u8; 16];
433		unsafe {
434			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
435		}
436
437		if field.direction == SortDirection::Desc {
438			for b in bytes.iter_mut() {
439				*b = !*b;
440			}
441		}
442
443		let uuid = Uuid::from_bytes(bytes);
444		Uuid7::from(uuid)
445	}
446
447	pub fn get_identity_id(&self, key: &EncodedIndexKey, index: usize) -> IdentityId {
448		let field = &self.fields[index];
449		debug_assert_eq!(field.value, Type::IdentityId);
450
451		let mut bytes = [0u8; 16];
452		unsafe {
453			ptr::copy_nonoverlapping(key.as_ptr().add(field.offset), bytes.as_mut_ptr(), 16);
454		}
455
456		if field.direction == SortDirection::Desc {
457			for b in bytes.iter_mut() {
458				*b = !*b;
459			}
460		}
461
462		let uuid = Uuid::from_bytes(bytes);
463		let uuid7 = Uuid7::from(uuid);
464		IdentityId::from(uuid7)
465	}
466}
467
468#[cfg(test)]
469pub mod tests {
470	use reifydb_type::value::r#type::Type;
471
472	use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
473
474	mod bool {
475		use super::*;
476
477		#[test]
478		fn test_asc() {
479			let layout = EncodedIndexLayout::new(&[Type::Boolean], &[SortDirection::Asc]).unwrap();
480			let mut key1 = layout.allocate_key();
481			let mut key2 = layout.allocate_key();
482
483			layout.set_bool(&mut key1, 0, false);
484			layout.set_bool(&mut key2, 0, true);
485
486			assert!(key1.as_slice() < key2.as_slice());
487			assert_eq!(layout.get_bool(&key1, 0), false);
488			assert_eq!(layout.get_bool(&key2, 0), true);
489		}
490
491		#[test]
492		fn test_desc() {
493			let layout = EncodedIndexLayout::new(&[Type::Boolean], &[SortDirection::Desc]).unwrap();
494			let mut key1 = layout.allocate_key();
495			let mut key2 = layout.allocate_key();
496
497			layout.set_bool(&mut key1, 0, false);
498			layout.set_bool(&mut key2, 0, true);
499
500			assert!(key1.as_slice() > key2.as_slice());
501			assert_eq!(layout.get_bool(&key1, 0), false);
502			assert_eq!(layout.get_bool(&key2, 0), true);
503		}
504	}
505
506	mod i8 {
507		use reifydb_type::value::r#type::Type;
508
509		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
510
511		#[test]
512		fn test_asc() {
513			let layout = EncodedIndexLayout::new(&[Type::Int1], &[SortDirection::Asc]).unwrap();
514			let mut key1 = layout.allocate_key();
515			let mut key2 = layout.allocate_key();
516			let mut key3 = layout.allocate_key();
517
518			layout.set_i8(&mut key1, 0, -10);
519			layout.set_i8(&mut key2, 0, 0);
520			layout.set_i8(&mut key3, 0, 10);
521
522			assert!(key1.as_slice() < key2.as_slice());
523			assert!(key2.as_slice() < key3.as_slice());
524			assert_eq!(layout.get_i8(&key1, 0), -10);
525			assert_eq!(layout.get_i8(&key2, 0), 0);
526			assert_eq!(layout.get_i8(&key3, 0), 10);
527		}
528
529		#[test]
530		fn test_desc() {
531			let layout = EncodedIndexLayout::new(&[Type::Int1], &[SortDirection::Desc]).unwrap();
532			let mut key1 = layout.allocate_key();
533			let mut key2 = layout.allocate_key();
534			let mut key3 = layout.allocate_key();
535
536			layout.set_i8(&mut key1, 0, -10);
537			layout.set_i8(&mut key2, 0, 0);
538			layout.set_i8(&mut key3, 0, 10);
539
540			assert!(key1.as_slice() > key2.as_slice());
541			assert!(key2.as_slice() > key3.as_slice());
542			assert_eq!(layout.get_i8(&key1, 0), -10);
543			assert_eq!(layout.get_i8(&key2, 0), 0);
544			assert_eq!(layout.get_i8(&key3, 0), 10);
545		}
546	}
547
548	mod i32 {
549		use reifydb_type::value::r#type::Type;
550
551		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
552
553		#[test]
554		fn test_asc() {
555			let layout = EncodedIndexLayout::new(&[Type::Int4], &[SortDirection::Asc]).unwrap();
556			let mut key1 = layout.allocate_key();
557			let mut key2 = layout.allocate_key();
558			let mut key3 = layout.allocate_key();
559
560			layout.set_i32(&mut key1, 0, -1000);
561			layout.set_i32(&mut key2, 0, 0);
562			layout.set_i32(&mut key3, 0, 1000);
563
564			assert!(key1.as_slice() < key2.as_slice());
565			assert!(key2.as_slice() < key3.as_slice());
566			assert_eq!(layout.get_i32(&key1, 0), -1000);
567			assert_eq!(layout.get_i32(&key2, 0), 0);
568			assert_eq!(layout.get_i32(&key3, 0), 1000);
569		}
570
571		#[test]
572		fn test_desc() {
573			let layout = EncodedIndexLayout::new(&[Type::Int4], &[SortDirection::Desc]).unwrap();
574			let mut key1 = layout.allocate_key();
575			let mut key2 = layout.allocate_key();
576			let mut key3 = layout.allocate_key();
577
578			layout.set_i32(&mut key1, 0, -1000);
579			layout.set_i32(&mut key2, 0, 0);
580			layout.set_i32(&mut key3, 0, 1000);
581
582			assert!(key1.as_slice() > key2.as_slice());
583			assert!(key2.as_slice() > key3.as_slice());
584			assert_eq!(layout.get_i32(&key1, 0), -1000);
585			assert_eq!(layout.get_i32(&key2, 0), 0);
586			assert_eq!(layout.get_i32(&key3, 0), 1000);
587		}
588	}
589
590	mod i64 {
591		use reifydb_type::value::r#type::Type;
592
593		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
594
595		#[test]
596		fn test_asc() {
597			let layout = EncodedIndexLayout::new(&[Type::Int8], &[SortDirection::Asc]).unwrap();
598			let mut key1 = layout.allocate_key();
599			let mut key2 = layout.allocate_key();
600			let mut key3 = layout.allocate_key();
601
602			layout.set_i64(&mut key1, 0, i64::MIN);
603			layout.set_i64(&mut key2, 0, 0);
604			layout.set_i64(&mut key3, 0, i64::MAX);
605
606			assert!(key1.as_slice() < key2.as_slice());
607			assert!(key2.as_slice() < key3.as_slice());
608			assert_eq!(layout.get_i64(&key1, 0), i64::MIN);
609			assert_eq!(layout.get_i64(&key2, 0), 0);
610			assert_eq!(layout.get_i64(&key3, 0), i64::MAX);
611		}
612
613		#[test]
614		fn test_desc() {
615			let layout = EncodedIndexLayout::new(&[Type::Int8], &[SortDirection::Desc]).unwrap();
616			let mut key1 = layout.allocate_key();
617			let mut key2 = layout.allocate_key();
618			let mut key3 = layout.allocate_key();
619
620			layout.set_i64(&mut key1, 0, i64::MIN);
621			layout.set_i64(&mut key2, 0, 0);
622			layout.set_i64(&mut key3, 0, i64::MAX);
623
624			assert!(key1.as_slice() > key2.as_slice());
625			assert!(key2.as_slice() > key3.as_slice());
626			assert_eq!(layout.get_i64(&key1, 0), i64::MIN);
627			assert_eq!(layout.get_i64(&key2, 0), 0);
628			assert_eq!(layout.get_i64(&key3, 0), i64::MAX);
629		}
630	}
631
632	mod u8 {
633		use reifydb_type::value::r#type::Type;
634
635		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
636
637		#[test]
638		fn test_asc() {
639			let layout = EncodedIndexLayout::new(&[Type::Uint1], &[SortDirection::Asc]).unwrap();
640			let mut key1 = layout.allocate_key();
641			let mut key2 = layout.allocate_key();
642			let mut key3 = layout.allocate_key();
643
644			layout.set_u8(&mut key1, 0, 0);
645			layout.set_u8(&mut key2, 0, 128);
646			layout.set_u8(&mut key3, 0, 255);
647
648			assert!(key1.as_slice() < key2.as_slice());
649			assert!(key2.as_slice() < key3.as_slice());
650			assert_eq!(layout.get_u8(&key1, 0), 0);
651			assert_eq!(layout.get_u8(&key2, 0), 128);
652			assert_eq!(layout.get_u8(&key3, 0), 255);
653		}
654
655		#[test]
656		fn test_desc() {
657			let layout = EncodedIndexLayout::new(&[Type::Uint1], &[SortDirection::Desc]).unwrap();
658			let mut key1 = layout.allocate_key();
659			let mut key2 = layout.allocate_key();
660			let mut key3 = layout.allocate_key();
661
662			layout.set_u8(&mut key1, 0, 0);
663			layout.set_u8(&mut key2, 0, 128);
664			layout.set_u8(&mut key3, 0, 255);
665
666			assert!(key1.as_slice() > key2.as_slice());
667			assert!(key2.as_slice() > key3.as_slice());
668			assert_eq!(layout.get_u8(&key1, 0), 0);
669			assert_eq!(layout.get_u8(&key2, 0), 128);
670			assert_eq!(layout.get_u8(&key3, 0), 255);
671		}
672	}
673
674	mod u32 {
675		use reifydb_type::value::r#type::Type;
676
677		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
678
679		#[test]
680		fn test_asc() {
681			let layout = EncodedIndexLayout::new(&[Type::Uint4], &[SortDirection::Asc]).unwrap();
682			let mut key1 = layout.allocate_key();
683			let mut key2 = layout.allocate_key();
684			let mut key3 = layout.allocate_key();
685
686			layout.set_u32(&mut key1, 0, 0u32);
687			layout.set_u32(&mut key2, 0, 1000000u32);
688			layout.set_u32(&mut key3, 0, u32::MAX);
689
690			assert!(key1.as_slice() < key2.as_slice());
691			assert!(key2.as_slice() < key3.as_slice());
692			assert_eq!(layout.get_u32(&key1, 0), 0);
693			assert_eq!(layout.get_u32(&key2, 0), 1000000);
694			assert_eq!(layout.get_u32(&key3, 0), u32::MAX);
695		}
696
697		#[test]
698		fn test_desc() {
699			let layout = EncodedIndexLayout::new(&[Type::Uint4], &[SortDirection::Desc]).unwrap();
700			let mut key1 = layout.allocate_key();
701			let mut key2 = layout.allocate_key();
702			let mut key3 = layout.allocate_key();
703
704			layout.set_u32(&mut key1, 0, 0u32);
705			layout.set_u32(&mut key2, 0, 1000000u32);
706			layout.set_u32(&mut key3, 0, u32::MAX);
707
708			assert!(key1.as_slice() > key2.as_slice());
709			assert!(key2.as_slice() > key3.as_slice());
710			assert_eq!(layout.get_u32(&key1, 0), 0);
711			assert_eq!(layout.get_u32(&key2, 0), 1000000);
712			assert_eq!(layout.get_u32(&key3, 0), u32::MAX);
713		}
714	}
715
716	mod u64 {
717		use reifydb_type::value::r#type::Type;
718
719		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
720
721		#[test]
722		fn test_asc() {
723			let layout = EncodedIndexLayout::new(&[Type::Uint8], &[SortDirection::Asc]).unwrap();
724			let mut key1 = layout.allocate_key();
725			let mut key2 = layout.allocate_key();
726			let mut key3 = layout.allocate_key();
727
728			layout.set_u64(&mut key1, 0, 0u64);
729			layout.set_u64(&mut key2, 0, 1_000_000_000u64);
730			layout.set_u64(&mut key3, 0, u64::MAX);
731
732			assert!(key1.as_slice() < key2.as_slice());
733			assert!(key2.as_slice() < key3.as_slice());
734			assert_eq!(layout.get_u64(&key1, 0), 0);
735			assert_eq!(layout.get_u64(&key2, 0), 1_000_000_000);
736			assert_eq!(layout.get_u64(&key3, 0), u64::MAX);
737		}
738
739		#[test]
740		fn test_desc() {
741			let layout = EncodedIndexLayout::new(&[Type::Uint8], &[SortDirection::Desc]).unwrap();
742			let mut key1 = layout.allocate_key();
743			let mut key2 = layout.allocate_key();
744			let mut key3 = layout.allocate_key();
745
746			layout.set_u64(&mut key1, 0, 0u64);
747			layout.set_u64(&mut key2, 0, 1_000_000_000u64);
748			layout.set_u64(&mut key3, 0, u64::MAX);
749
750			assert!(key1.as_slice() > key2.as_slice());
751			assert!(key2.as_slice() > key3.as_slice());
752			assert_eq!(layout.get_u64(&key1, 0), 0);
753			assert_eq!(layout.get_u64(&key2, 0), 1_000_000_000);
754			assert_eq!(layout.get_u64(&key3, 0), u64::MAX);
755		}
756	}
757
758	mod f32 {
759		use reifydb_type::value::r#type::Type;
760
761		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
762
763		#[test]
764		fn test_asc() {
765			let layout = EncodedIndexLayout::new(&[Type::Float4], &[SortDirection::Asc]).unwrap();
766			let mut key1 = layout.allocate_key();
767			let mut key2 = layout.allocate_key();
768			let mut key3 = layout.allocate_key();
769
770			layout.set_f32(&mut key1, 0, -100.5);
771			layout.set_f32(&mut key2, 0, 0.0);
772			layout.set_f32(&mut key3, 0, 100.5);
773
774			assert!(key1.as_slice() < key2.as_slice());
775			assert!(key2.as_slice() < key3.as_slice());
776			assert_eq!(layout.get_f32(&key1, 0), -100.5);
777			assert_eq!(layout.get_f32(&key2, 0), 0.0);
778			assert_eq!(layout.get_f32(&key3, 0), 100.5);
779		}
780
781		#[test]
782		fn test_desc() {
783			let layout = EncodedIndexLayout::new(&[Type::Float4], &[SortDirection::Desc]).unwrap();
784			let mut key1 = layout.allocate_key();
785			let mut key2 = layout.allocate_key();
786			let mut key3 = layout.allocate_key();
787
788			layout.set_f32(&mut key1, 0, -100.5);
789			layout.set_f32(&mut key2, 0, 0.0);
790			layout.set_f32(&mut key3, 0, 100.5);
791
792			assert!(key1.as_slice() > key2.as_slice());
793			assert!(key2.as_slice() > key3.as_slice());
794			assert_eq!(layout.get_f32(&key1, 0), -100.5);
795			assert_eq!(layout.get_f32(&key2, 0), 0.0);
796			assert_eq!(layout.get_f32(&key3, 0), 100.5);
797		}
798	}
799
800	mod f64 {
801		use reifydb_type::value::r#type::Type;
802
803		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
804
805		#[test]
806		fn test_asc() {
807			let layout = EncodedIndexLayout::new(&[Type::Float8], &[SortDirection::Asc]).unwrap();
808			let mut key1 = layout.allocate_key();
809			let mut key2 = layout.allocate_key();
810			let mut key3 = layout.allocate_key();
811
812			layout.set_f64(&mut key1, 0, -1000.123456);
813			layout.set_f64(&mut key2, 0, 0.0);
814			layout.set_f64(&mut key3, 0, 1000.123456);
815
816			assert!(key1.as_slice() < key2.as_slice());
817			assert!(key2.as_slice() < key3.as_slice());
818			assert_eq!(layout.get_f64(&key1, 0), -1000.123456);
819			assert_eq!(layout.get_f64(&key2, 0), 0.0);
820			assert_eq!(layout.get_f64(&key3, 0), 1000.123456);
821		}
822
823		#[test]
824		fn test_desc() {
825			let layout = EncodedIndexLayout::new(&[Type::Float8], &[SortDirection::Desc]).unwrap();
826			let mut key1 = layout.allocate_key();
827			let mut key2 = layout.allocate_key();
828			let mut key3 = layout.allocate_key();
829
830			layout.set_f64(&mut key1, 0, -1000.123456);
831			layout.set_f64(&mut key2, 0, 0.0);
832			layout.set_f64(&mut key3, 0, 1000.123456);
833
834			assert!(key1.as_slice() > key2.as_slice());
835			assert!(key2.as_slice() > key3.as_slice());
836			assert_eq!(layout.get_f64(&key1, 0), -1000.123456);
837			assert_eq!(layout.get_f64(&key2, 0), 0.0);
838			assert_eq!(layout.get_f64(&key3, 0), 1000.123456);
839		}
840	}
841
842	mod date {
843		use reifydb_type::value::{date::Date, r#type::Type};
844
845		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
846
847		#[test]
848		fn test_asc() {
849			let layout = EncodedIndexLayout::new(&[Type::Date], &[SortDirection::Asc]).unwrap();
850			let mut key1 = layout.allocate_key();
851			let mut key2 = layout.allocate_key();
852			let mut key3 = layout.allocate_key();
853
854			let date1 = Date::new(2020, 1, 1).unwrap();
855			let date2 = Date::new(2023, 6, 15).unwrap();
856			let date3 = Date::new(2025, 12, 31).unwrap();
857
858			layout.set_date(&mut key1, 0, date1.clone());
859			layout.set_date(&mut key2, 0, date2.clone());
860			layout.set_date(&mut key3, 0, date3.clone());
861
862			assert!(key1.as_slice() < key2.as_slice());
863			assert!(key2.as_slice() < key3.as_slice());
864			assert_eq!(layout.get_date(&key1, 0), date1);
865			assert_eq!(layout.get_date(&key2, 0), date2);
866			assert_eq!(layout.get_date(&key3, 0), date3);
867		}
868
869		#[test]
870		fn test_desc() {
871			let layout = EncodedIndexLayout::new(&[Type::Date], &[SortDirection::Desc]).unwrap();
872			let mut key1 = layout.allocate_key();
873			let mut key2 = layout.allocate_key();
874			let mut key3 = layout.allocate_key();
875
876			let date1 = Date::new(2020, 1, 1).unwrap();
877			let date2 = Date::new(2023, 6, 15).unwrap();
878			let date3 = Date::new(2025, 12, 31).unwrap();
879
880			layout.set_date(&mut key1, 0, date1.clone());
881			layout.set_date(&mut key2, 0, date2.clone());
882			layout.set_date(&mut key3, 0, date3.clone());
883
884			assert!(key1.as_slice() > key2.as_slice());
885			assert!(key2.as_slice() > key3.as_slice());
886			assert_eq!(layout.get_date(&key1, 0), date1);
887			assert_eq!(layout.get_date(&key2, 0), date2);
888			assert_eq!(layout.get_date(&key3, 0), date3);
889		}
890	}
891
892	mod row_number {
893		use reifydb_type::value::r#type::Type;
894
895		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
896
897		#[test]
898		fn test_asc() {
899			let layout = EncodedIndexLayout::new(&[Type::Uint8], &[SortDirection::Asc]).unwrap();
900			let mut key1 = layout.allocate_key();
901			let mut key2 = layout.allocate_key();
902			let mut key3 = layout.allocate_key();
903
904			layout.set_row_number(&mut key1, 0, 1u64);
905			layout.set_row_number(&mut key2, 0, 1000u64);
906			layout.set_row_number(&mut key3, 0, u64::MAX);
907
908			assert!(key1.as_slice() < key2.as_slice());
909			assert!(key2.as_slice() < key3.as_slice());
910			assert_eq!(layout.get_row_number(&key1, 0), 1);
911			assert_eq!(layout.get_row_number(&key2, 0), 1000);
912			assert_eq!(layout.get_row_number(&key3, 0), u64::MAX);
913		}
914
915		#[test]
916		fn test_desc() {
917			let layout = EncodedIndexLayout::new(&[Type::Uint8], &[SortDirection::Desc]).unwrap();
918			let mut key1 = layout.allocate_key();
919			let mut key2 = layout.allocate_key();
920			let mut key3 = layout.allocate_key();
921
922			layout.set_row_number(&mut key1, 0, 1u64);
923			layout.set_row_number(&mut key2, 0, 1000u64);
924			layout.set_row_number(&mut key3, 0, u64::MAX);
925
926			assert!(key1.as_slice() > key2.as_slice());
927			assert!(key2.as_slice() > key3.as_slice());
928			assert_eq!(layout.get_row_number(&key1, 0), 1);
929			assert_eq!(layout.get_row_number(&key2, 0), 1000);
930			assert_eq!(layout.get_row_number(&key3, 0), u64::MAX);
931		}
932	}
933
934	mod identity_id {
935		use std::{thread::sleep, time::Duration};
936
937		use reifydb_type::value::{identity::IdentityId, r#type::Type};
938
939		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
940
941		#[test]
942		fn test_asc() {
943			let layout = EncodedIndexLayout::new(&[Type::IdentityId], &[SortDirection::Asc]).unwrap();
944			let mut key1 = layout.allocate_key();
945			let mut key2 = layout.allocate_key();
946
947			let id1 = IdentityId::generate();
948			// Sleep to ensure different timestamps
949			sleep(Duration::from_millis(10));
950			let id2 = IdentityId::generate();
951
952			layout.set_identity_id(&mut key1, 0, id1.clone());
953			layout.set_identity_id(&mut key2, 0, id2.clone());
954
955			// Should be ordered by timestamp
956			assert!(key1.as_slice() < key2.as_slice());
957			// Should decode back to original values
958			assert_eq!(layout.get_identity_id(&key1, 0), id1);
959			assert_eq!(layout.get_identity_id(&key2, 0), id2);
960		}
961
962		#[test]
963		fn test_desc() {
964			let layout = EncodedIndexLayout::new(&[Type::IdentityId], &[SortDirection::Desc]).unwrap();
965			let mut key1 = layout.allocate_key();
966			let mut key2 = layout.allocate_key();
967
968			let id1 = IdentityId::generate();
969			// Sleep to ensure different timestamps
970			sleep(Duration::from_millis(10));
971			let id2 = IdentityId::generate();
972
973			layout.set_identity_id(&mut key1, 0, id1.clone());
974			layout.set_identity_id(&mut key2, 0, id2.clone());
975
976			// Should be reverse ordered for DESC
977			assert!(key1.as_slice() > key2.as_slice());
978			// Should decode back to original values
979			assert_eq!(layout.get_identity_id(&key1, 0), id1);
980			assert_eq!(layout.get_identity_id(&key2, 0), id2);
981		}
982
983		#[test]
984		fn test_roundtrip() {
985			let layout = EncodedIndexLayout::new(&[Type::IdentityId], &[SortDirection::Asc]).unwrap();
986
987			let id = IdentityId::generate();
988			let mut key = layout.allocate_key();
989
990			// Set and get should preserve the value
991			layout.set_identity_id(&mut key, 0, id.clone());
992			let retrieved = layout.get_identity_id(&key, 0);
993			assert_eq!(retrieved, id);
994		}
995	}
996
997	mod composite {
998		use reifydb_type::value::r#type::Type;
999
1000		use crate::{sort::SortDirection, value::index::layout::EncodedIndexLayout};
1001
1002		#[test]
1003		fn test_mixed_directions() {
1004			let layout = EncodedIndexLayout::new(
1005				&[Type::Int4, Type::Uint8, Type::Uint8],
1006				&[SortDirection::Desc, SortDirection::Asc, SortDirection::Asc],
1007			)
1008			.unwrap();
1009
1010			let mut key1 = layout.allocate_key();
1011			let mut key2 = layout.allocate_key();
1012			let mut key3 = layout.allocate_key();
1013			let mut key4 = layout.allocate_key();
1014
1015			layout.set_i32(&mut key1, 0, 100);
1016			layout.set_u64(&mut key1, 1, 1u64);
1017			layout.set_row_number(&mut key1, 2, 1u64);
1018
1019			layout.set_i32(&mut key2, 0, 100);
1020			layout.set_u64(&mut key2, 1, 2u64);
1021			layout.set_row_number(&mut key2, 2, 1u64);
1022
1023			layout.set_i32(&mut key3, 0, 50);
1024			layout.set_u64(&mut key3, 1, 1u64);
1025			layout.set_row_number(&mut key3, 2, 1u64);
1026
1027			layout.set_i32(&mut key4, 0, 50);
1028			layout.set_u64(&mut key4, 1, 1u64);
1029			layout.set_row_number(&mut key4, 2, 2u64);
1030
1031			// key1 (100, 1, 1) vs key2 (100, 2, 1): same first
1032			// field, second field ascending
1033			assert!(key1.as_slice() < key2.as_slice());
1034			// key1 (100, 1, 1) vs key3 (50, 1, 1): first field is
1035			// DESC, so 100 < 50 in byte order
1036			assert!(key1.as_slice() < key3.as_slice());
1037			// key3 (50, 1, 1) vs key4 (50, 1, 2): same first two
1038			// fields, third field ascending
1039			assert!(key3.as_slice() < key4.as_slice());
1040		}
1041	}
1042}