use super::types::{IndexMap, PropertiesMap};
use super::{MemoryIndex, MemoryState};
use crate::features::{FeaturePattern, FeatureRelationship, PersistentFeature};
use eryon::LearnedRule;
use std::collections::hash_map::{self, HashMap};
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Deserialize, serde_derive::Serialize)
)]
pub struct TopoLedger<T = f32> {
pub(crate) features: Vec<PersistentFeature<T>>,
pub(crate) index: MemoryIndex,
pub(crate) relationships: Vec<FeatureRelationship<T>>,
pub(crate) rulespace: Vec<LearnedRule<T, usize, usize>>,
pub(crate) patterns: Vec<FeaturePattern<T>>,
pub(crate) properties: HashMap<String, String>,
pub(crate) state: MemoryState,
}
impl<T> TopoLedger<T> {
pub fn new() -> Self {
Self {
features: Vec::new(),
index: MemoryIndex::new(),
patterns: Vec::new(),
properties: PropertiesMap::new(),
relationships: Vec::new(),
rulespace: Vec::new(),
state: MemoryState::new(),
}
}
pub const fn features(&self) -> &Vec<PersistentFeature<T>> {
&self.features
}
pub const fn features_mut(&mut self) -> &mut Vec<PersistentFeature<T>> {
&mut self.features
}
pub const fn index(&self) -> &MemoryIndex {
&self.index
}
pub const fn index_mut(&mut self) -> &mut MemoryIndex {
&mut self.index
}
pub const fn patterns(&self) -> &Vec<FeaturePattern<T>> {
&self.patterns
}
pub const fn patterns_mut(&mut self) -> &mut Vec<FeaturePattern<T>> {
&mut self.patterns
}
pub const fn properties(&self) -> &HashMap<String, String> {
&self.properties
}
pub const fn properties_mut(&mut self) -> &mut HashMap<String, String> {
&mut self.properties
}
pub const fn relationships(&self) -> &Vec<FeatureRelationship<T>> {
&self.relationships
}
pub const fn relationships_mut(&mut self) -> &mut Vec<FeatureRelationship<T>> {
&mut self.relationships
}
pub const fn rulespace(&self) -> &Vec<LearnedRule<T>> {
&self.rulespace
}
pub const fn rulespace_mut(&mut self) -> &mut Vec<LearnedRule<T>> {
&mut self.rulespace
}
pub const fn state(&self) -> MemoryState {
self.state
}
pub const fn state_mut(&mut self) -> &mut MemoryState {
&mut self.state
}
pub const fn content_index(&self) -> &IndexMap<Vec<usize>, usize> {
self.index().content_index()
}
pub const fn content_index_mut(&mut self) -> &mut IndexMap<Vec<usize>, usize> {
self.index_mut().content_index_mut()
}
pub const fn dimension_index(&self) -> &IndexMap<usize, usize> {
self.index().dimension_index()
}
pub const fn dimension_index_mut(&mut self) -> &mut IndexMap<usize, usize> {
self.index_mut().dimension_index_mut()
}
pub const fn importance_index(&self) -> &IndexMap<usize, usize> {
self.index().importance_index()
}
pub const fn importance_index_mut(&mut self) -> &mut IndexMap<usize, usize> {
self.index_mut().importance_index_mut()
}
#[inline]
pub fn count_features(&self) -> usize {
self.features().len()
}
#[inline]
pub fn count_patterns(&self) -> usize {
self.patterns().len()
}
#[inline]
pub fn count_relationships(&self) -> usize {
self.relationships().len()
}
pub fn get_property<Q>(&self, key: &Q) -> Option<&String>
where
Q: Eq + core::hash::Hash + ?Sized,
String: core::borrow::Borrow<Q>,
{
self.properties().get(key)
}
pub fn get_property_float<Q>(&self, key: &Q) -> Option<T>
where
Q: Eq + core::hash::Hash + ?Sized,
T: num_traits::Num,
String: core::borrow::Borrow<Q>,
{
self.get_property(key)
.and_then(|v| T::from_str_radix(v, 10).ok())
}
pub const fn current_epoch(&self) -> usize {
self.state().epoch()
}
pub fn next_epoch(&mut self) -> usize {
self.state_mut().next_epoch()
}
pub fn next_feature_id(&mut self) -> usize {
self.state_mut().next_feature_id()
}
pub fn next_pattern_id(&mut self) -> usize {
self.state_mut().next_pattern_id()
}
pub fn property<K: ToString>(&mut self, key: K) -> hash_map::Entry<'_, String, String> {
self.properties_mut().entry(key.to_string())
}
pub fn set_property<V>(&mut self, key: &str, value: V)
where
V: ToString,
{
self.properties_mut()
.insert(key.to_string(), value.to_string());
}
}
impl<T> Default for TopoLedger<T> {
fn default() -> Self {
Self::new()
}
}