use std::collections::BTreeMap;
use super::Registry;
use crate::registry_core::identity::{NodeId, StableFaceId};
use std::sync::Arc;
#[derive(Clone, Debug, Default)]
pub struct RegistryIndex {
pub(super) by_id: BTreeMap<NodeId, String>,
pub(super) by_path: BTreeMap<String, NodeId>,
pub(super) by_kind: BTreeMap<String, Vec<NodeId>>,
pub(super) by_stable: BTreeMap<StableFaceId, Vec<NodeId>>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RegistryStorageStats {
pub pages: usize,
pub entries: usize,
pub shared_pages: usize,
}
impl RegistryIndex {
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.by_id.len()
}
}
impl Registry {
pub fn storage_stats(&self) -> super::RegistryStorageStats {
let entries_shared = Arc::strong_count(&self.entries) > 1;
super::RegistryStorageStats {
pages: super::entry_pages::ENTRY_PAGE_COUNT,
entries: self.entries.len(),
shared_pages: if entries_shared {
super::entry_pages::ENTRY_PAGE_COUNT
} else {
self.entries
.pages
.iter()
.filter(|page| Arc::strong_count(page) > 1)
.count()
},
}
}
pub fn index(&self) -> RegistryIndex {
let mut index = RegistryIndex::default();
self.fill_index(&mut index);
index
}
fn fill_index(&self, index: &mut RegistryIndex) {
index.by_id.insert(self.header.id, self.header.path.clone());
index
.by_path
.insert(self.header.path.clone(), self.header.id);
for entry in self.entries.values() {
let entry_path = format!("{}/{}", self.header.path, entry.info.registry_name);
index.by_id.insert(entry.info.id, entry_path.clone());
index.by_path.insert(entry_path, entry.info.id);
index
.by_kind
.entry(entry.info.kind.clone())
.or_default()
.push(entry.info.id);
if let Some(stable) = entry.info.explicit_stable_face_id() {
index
.by_stable
.entry(stable)
.or_default()
.push(entry.info.id);
}
if let Some(child) = &entry.child {
child.fill_index(index);
}
}
}
}