use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SortedVec<T>(Vec<T>);
impl<T: zerompk::ToMessagePack> zerompk::ToMessagePack for SortedVec<T> {
fn write<W: zerompk::Write>(&self, writer: &mut W) -> zerompk::Result<()> {
self.0.write(writer)
}
}
impl<'de, T> zerompk::FromMessagePack<'de> for SortedVec<T>
where
T: zerompk::FromMessagePack<'de> + Ord + Clone,
{
fn read<R: zerompk::Read<'de>>(reader: &mut R) -> zerompk::Result<Self> {
let v = Vec::<T>::read(reader)?;
Ok(Self::new(v))
}
}
impl<T: Ord + Clone> SortedVec<T> {
pub fn new(mut items: Vec<T>) -> Self {
items.sort();
items.dedup();
Self(items)
}
pub fn as_slice(&self) -> &[T] {
&self.0
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn iter(&self) -> std::slice::Iter<'_, T> {
self.0.iter()
}
}
impl<T: Ord + Clone> From<Vec<T>> for SortedVec<T> {
fn from(v: Vec<T>) -> Self {
Self::new(v)
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Serialize,
Deserialize,
zerompk::ToMessagePack,
zerompk::FromMessagePack,
)]
pub enum EngineKeySet {
Document {
collection: String,
surrogates: SortedVec<u32>,
},
Vector {
collection: String,
surrogates: SortedVec<u32>,
},
Kv {
collection: String,
keys: SortedVec<Vec<u8>>,
},
Edge {
collection: String,
edges: SortedVec<(u32, u32)>,
},
}
impl EngineKeySet {
pub fn serialized_size_hint(&self) -> usize {
match self {
Self::Document { surrogates, .. } | Self::Vector { surrogates, .. } => {
surrogates.len() * 4
}
Self::Kv { keys, .. } => keys.iter().map(|k| k.len()).sum(),
Self::Edge { edges, .. } => edges.len() * 8,
}
}
pub fn collection(&self) -> &str {
match self {
Self::Document { collection, .. }
| Self::Vector { collection, .. }
| Self::Kv { collection, .. }
| Self::Edge { collection, .. } => collection,
}
}
pub fn is_empty(&self) -> bool {
match self {
Self::Document { surrogates, .. } => surrogates.is_empty(),
Self::Vector { surrogates, .. } => surrogates.is_empty(),
Self::Kv { keys, .. } => keys.is_empty(),
Self::Edge { edges, .. } => edges.is_empty(),
}
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Serialize,
Deserialize,
zerompk::ToMessagePack,
zerompk::FromMessagePack,
)]
pub struct PassiveReadKey {
pub engine_key: EngineKeySet,
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Serialize,
Deserialize,
zerompk::ToMessagePack,
zerompk::FromMessagePack,
)]
pub struct DependentReadSpec {
pub passive_reads: BTreeMap<u32, Vec<PassiveReadKey>>,
}
impl DependentReadSpec {
pub fn total_bytes(&self) -> usize {
self.passive_reads
.values()
.flat_map(|ks| ks.iter())
.map(|k| k.engine_key.serialized_size_hint())
.sum()
}
}