2022-09-01 11:40:29 +02:00
|
|
|
use std::borrow::Cow;
|
|
|
|
use std::convert::TryInto;
|
2022-08-29 16:01:54 +02:00
|
|
|
|
2023-11-22 18:21:19 +01:00
|
|
|
use heed::{BoxedError, BytesDecode};
|
2023-11-28 10:11:17 +01:00
|
|
|
use thiserror::Error;
|
2022-08-29 16:01:54 +02:00
|
|
|
|
|
|
|
use crate::facet::value_encoding::f64_into_bytes;
|
2023-11-28 10:11:17 +01:00
|
|
|
use crate::heed_codec::SliceTooShortError;
|
2022-08-29 16:01:54 +02:00
|
|
|
|
|
|
|
pub struct OrderedF64Codec;
|
|
|
|
|
|
|
|
impl<'a> BytesDecode<'a> for OrderedF64Codec {
|
|
|
|
type DItem = f64;
|
|
|
|
|
2023-11-22 18:21:19 +01:00
|
|
|
fn bytes_decode(bytes: &'a [u8]) -> Result<Self::DItem, BoxedError> {
|
2022-08-29 16:01:54 +02:00
|
|
|
if bytes.len() < 16 {
|
2023-11-28 10:11:17 +01:00
|
|
|
Err(SliceTooShortError.into())
|
2023-11-23 14:47:56 +01:00
|
|
|
} else {
|
|
|
|
bytes[8..].try_into().map(f64::from_be_bytes).map_err(Into::into)
|
2022-08-29 16:01:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl heed::BytesEncode<'_> for OrderedF64Codec {
|
|
|
|
type EItem = f64;
|
|
|
|
|
2023-11-22 18:21:19 +01:00
|
|
|
fn bytes_encode(f: &Self::EItem) -> Result<Cow<[u8]>, BoxedError> {
|
2022-08-29 16:01:54 +02:00
|
|
|
let mut buffer = [0u8; 16];
|
|
|
|
|
|
|
|
// write the globally ordered float
|
2023-11-28 10:11:17 +01:00
|
|
|
let bytes = f64_into_bytes(*f).ok_or(InvalidGloballyOrderedFloatError { float: *f })?;
|
2022-08-29 16:01:54 +02:00
|
|
|
buffer[..8].copy_from_slice(&bytes[..]);
|
|
|
|
// Then the f64 value just to be able to read it back
|
|
|
|
let bytes = f.to_be_bytes();
|
|
|
|
buffer[8..16].copy_from_slice(&bytes[..]);
|
|
|
|
|
2023-11-22 18:21:19 +01:00
|
|
|
Ok(Cow::Owned(buffer.to_vec()))
|
2022-08-29 16:01:54 +02:00
|
|
|
}
|
|
|
|
}
|
2023-11-28 10:11:17 +01:00
|
|
|
|
|
|
|
#[derive(Error, Debug)]
|
|
|
|
#[error("the float {float} cannot be converted to a globally ordered representation")]
|
|
|
|
pub struct InvalidGloballyOrderedFloatError {
|
|
|
|
float: f64,
|
|
|
|
}
|