fcb_core/static_btree/
key.rs1use crate::static_btree::error::{Error, Result};
2use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
3use chrono::{DateTime, TimeZone, Utc};
4use ordered_float::OrderedFloat; use std::fmt::Debug;
6use std::io::{Read, Write};
7use std::mem;
8
9#[derive(Debug, Clone)]
11pub enum KeyType {
12 StringKey20(FixedStringKey<20>),
14 StringKey50(FixedStringKey<50>),
15 StringKey100(FixedStringKey<100>),
16 Int32(i32),
18 Int64(i64),
19 UInt32(u32),
20 UInt64(u64),
21 Int8(i8),
22 UInt8(u8),
23 Int16(i16),
24 UInt16(u16),
25 Float32(OrderedFloat<f32>),
27 Float64(OrderedFloat<f64>),
28 Bool(bool),
30 DateTime(DateTime<Utc>),
32}
33
34pub trait Max {
39 fn max_value() -> Self;
41}
42
43pub trait Min {
44 fn min_value() -> Self;
46}
47
48pub trait Key: Sized + Ord + Clone + Debug + Default + Max + Min {
54 const SERIALIZED_SIZE: usize;
57
58 fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize>;
67
68 fn read_from<R: Read>(reader: &mut R) -> Result<Self>;
77
78 fn from_bytes(bytes: &[u8]) -> Result<Self>;
87}
88
89impl Max for i8 {
91 fn max_value() -> Self {
92 i8::MAX
93 }
94}
95
96impl Max for u8 {
97 fn max_value() -> Self {
98 u8::MAX
99 }
100}
101
102impl Max for u16 {
103 fn max_value() -> Self {
104 u16::MAX
105 }
106}
107
108impl Max for i16 {
109 fn max_value() -> Self {
110 i16::MAX
111 }
112}
113
114impl Max for i32 {
115 fn max_value() -> Self {
116 i32::MAX
117 }
118}
119
120impl Max for u32 {
121 fn max_value() -> Self {
122 u32::MAX
123 }
124}
125
126impl Max for i64 {
127 fn max_value() -> Self {
128 i64::MAX
129 }
130}
131
132impl Max for u64 {
133 fn max_value() -> Self {
134 u64::MAX
135 }
136}
137
138impl Max for OrderedFloat<f32> {
140 fn max_value() -> Self {
141 OrderedFloat(f32::INFINITY)
142 }
143}
144
145impl Max for OrderedFloat<f64> {
146 fn max_value() -> Self {
147 OrderedFloat(f64::INFINITY)
148 }
149}
150
151impl Max for bool {
153 fn max_value() -> Self {
154 true
155 }
156}
157
158impl Max for DateTime<Utc> {
160 fn max_value() -> Self {
161 Utc.timestamp_opt(253402300799, 999_999_999)
163 .single()
164 .unwrap()
165 }
166}
167
168impl<const N: usize> Max for FixedStringKey<N> {
170 fn max_value() -> Self {
171 Self([0xFF; N])
173 }
174}
175
176impl Min for i8 {
178 fn min_value() -> Self {
179 i8::MIN
180 }
181}
182
183impl Min for u8 {
184 fn min_value() -> Self {
185 u8::MIN
186 }
187}
188impl Min for i16 {
189 fn min_value() -> Self {
190 i16::MIN
191 }
192}
193
194impl Min for u16 {
195 fn min_value() -> Self {
196 u16::MIN
197 }
198}
199
200impl Min for i32 {
201 fn min_value() -> Self {
202 i32::MIN
203 }
204}
205
206impl Min for u32 {
207 fn min_value() -> Self {
208 u32::MIN
209 }
210}
211
212impl Min for i64 {
213 fn min_value() -> Self {
214 i64::MIN
215 }
216}
217
218impl Min for u64 {
219 fn min_value() -> Self {
220 u64::MIN
221 }
222}
223
224impl Min for OrderedFloat<f32> {
225 fn min_value() -> Self {
226 OrderedFloat(f32::NEG_INFINITY)
227 }
228}
229
230impl Min for OrderedFloat<f64> {
231 fn min_value() -> Self {
232 OrderedFloat(f64::NEG_INFINITY)
233 }
234}
235
236impl Min for bool {
237 fn min_value() -> Self {
238 false
239 }
240}
241
242impl Min for DateTime<Utc> {
243 fn min_value() -> Self {
244 Utc.timestamp_opt(0, 0).single().unwrap()
245 }
246}
247
248impl<const N: usize> Min for FixedStringKey<N> {
249 fn min_value() -> Self {
250 FixedStringKey([0u8; N])
251 }
252}
253
254macro_rules! impl_key_for_int {
256 ($T:ty, $write_method:ident) => {
257 impl Key for $T {
258 const SERIALIZED_SIZE: usize = mem::size_of::<$T>();
259
260 #[inline]
261 fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
262 writer.$write_method::<LittleEndian>(*self)?;
263 Ok(Self::SERIALIZED_SIZE)
264 }
265
266 #[inline]
267 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
268 let mut bytes = [0u8; Self::SERIALIZED_SIZE];
269 reader.read_exact(&mut bytes)?;
270 Ok(<$T>::from_le_bytes(bytes))
271 }
272
273 #[inline]
274 fn from_bytes(bytes: &[u8]) -> Result<Self> {
275 let mut array = [0u8; Self::SERIALIZED_SIZE];
276 array.copy_from_slice(&bytes[0..Self::SERIALIZED_SIZE]);
277 Ok(<$T>::from_le_bytes(array))
278 }
279 }
280 };
281}
282
283macro_rules! impl_key_for_byte {
285 ($T:ty, $write_method:ident) => {
286 impl Key for $T {
287 const SERIALIZED_SIZE: usize = mem::size_of::<$T>();
288
289 #[inline]
290 fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
291 writer.$write_method(*self)?;
292 Ok(Self::SERIALIZED_SIZE)
293 }
294
295 #[inline]
296 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
297 let mut bytes = [0u8; Self::SERIALIZED_SIZE];
298 reader.read_exact(&mut bytes)?;
299 Ok(<$T>::from_le_bytes(bytes))
300 }
301
302 #[inline]
303 fn from_bytes(bytes: &[u8]) -> Result<Self> {
304 let mut array = [0u8; Self::SERIALIZED_SIZE];
305 array.copy_from_slice(&bytes[0..Self::SERIALIZED_SIZE]);
306 Ok(<$T>::from_le_bytes(array))
307 }
308 }
309 };
310}
311
312impl_key_for_byte!(u8, write_u8);
314impl_key_for_byte!(i8, write_i8);
315impl_key_for_int!(i16, write_i16);
316impl_key_for_int!(u16, write_u16);
317impl_key_for_int!(i32, write_i32);
318impl_key_for_int!(u32, write_u32);
319impl_key_for_int!(i64, write_i64);
320impl_key_for_int!(u64, write_u64);
321
322impl Key for OrderedFloat<f32> {
324 const SERIALIZED_SIZE: usize = mem::size_of::<f32>();
325
326 #[inline]
327 fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
328 writer.write_f32::<LittleEndian>(self.into_inner())?;
329 Ok(Self::SERIALIZED_SIZE)
330 }
331
332 #[inline]
333 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
334 let mut bytes = [0u8; Self::SERIALIZED_SIZE];
335 reader.read_exact(&mut bytes)?;
336 Ok(OrderedFloat::from(f32::from_le_bytes(bytes)))
337 }
338
339 #[inline]
340 fn from_bytes(bytes: &[u8]) -> Result<Self> {
341 let mut array = [0u8; Self::SERIALIZED_SIZE];
342 array.copy_from_slice(&bytes[0..Self::SERIALIZED_SIZE]);
343 Ok(OrderedFloat::from(f32::from_le_bytes(array)))
344 }
345}
346
347impl Key for OrderedFloat<f64> {
349 const SERIALIZED_SIZE: usize = mem::size_of::<f64>();
350
351 #[inline]
352 fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
353 writer.write_f64::<LittleEndian>(self.into_inner())?;
354 Ok(Self::SERIALIZED_SIZE)
355 }
356
357 #[inline]
358 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
359 let mut bytes = [0u8; Self::SERIALIZED_SIZE];
360 reader.read_exact(&mut bytes)?;
361 Ok(OrderedFloat::from(f64::from_le_bytes(bytes)))
362 }
363
364 #[inline]
365 fn from_bytes(bytes: &[u8]) -> Result<Self> {
366 let mut array = [0u8; Self::SERIALIZED_SIZE];
367 array.copy_from_slice(&bytes[0..Self::SERIALIZED_SIZE]);
368 Ok(OrderedFloat::from(f64::from_le_bytes(array)))
369 }
370}
371
372impl Key for bool {
374 const SERIALIZED_SIZE: usize = 1;
375
376 #[inline]
377 fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
378 writer.write_all(&[*self as u8]).map_err(Error::from)?;
379 Ok(Self::SERIALIZED_SIZE)
380 }
381
382 #[inline]
383 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
384 let mut byte = [0u8];
385 reader.read_exact(&mut byte)?;
386 Ok(byte[0] != 0)
387 }
388
389 #[inline]
390 fn from_bytes(bytes: &[u8]) -> Result<Self> {
391 Ok(bytes[0] != 0)
392 }
393}
394
395impl Key for DateTime<Utc> {
397 const SERIALIZED_SIZE: usize = 12; #[inline]
400 fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
401 writer.write_i64::<LittleEndian>(self.timestamp())?;
403 writer.write_u32::<LittleEndian>(self.timestamp_subsec_nanos())?;
405 Ok(Self::SERIALIZED_SIZE)
406 }
407
408 #[inline]
409 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
410 let secs = reader.read_i64::<LittleEndian>()?;
411 let nanos = reader.read_u32::<LittleEndian>()?;
412 let dt = DateTime::<Utc>::from_timestamp(secs, nanos).expect("invalid datetime value");
413 Ok(dt)
414 }
415
416 #[inline]
417 fn from_bytes(bytes: &[u8]) -> Result<Self> {
418 let mut array = [0u8; Self::SERIALIZED_SIZE];
419 array.copy_from_slice(&bytes[0..Self::SERIALIZED_SIZE]);
420 let secs = i64::from_le_bytes(array[0..8].try_into().unwrap());
421 let nanos = u32::from_le_bytes(array[8..12].try_into().unwrap());
422 let dt = DateTime::<Utc>::from_timestamp(secs, nanos).expect("invalid datetime value");
423 Ok(dt)
424 }
425}
426
427#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
434pub struct FixedStringKey<const N: usize>([u8; N]);
435
436impl<const N: usize> Default for FixedStringKey<N> {
437 fn default() -> Self {
438 Self([0u8; N])
439 }
440}
441
442impl<const N: usize> Key for FixedStringKey<N> {
443 const SERIALIZED_SIZE: usize = N;
444
445 #[inline]
446 fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
447 writer.write_all(&self.0).map_err(Error::from)?;
448 Ok(Self::SERIALIZED_SIZE)
449 }
450
451 #[inline]
452 fn read_from<R: Read>(reader: &mut R) -> Result<Self> {
453 let mut bytes = [0u8; N];
454 reader.read_exact(&mut bytes)?;
455 Ok(FixedStringKey(bytes))
456 }
457
458 #[inline]
459 fn from_bytes(bytes: &[u8]) -> Result<Self> {
460 let mut array = [0u8; N];
461 array.copy_from_slice(&bytes[0..N]);
462 Ok(FixedStringKey(array))
463 }
464}
465
466impl<const N: usize> FixedStringKey<N> {
467 pub fn from_str(s: &str) -> Self {
483 let mut bytes = [0u8; N];
484 let source_bytes = s.as_bytes();
485 let len_to_copy = std::cmp::min(source_bytes.len(), N);
486 bytes[..len_to_copy].copy_from_slice(&source_bytes[..len_to_copy]);
487 FixedStringKey(bytes)
489 }
490
491 pub fn to_string_lossy(&self) -> String {
511 let first_null = self.0.iter().position(|&b| b == 0).unwrap_or(N);
513 String::from_utf8_lossy(&self.0[..first_null]).into_owned()
515 }
516}
517
518#[cfg(test)]
519mod tests {
520 use chrono::Datelike;
521
522 use super::*;
523 use std::cmp::Ordering;
524 use std::f32;
525 use std::f64;
526 use std::io::Cursor;
527
528 fn test_key_impl<T: Key + Eq + Debug>(key_val: T) {
529 let mut buffer = Vec::new();
530 key_val.write_to(&mut buffer).expect("write should succeed");
531 assert_eq!(buffer.len(), T::SERIALIZED_SIZE);
532
533 let mut cursor = Cursor::new(buffer);
534 let deserialized_key = T::read_from(&mut cursor).expect("read should succeed");
535 assert_eq!(key_val, deserialized_key);
536
537 if T::SERIALIZED_SIZE > 0 {
539 let short_buffer = vec![0u8; T::SERIALIZED_SIZE - 1];
541 let mut short_cursor = Cursor::new(short_buffer);
542 let result = T::read_from(&mut short_cursor);
543 assert!(result.is_err());
544 match result.err().unwrap() {
545 Error::IoError(e) => assert_eq!(e.kind(), std::io::ErrorKind::UnexpectedEof),
546 _ => panic!("expected io error for short read"),
547 }
548 }
549 }
550
551 #[test]
552 fn test_max_values() {
553 assert_eq!(i32::max_value(), i32::MAX);
555 assert_eq!(u32::max_value(), u32::MAX);
556 assert_eq!(i64::max_value(), i64::MAX);
557 assert_eq!(u64::max_value(), u64::MAX);
558
559 assert_eq!(
561 OrderedFloat::<f32>::max_value(),
562 OrderedFloat(f32::INFINITY)
563 );
564 assert_eq!(
565 OrderedFloat::<f64>::max_value(),
566 OrderedFloat(f64::INFINITY)
567 );
568
569 assert!(bool::max_value());
571
572 let max_date = DateTime::<Utc>::max_value();
574 assert!(max_date.year() >= 9999); let max_str_key = FixedStringKey::<5>::max_value();
578 assert_eq!(max_str_key.0, [0xFF; 5]);
579
580 assert!(5_i32 < i32::max_value());
582 assert!(OrderedFloat(1000.0f64) < OrderedFloat::<f64>::max_value());
583 assert!(bool::max_value());
584 assert!(Utc::now() < DateTime::<Utc>::max_value());
585 assert!(FixedStringKey::<5>::from_str("zzzzz") < FixedStringKey::<5>::max_value());
586 }
587
588 #[test]
589 fn test_int_keys() {
590 test_key_impl(12345i32);
591 test_key_impl(-54321i32);
592 test_key_impl(0i32);
593 test_key_impl(i32::MAX);
594 test_key_impl(i32::MIN);
595
596 test_key_impl(12345u32);
597 test_key_impl(0u32);
598 test_key_impl(u32::MAX);
599
600 test_key_impl(123456789012345i64);
601 test_key_impl(-98765432109876i64);
602 test_key_impl(0i64);
603 test_key_impl(i64::MAX);
604 test_key_impl(i64::MIN);
605
606 test_key_impl(123456789012345u64);
607 test_key_impl(0u64);
608 test_key_impl(u64::MAX);
609 }
610
611 #[test]
612 fn test_float_keys() {
613 test_key_impl(OrderedFloat(123.45f32));
614 test_key_impl(OrderedFloat(-987.65f32));
615 test_key_impl(OrderedFloat(0.0f32));
616 test_key_impl(OrderedFloat(f32::MAX));
617 test_key_impl(OrderedFloat(f32::MIN));
618 test_key_impl(OrderedFloat(f32::INFINITY));
619 test_key_impl(OrderedFloat(f32::NEG_INFINITY));
620 test_key_impl(OrderedFloat(f32::NAN)); test_key_impl(OrderedFloat(123456.789012f64));
623 test_key_impl(OrderedFloat(-987654.321098f64));
624 test_key_impl(OrderedFloat(0.0f64));
625 test_key_impl(OrderedFloat(f64::MAX));
626 test_key_impl(OrderedFloat(f64::MIN));
627 test_key_impl(OrderedFloat(f64::INFINITY));
628 test_key_impl(OrderedFloat(f64::NEG_INFINITY));
629 test_key_impl(OrderedFloat(f64::NAN)); }
631
632 #[test]
633 fn test_float_ordering() {
634 assert!(OrderedFloat(1.0f32) < OrderedFloat(2.0f32));
636 assert!(OrderedFloat(-1.0f64) < OrderedFloat(1.0f64));
637
638 assert!(OrderedFloat(f32::MAX) < OrderedFloat(f32::INFINITY));
640 assert!(OrderedFloat(f64::NEG_INFINITY) < OrderedFloat(f64::MIN));
641
642 assert!(OrderedFloat(f32::INFINITY) < OrderedFloat(f32::NAN));
644 assert!(OrderedFloat(f64::MAX) < OrderedFloat(f64::NAN));
645 assert!(OrderedFloat(f32::NAN).cmp(&OrderedFloat(f32::NAN)) == Ordering::Equal);
646 }
647
648 #[test]
649 fn test_fixed_string_key_from_str() {
650 let key_short = FixedStringKey::<10>::from_str("hello");
652 assert_eq!(key_short.0[0..5], *b"hello");
653 assert_eq!(key_short.0[5..], [0u8; 5]);
654 assert_eq!(key_short.to_string_lossy(), "hello");
655
656 let key_long = FixedStringKey::<3>::from_str("world");
658 assert_eq!(key_long.0, *b"wor");
659 assert_eq!(key_long.to_string_lossy(), "wor");
660
661 let key_exact = FixedStringKey::<5>::from_str("exact");
663 assert_eq!(key_exact.0, *b"exact");
664 assert_eq!(key_exact.to_string_lossy(), "exact");
665
666 let key_empty = FixedStringKey::<4>::from_str("");
668 assert_eq!(key_empty.0, [0u8; 4]);
669 assert_eq!(key_empty.to_string_lossy(), "");
670 }
671
672 #[test]
673 fn test_fixed_string_key_to_string_lossy() {
674 let key1 = FixedStringKey::<10>::from_str("test\0ing"); assert_eq!(key1.to_string_lossy(), "test"); let key2 = FixedStringKey::<5>::from_str("abcde");
678 assert_eq!(key2.to_string_lossy(), "abcde"); let key3 = FixedStringKey::<3>::from_str("xyz123"); assert_eq!(key3.to_string_lossy(), "xyz");
682 }
683
684 #[test]
685 fn test_fixed_string_key_serialization() {
686 test_key_impl(FixedStringKey::<8>::from_str("testkey"));
687 test_key_impl(FixedStringKey::<4>::from_str("longkey")); test_key_impl(FixedStringKey::<12>::from_str("short")); test_key_impl(FixedStringKey::<5>::from_str("")); }
691
692 #[test]
693 fn test_fixed_string_key_ordering() {
694 let key1 = FixedStringKey::<10>::from_str("apple");
695 let key2 = FixedStringKey::<10>::from_str("apply");
696 let key3 = FixedStringKey::<10>::from_str("banana");
697 let key4 = FixedStringKey::<10>::from_str("apple"); let key5 = FixedStringKey::<10>::from_str("app"); assert!(key1 < key2);
701 assert!(key2 < key3);
702 assert!(key1 < key3);
703 assert_eq!(key1.cmp(&key4), Ordering::Equal);
704 assert!(key5 < key1); }
706
707 #[test]
708 fn test_bool_keys() {
709 test_key_impl(true);
710 test_key_impl(false);
711 }
712
713 #[test]
714 fn test_datetime_keys() {
715 let dt = chrono::DateTime::parse_from_rfc3339("2010-10-13T12:43:04Z")
740 .unwrap()
741 .to_utc();
742 test_key_impl(dt);
743 }
744}