use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::receptionist::Visibility;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum OpType {
Register {
label: String,
actor_type_name: String,
key_ids: Vec<String>,
origin_addr: String,
#[serde(default)]
visibility: Visibility,
},
Remove {
label: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Op {
pub seq: u64,
pub node_id: String,
pub op_type: OpType,
}
pub(crate) struct OpLog {
pub(crate) ops: Vec<Op>,
next_seq: u64,
node_id: String,
}
impl OpLog {
pub(crate) fn new(node_id: String) -> Self {
Self {
ops: Vec::new(),
next_seq: 1,
node_id,
}
}
pub(crate) fn append(&mut self, op_type: OpType) -> Op {
let op = Op {
seq: self.next_seq,
node_id: self.node_id.clone(),
op_type,
};
self.next_seq += 1;
self.ops.push(op.clone());
op
}
pub(crate) fn ops_since(&self, seq: u64) -> &[Op] {
let start = self.ops.partition_point(|op| op.seq <= seq);
&self.ops[start..]
}
pub(crate) fn latest_seq(&self) -> u64 {
self.next_seq.saturating_sub(1)
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct VersionVector {
versions: HashMap<String, u64>,
}
impl VersionVector {
pub fn new() -> Self {
Self::default()
}
pub fn get(&self, node_id: &str) -> u64 {
self.versions.get(node_id).copied().unwrap_or(0)
}
pub fn update(&mut self, node_id: &str, seq: u64) {
let entry = self.versions.entry(node_id.to_string()).or_insert(0);
if seq > *entry {
*entry = seq;
}
}
pub fn merge(&mut self, other: &VersionVector) {
for (node_id, &seq) in &other.versions {
self.update(node_id, seq);
}
}
}