icydb_core/db/registry/
registry.rs1use crate::{
2 db::{
3 data::DataStore,
4 index::IndexStore,
5 registry::{StoreAllocationIdentities, StoreHandle, StoreRegistryError},
6 schema::SchemaStore,
7 },
8 error::InternalError,
9};
10use std::{cell::RefCell, thread::LocalKey};
11
12#[derive(Default)]
22pub struct StoreRegistry {
23 stores: Vec<(&'static str, StoreHandle)>,
24}
25
26impl StoreRegistry {
27 #[must_use]
29 pub fn new() -> Self {
30 Self::default()
31 }
32
33 pub fn iter(&self) -> impl Iterator<Item = (&'static str, StoreHandle)> {
39 self.stores.iter().copied()
40 }
41
42 pub fn register_store(
44 &mut self,
45 name: &'static str,
46 data: &'static LocalKey<RefCell<DataStore>>,
47 index: &'static LocalKey<RefCell<IndexStore>>,
48 schema: &'static LocalKey<RefCell<SchemaStore>>,
49 ) -> Result<(), InternalError> {
50 self.register_store_with_allocations(
51 name,
52 data,
53 index,
54 schema,
55 StoreAllocationIdentities::absent(),
56 )
57 }
58
59 pub fn register_store_with_allocations(
62 &mut self,
63 name: &'static str,
64 data: &'static LocalKey<RefCell<DataStore>>,
65 index: &'static LocalKey<RefCell<IndexStore>>,
66 schema: &'static LocalKey<RefCell<SchemaStore>>,
67 allocations: StoreAllocationIdentities,
68 ) -> Result<(), InternalError> {
69 if self
70 .stores
71 .iter()
72 .any(|(existing_name, _)| *existing_name == name)
73 {
74 return Err(StoreRegistryError::StoreAlreadyRegistered(name.to_string()).into());
75 }
76
77 if let Some(existing_name) =
80 self.stores
81 .iter()
82 .find_map(|(existing_name, existing_handle)| {
83 (std::ptr::eq(existing_handle.data_store(), data)
84 && std::ptr::eq(existing_handle.index_store(), index)
85 && std::ptr::eq(existing_handle.schema_store(), schema))
86 .then_some(*existing_name)
87 })
88 {
89 return Err(StoreRegistryError::StoreHandleTripletAlreadyRegistered {
90 name: name.to_string(),
91 existing_name: existing_name.to_string(),
92 }
93 .into());
94 }
95
96 self.stores.push((
97 name,
98 StoreHandle::new_with_allocations(data, index, schema, allocations),
99 ));
100
101 Ok(())
102 }
103
104 pub fn try_get_store(&self, path: &str) -> Result<StoreHandle, InternalError> {
106 self.stores
107 .iter()
108 .find_map(|(existing_path, handle)| (*existing_path == path).then_some(*handle))
109 .ok_or_else(|| StoreRegistryError::StoreNotFound(path.to_string()).into())
110 }
111}