use std::hash::{BuildHasher, Hash, Hasher};
use hashbrown::HashMap;
use hashbrown::hash_map::RawEntryMut;
use super::row::{OwnedRowKey, RowBody, RowValue};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WriteOp {
Insert,
Update,
Skip,
}
#[derive(Default)]
pub struct Shadow {
rows: HashMap<OwnedRowKey, RowBody>,
}
impl Shadow {
pub fn new() -> Self {
Self::default()
}
pub fn record(&mut self, value: &RowValue<'_>) -> WriteOp {
let key_ref = value.key();
let hash = {
let mut state = self.rows.hasher().build_hasher();
key_ref.hash(&mut state);
state.finish()
};
let entry = self
.rows
.raw_entry_mut()
.from_hash(hash, |owned| key_ref.matches_owned(owned));
match entry {
RawEntryMut::Occupied(mut o) => {
if value.body_eq(o.get()) {
WriteOp::Skip
} else {
*o.get_mut() = value.to_body();
WriteOp::Update
}
}
RawEntryMut::Vacant(v) => {
v.insert_hashed_nocheck(hash, key_ref.to_owned_key(), value.to_body());
WriteOp::Insert
}
}
}
}