use crate::engine::EngineId;
#[derive(Debug, Clone)]
pub struct EngineLimits([usize; EngineId::COUNT]);
impl EngineLimits {
pub const fn zeroed() -> Self {
Self([0; EngineId::COUNT])
}
pub const fn uniform(bytes: usize) -> Self {
Self([bytes; EngineId::COUNT])
}
pub fn with(mut self, engine: EngineId, bytes: usize) -> Self {
self.set(engine, bytes);
self
}
pub fn set(&mut self, engine: EngineId, bytes: usize) {
self.0[engine.index()] = bytes;
}
pub fn get(&self, engine: EngineId) -> usize {
self.0[engine.index()]
}
pub fn total(&self) -> usize {
self.0.iter().sum()
}
pub fn iter(&self) -> impl Iterator<Item = (EngineId, usize)> + '_ {
EngineId::ALL
.iter()
.map(|&engine| (engine, self.get(engine)))
}
pub(crate) fn as_array(&self) -> &[usize; EngineId::COUNT] {
&self.0
}
}
impl FromIterator<(EngineId, usize)> for EngineLimits {
fn from_iter<T: IntoIterator<Item = (EngineId, usize)>>(iter: T) -> Self {
let mut limits = Self::zeroed();
for (engine, bytes) in iter {
limits.set(engine, bytes);
}
limits
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn zeroed_has_no_limit() {
let limits = EngineLimits::zeroed();
for &engine in EngineId::ALL {
assert_eq!(limits.get(engine), 0);
}
assert_eq!(limits.total(), 0);
}
#[test]
fn uniform_applies_to_every_engine() {
let limits = EngineLimits::uniform(1024);
for &engine in EngineId::ALL {
assert_eq!(limits.get(engine), 1024);
}
assert_eq!(limits.total(), 1024 * EngineId::COUNT);
}
#[test]
fn with_sets_a_single_engine() {
let limits = EngineLimits::zeroed()
.with(EngineId::Vector, 100)
.with(EngineId::Query, 200);
assert_eq!(limits.get(EngineId::Vector), 100);
assert_eq!(limits.get(EngineId::Query), 200);
assert_eq!(limits.get(EngineId::Kv), 0);
assert_eq!(limits.total(), 300);
}
#[test]
fn set_mutates_in_place() {
let mut limits = EngineLimits::zeroed();
limits.set(EngineId::Crdt, 42);
assert_eq!(limits.get(EngineId::Crdt), 42);
}
#[test]
fn iter_covers_every_engine_in_all_order() {
let limits = EngineLimits::zeroed().with(EngineId::Fts, 7);
let collected: Vec<_> = limits.iter().collect();
assert_eq!(collected.len(), EngineId::COUNT);
assert_eq!(
collected.iter().map(|(e, _)| *e).collect::<Vec<_>>(),
EngineId::ALL.to_vec()
);
assert_eq!(
collected
.iter()
.find(|(e, _)| *e == EngineId::Fts)
.unwrap()
.1,
7
);
}
#[test]
fn from_iter_leaves_unlisted_engines_zero() {
let limits: EngineLimits = [(EngineId::Vector, 10), (EngineId::Kv, 20)]
.into_iter()
.collect();
assert_eq!(limits.get(EngineId::Vector), 10);
assert_eq!(limits.get(EngineId::Kv), 20);
assert_eq!(limits.get(EngineId::Graph), 0);
}
}