use crate::session::SessionId;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
pub type StringId = u32;
pub type EdgeId = u32;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SymbolTable {
symbols: Vec<String>,
index: BTreeMap<String, StringId>,
}
impl SymbolTable {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn intern(&mut self, value: &str) -> StringId {
if let Some(id) = self.index.get(value) {
return *id;
}
let id = match u32::try_from(self.symbols.len()) {
Ok(id) => id,
Err(_) => return u32::MAX,
};
let owned = value.to_string();
self.symbols.push(owned.clone());
self.index.insert(owned, id);
id
}
#[must_use]
#[allow(clippy::as_conversions)]
pub fn resolve(&self, id: StringId) -> Option<&str> {
self.symbols.get(id as usize).map(String::as_str)
}
#[must_use]
pub fn len(&self) -> usize {
self.symbols.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.symbols.is_empty()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct EdgeSymbol {
pub sid: SessionId,
pub sender: StringId,
pub receiver: StringId,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct EdgeSymbolTable {
symbols: Vec<EdgeSymbol>,
index: BTreeMap<EdgeSymbol, EdgeId>,
}
impl EdgeSymbolTable {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn intern(&mut self, sid: SessionId, sender: StringId, receiver: StringId) -> EdgeId {
let edge = EdgeSymbol {
sid,
sender,
receiver,
};
if let Some(id) = self.index.get(&edge) {
return *id;
}
let id = match u32::try_from(self.symbols.len()) {
Ok(id) => id,
Err(_) => return u32::MAX,
};
self.symbols.push(edge);
self.index.insert(edge, id);
id
}
#[must_use]
#[allow(clippy::as_conversions)]
pub fn resolve(&self, id: EdgeId) -> Option<EdgeSymbol> {
self.symbols.get(id as usize).copied()
}
#[must_use]
pub fn len(&self) -> usize {
self.symbols.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.symbols.is_empty()
}
}