#[allow(dead_code)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct Arena {
slots: Vec<Option<Value>>,
next_free: usize,
capacity: usize,
}
impl Default for Arena {
fn default() -> Self {
Self::new(128)
}
}
#[allow(dead_code)]
impl Arena {
#[must_use]
pub(crate) fn new(capacity: usize) -> Self {
let cap = capacity.max(1);
Self {
slots: vec![None; cap],
next_free: 0,
capacity: cap,
}
}
pub(crate) fn alloc(&mut self, value: Value) -> Result<usize, String> {
for offset in 0..self.capacity {
let idx = (self.next_free + offset) % self.capacity;
if self.slots[idx].is_none() {
self.slots[idx] = Some(value);
self.next_free = (idx + 1) % self.capacity;
debug_assert!(self.check_invariants());
return Ok(idx);
}
}
Err("arena full".to_string())
}
pub(crate) fn free(&mut self, idx: usize) -> Result<Value, String> {
if idx >= self.capacity {
return Err("arena index out of bounds".to_string());
}
let value = self.slots[idx]
.take()
.ok_or_else(|| "arena slot already free".to_string())?;
if idx < self.next_free {
self.next_free = idx;
}
debug_assert!(self.check_invariants());
Ok(value)
}
#[must_use]
pub(crate) fn get(&self, idx: usize) -> Option<&Value> {
self.slots.get(idx).and_then(Option::as_ref)
}
pub(crate) fn get_mut(&mut self, idx: usize) -> Option<&mut Value> {
self.slots.get_mut(idx).and_then(Option::as_mut)
}
#[must_use]
pub(crate) fn check_invariants(&self) -> bool {
self.slots.len() == self.capacity && self.next_free < self.capacity
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub(crate) enum SessionKind {
Client,
Server,
Peer,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub(crate) struct WellTypedInstr {
pub endpoint: Endpoint,
pub instr_tag: String,
pub tick: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub(crate) struct SessionMonitor {
session_kinds: BTreeMap<SessionId, SessionKind>,
last_judgment: Option<WellTypedInstr>,
}
impl SessionMonitor {
pub(crate) fn set_kind(&mut self, sid: SessionId, kind: SessionKind) {
self.session_kinds.insert(sid, kind);
}
pub(crate) fn remove_kind(&mut self, sid: SessionId) {
self.session_kinds.remove(&sid);
}
pub(crate) fn record(&mut self, endpoint: &Endpoint, instr_tag: &str, tick: u64) {
self.last_judgment = Some(WellTypedInstr {
endpoint: endpoint.clone(),
instr_tag: instr_tag.to_string(),
tick,
});
}
}
pub(crate) type SiteId = String;
#[allow(dead_code)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub(crate) struct CorruptedEdge {
edge: Edge,
corruption: CorruptionType,
}
#[allow(dead_code)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub(crate) struct SiteTimeout {
site: SiteId,
until_tick: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GuardLayerConfig {
pub id: String,
pub active: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum MonitorMode {
Off,
#[default]
SessionTypePrecheck,
}