1use crate::{
6 config::Config, file::LEVELS_MANIFEST_FILE, level_manifest::LevelManifest, memtable::Memtable,
7 segment::meta::SegmentId, stop_signal::StopSignal,
8};
9use std::sync::{atomic::AtomicU64, Arc, RwLock};
10
11pub type TreeId = u64;
15
16pub type MemtableId = u64;
20
21#[derive(Default)]
26pub struct SealedMemtables(Vec<(MemtableId, Arc<Memtable>)>);
27
28impl SealedMemtables {
29 pub fn add(&mut self, id: MemtableId, memtable: Arc<Memtable>) {
30 self.0.push((id, memtable));
31 }
32
33 pub fn remove(&mut self, id_to_remove: MemtableId) {
34 self.0.retain(|(id, _)| *id != id_to_remove);
35 }
36
37 pub fn iter(&self) -> impl DoubleEndedIterator<Item = &(MemtableId, Arc<Memtable>)> {
38 self.0.iter()
39 }
40
41 pub fn len(&self) -> usize {
42 self.0.len()
43 }
44}
45
46pub fn get_next_tree_id() -> TreeId {
48 static TREE_ID_COUNTER: AtomicU64 = AtomicU64::new(0);
49 TREE_ID_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
50}
51
52#[allow(clippy::module_name_repetitions)]
53pub struct TreeInner {
54 pub id: TreeId,
56
57 #[doc(hidden)]
59 pub segment_id_counter: Arc<AtomicU64>,
60
61 pub(crate) active_memtable: Arc<RwLock<Arc<Memtable>>>,
63
64 pub(crate) sealed_memtables: Arc<RwLock<SealedMemtables>>,
66
67 #[doc(hidden)]
69 pub levels: Arc<RwLock<LevelManifest>>,
70
71 pub config: Config,
73
74 pub(crate) stop_signal: StopSignal,
77
78 pub(crate) major_compaction_lock: RwLock<()>,
79}
80
81impl TreeInner {
82 pub(crate) fn create_new(config: Config) -> crate::Result<Self> {
83 let levels =
84 LevelManifest::create_new(config.level_count, config.path.join(LEVELS_MANIFEST_FILE))?;
85
86 Ok(Self {
87 id: get_next_tree_id(),
88 segment_id_counter: Arc::new(AtomicU64::default()),
89 config,
90 active_memtable: Arc::default(),
91 sealed_memtables: Arc::default(),
92 levels: Arc::new(RwLock::new(levels)),
93 stop_signal: StopSignal::default(),
94 major_compaction_lock: RwLock::default(),
95 })
96 }
97
98 pub fn get_next_segment_id(&self) -> SegmentId {
99 self.segment_id_counter
100 .fetch_add(1, std::sync::atomic::Ordering::Relaxed)
101 }
102}
103
104impl Drop for TreeInner {
105 fn drop(&mut self) {
106 log::debug!("Dropping TreeInner");
107
108 log::trace!("Sending stop signal to compactors");
109 self.stop_signal.send();
110 }
111}