swactor/crates/swactor-gossip/src/state.rs

70 lines
1.8 KiB
Rust
Raw Normal View History

2026-02-08 13:40:48 +00:00
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct VersionedValue {
pub value: Vec<u8>,
pub version: u64,
}
#[derive(Debug, Clone, Default)]
pub struct GossipState {
entries: HashMap<String, VersionedValue>,
}
impl GossipState {
pub fn new() -> Self {
Self::default()
}
/// Insert or update a key. Auto-increments the version for that key.
/// Returns the new version number.
pub fn set(&mut self, key: String, value: Vec<u8>) -> u64 {
let new_version = self
.entries
.get(&key)
.map_or(1, |existing| existing.version + 1);
self.entries.insert(
key,
VersionedValue {
value,
version: new_version,
},
);
new_version
}
pub fn get(&self, key: &str) -> Option<&VersionedValue> {
self.entries.get(key)
}
pub fn entries(&self) -> &HashMap<String, VersionedValue> {
&self.entries
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
/// Merge a remote state into this one. For each key, keep the entry
/// with the higher version (last-writer-wins). Returns the number of
/// entries that were updated.
pub fn merge(&mut self, remote: &GossipState) -> usize {
let mut updated = 0;
for (key, remote_val) in &remote.entries {
let dominated = match self.entries.get(key) {
Some(local_val) => remote_val.version > local_val.version,
None => true,
};
if dominated {
self.entries.insert(key.clone(), remote_val.clone());
updated += 1;
}
}
updated
}
}