1use crate::*;
2
3#[derive(Clone, Debug, Eq, PartialEq, Default)]
6pub struct Meta {
7 pub(crate) inner: BTreeMap<IVec, PageId>,
8}
9
10impl Meta {
11 pub(crate) fn get_root(&self, table: &[u8]) -> Option<PageId> {
13 self.inner.get(table).cloned()
14 }
15
16 pub(crate) fn set_root(
18 &mut self,
19 name: IVec,
20 pid: PageId,
21 ) -> Option<PageId> {
22 self.inner.insert(name, pid)
23 }
24
25 pub(crate) fn del_root(&mut self, name: &[u8]) -> Option<PageId> {
27 self.inner.remove(name)
28 }
29
30 pub(crate) fn tenants(&self) -> BTreeMap<IVec, PageId> {
32 self.inner.clone()
33 }
34
35 pub(crate) fn rss(&self) -> u64 {
36 self.inner
37 .iter()
38 .map(|(k, _pid)| {
39 k.len() as u64 + std::mem::size_of::<PageId>() as u64
40 })
41 .sum()
42 }
43}
44
45pub(crate) fn open_tree<V>(
48 context: &Context,
49 raw_name: V,
50 guard: &Guard,
51) -> Result<Tree>
52where
53 V: Into<IVec>,
54{
55 let name = raw_name.into();
56
57 loop {
60 match context.pagecache.meta_pid_for_name(&name, guard) {
61 Ok(root_id) => {
62 return Ok(Tree(Arc::new(TreeInner {
63 tree_id: name,
64 context: context.clone(),
65 subscribers: Subscribers::default(),
66 root: AtomicU64::new(root_id),
67 merge_operator: RwLock::new(None),
68 })));
69 }
70 Err(Error::CollectionNotFound(_)) => {}
71 Err(other) => return Err(other),
72 }
73
74 let leaf = Node::default();
76 let (leaf_id, leaf_ptr) = context.pagecache.allocate(leaf, guard)?;
77
78 trace!(
79 "allocated pid {} for leaf in new_tree for namespace {:?}",
80 leaf_id,
81 name
82 );
83
84 let root = Node::new_root(leaf_id);
88 let (root_id, root_ptr) = context.pagecache.allocate(root, guard)?;
89
90 debug!("allocated pid {} for root of new_tree {:?}", root_id, name);
91
92 let res = context.pagecache.cas_root_in_meta(
93 &name,
94 None,
95 Some(root_id),
96 guard,
97 )?;
98
99 if res.is_err() {
100 let _ = context
103 .pagecache
104 .free(root_id, root_ptr, guard)?
105 .expect("could not free allocated page");
106 let _ = context
107 .pagecache
108 .free(leaf_id, leaf_ptr, guard)?
109 .expect("could not free allocated page");
110 continue;
111 }
112
113 return Ok(Tree(Arc::new(TreeInner {
114 tree_id: name,
115 subscribers: Subscribers::default(),
116 context: context.clone(),
117 root: AtomicU64::new(root_id),
118 merge_operator: RwLock::new(None),
119 })));
120 }
121}