use super::dharht_memory::{shape_hash, DHarhtMemory};
#[derive(Clone, Debug)]
pub struct SealedU64Map<V: Clone> {
inner: DHarhtMemory<V>,
}
impl<V: Clone> SealedU64Map<V> {
pub fn new() -> Self {
Self {
inner: DHarhtMemory::new(),
}
}
pub fn insert(&mut self, key: u64, value: V) -> Option<V> {
self.inner.insert(key, value)
}
#[inline]
pub fn get(&self, key: u64) -> Option<&V> {
self.inner.get(key)
}
pub fn contains_key(&self, key: u64) -> bool {
self.inner.contains_key(key)
}
pub fn seal(&mut self) {
self.inner.seal_for_lookup();
}
pub fn is_sealed(&self) -> bool {
self.inner.is_sealed()
}
pub fn len(&self) -> u64 {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn iter_sorted(&self) -> Vec<(u64, &V)> {
self.inner.iter_sorted()
}
pub fn approx_memory_bytes(&self) -> usize {
self.inner.approx_memory_bytes()
}
pub fn micro_overflow_count(&self) -> u64 {
self.inner.micro_overflow_count()
}
pub fn max_collision_group(&self) -> u32 {
self.inner.max_collision_group()
}
pub fn shape_hash(&self) -> u64
where
V: std::hash::Hash,
{
shape_hash(&self.inner)
}
}
impl<V: Clone> Default for SealedU64Map<V> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn build_seal_read_lifecycle() {
let mut m: SealedU64Map<u64> = SealedU64Map::new();
for i in 0..1000u64 {
m.insert(i, i * 31);
}
assert_eq!(m.get(42), Some(&(42 * 31)));
assert!(!m.is_sealed());
m.seal();
assert!(m.is_sealed());
for i in 0..1000u64 {
assert_eq!(m.get(i), Some(&(i * 31)));
}
}
#[test]
fn shape_hash_byte_equal_for_identical_input() {
let build = || -> SealedU64Map<u64> {
let mut m = SealedU64Map::new();
for i in 0..500u64 {
m.insert(i.wrapping_mul(0xdeadbeef), i);
}
m.seal();
m
};
assert_eq!(build().shape_hash(), build().shape_hash());
}
#[test]
fn iter_sorted_canonical() {
let mut a: SealedU64Map<u64> = SealedU64Map::new();
let mut b: SealedU64Map<u64> = SealedU64Map::new();
for i in 0..100u64 {
a.insert(i, i);
}
for i in (0..100u64).rev() {
b.insert(i, i);
}
a.seal();
b.seal();
let av: Vec<(u64, u64)> = a.iter_sorted().into_iter().map(|(k, v)| (k, *v)).collect();
let bv: Vec<(u64, u64)> = b.iter_sorted().into_iter().map(|(k, v)| (k, *v)).collect();
assert_eq!(av, bv);
}
#[test]
fn no_silent_loss_at_scale() {
let mut m: SealedU64Map<u64> = SealedU64Map::new();
for i in 0..50_000u64 {
m.insert(i, i);
}
m.seal();
for i in 0..50_000u64 {
assert_eq!(m.get(i), Some(&i));
}
}
}