prolly-map 0.4.0

Content-addressed versioned map storage primitives.
Documentation
use super::super::error::Error;
use xxhash_rust::xxh64::xxh64;

pub(crate) fn encode_components(vector: &[f32], out: &mut Vec<u8>) {
    for component in vector {
        out.extend_from_slice(&component.to_bits().to_le_bytes());
    }
}

pub(crate) fn decode_components(bytes: &[u8], dimensions: u32) -> Result<Vec<f32>, Error> {
    let count = usize::try_from(dimensions).map_err(|_| Error::InvalidProximityVector {
        reason: "dimensions exceed usize".to_owned(),
    })?;
    let expected = count
        .checked_mul(4)
        .ok_or_else(|| Error::InvalidProximityVector {
            reason: "vector byte length overflow".to_owned(),
        })?;
    if bytes.len() != expected {
        return Err(Error::InvalidProximityVector {
            reason: format!("expected {expected} vector bytes, received {}", bytes.len()),
        });
    }
    let mut vector = Vec::with_capacity(count);
    for (index, chunk) in bytes.chunks_exact(4).enumerate() {
        let bits = u32::from_le_bytes(chunk.try_into().expect("four-byte chunk"));
        let component = f32::from_bits(bits);
        if !component.is_finite() || bits == 0x8000_0000 {
            return Err(Error::InvalidProximityVector {
                reason: format!("component {index} is non-canonical"),
            });
        }
        vector.push(component);
    }
    Ok(vector)
}

pub(crate) fn promotion_level(key: &[u8], log_chunk_size: u8, seed: u64) -> u8 {
    let zeros = xxh64(key, seed).leading_zeros() as u8;
    zeros / log_chunk_size
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn promotion_is_deterministic() {
        assert_eq!(
            promotion_level(b"stable", 8, 42),
            promotion_level(b"stable", 8, 42)
        );
    }
}