1use std::sync::{Mutex as StdMutex, RwLock};
2
3use crossbeam_channel as xchan;
4
5use crate::bplus_tree::BPlusTree;
6use crate::codecs::{IdCodec, KeyCodec};
7use crate::errors::Error;
8use crate::iter::{BPlusTreeIter, ScanOpts};
9use crate::node_cache::NodeCache;
10use crate::pager::Pager;
11use crate::traits::BTree;
12use std::sync::Arc;
13
14pub struct SharedBPlusTree<P, KC, IC>
17where
18 P: Pager + Clone,
19 P::Page: Send + Sync + 'static,
20 P::Id: Send + Sync + 'static,
21 KC: KeyCodec,
22 IC: IdCodec<Id = P::Id>,
23{
24 pager: P,
25 writer: StdMutex<BPlusTree<P, KC, IC>>, latest_root: RwLock<P::Id>, shared_node_cache: Arc<RwLock<NodeCache<P>>>,
28 page_size: usize,
30}
31
32impl<P, KC, IC> SharedBPlusTree<P, KC, IC>
33where
34 P: Pager + Clone,
35 P::Page: Send + Sync + 'static,
36 P::Id: Send + Sync + 'static,
37 KC: KeyCodec,
38 IC: IdCodec<Id = P::Id>,
39{
40 pub fn create_empty(
42 pager: P,
43 opt_shared_node_cache: Option<Arc<RwLock<NodeCache<P>>>>,
44 ) -> Result<Self, Error> {
45 let shared_node_cache = BPlusTree::<P, KC, IC>::init_node_cache(opt_shared_node_cache);
46
47 let writer = BPlusTree::<P, KC, IC>::create_empty(
48 pager.clone(),
49 Some(Arc::clone(&shared_node_cache)),
50 )?;
51 let root = writer.root_id();
52 let page_size = writer.page_size();
53
54 Ok(Self {
55 pager,
56 writer: StdMutex::new(writer),
57 latest_root: RwLock::new(root),
58 shared_node_cache,
59 page_size,
60 })
61 }
62
63 pub fn open(
65 pager: P,
66 root: P::Id,
67 opt_shared_node_cache: Option<Arc<RwLock<NodeCache<P>>>>,
68 ) -> Self {
69 let shared_node_cache = BPlusTree::<P, KC, IC>::init_node_cache(opt_shared_node_cache);
70
71 let writer = BPlusTree::<P, KC, IC>::new(
72 pager.clone(),
73 root.clone(),
74 Some(Arc::clone(&shared_node_cache)),
75 );
76 let page_size = writer.page_size();
77
78 Self {
79 pager,
80 writer: StdMutex::new(writer),
81 latest_root: RwLock::new(root),
82 shared_node_cache,
83 page_size,
84 }
85 }
86
87 pub fn snapshot(&self) -> BPlusTree<P, KC, IC> {
90 let root = { self.latest_root.read().unwrap().clone() };
91 let shared_node_cache = Arc::clone(&self.shared_node_cache);
92
93 BPlusTree::<P, KC, IC>::with_readonly_pager_state(
94 self.pager.clone(),
95 root,
96 shared_node_cache,
97 self.page_size,
98 )
99 }
100
101 pub fn start_stream_with_opts(
110 &self,
111 opts: ScanOpts<'static, KC>,
112 ) -> xchan::Receiver<(KC::Key, Vec<u8>)>
113 where
114 P: Send + 'static,
116 P::Id: Send + 'static,
117 KC: KeyCodec + 'static,
118 KC::Key: Send + Sync + 'static,
119 IC: IdCodec<Id = P::Id> + 'static,
120 {
121 let root = { self.latest_root.read().unwrap().clone() };
122 let pager = self.pager.clone();
123
124 let (tx, rx) = xchan::bounded(1);
126
127 let shared_node_cache = Arc::clone(&self.shared_node_cache);
128 let page_size = self.page_size;
129
130 rayon::spawn(move || {
131 let tree = BPlusTree::<P, KC, IC>::with_readonly_pager_state(
132 pager,
133 root,
134 shared_node_cache,
135 page_size,
136 );
137 if let Ok(it) = BPlusTreeIter::with_opts(&tree, opts) {
138 for (kref, vref) in it {
139 let key = KC::decode_from(kref.as_ref()).expect("decode key");
140 let val = vref.as_ref().to_vec();
141 if tx.send((key, val)).is_err() {
142 break;
143 }
144 }
146 }
147 });
149
150 rx
151 }
152
153 }
161
162impl<'a, P, KC, IC> BTree<'a, KC::Key> for SharedBPlusTree<P, KC, IC>
165where
166 P: Pager + Clone + 'a,
167 P::Page: Send + Sync + 'static,
168 P::Id: Send + Sync + 'static,
169 KC: KeyCodec + 'a,
170 IC: IdCodec<Id = P::Id> + 'a,
171{
172 type Value = <BPlusTree<P, KC, IC> as BTree<'a, KC::Key>>::Value;
173
174 fn get_many(&'a self, keys: &[KC::Key]) -> Result<Vec<Option<Self::Value>>, Error> {
175 self.snapshot().get_many(keys)
176 }
177
178 fn contains_key(&'a self, key: &KC::Key) -> Result<bool, Error> {
179 self.snapshot().contains_key(key)
180 }
181
182 fn insert_many(&self, items: &[(KC::Key, &[u8])]) -> Result<(), Error>
183 where
184 KC::Key: Clone,
185 {
186 let new_root = {
189 let w = self.writer.lock().unwrap();
190 w.insert_many(items)?;
191 w.flush()?;
192 w.root_id()
193 };
194 *self.latest_root.write().unwrap() = new_root;
195 Ok(())
196 }
197
198 fn delete_many(&self, keys: &[KC::Key]) -> Result<(), Error>
199 where
200 KC::Key: Clone,
201 {
202 let new_root = {
203 let w = self.writer.lock().unwrap();
204 w.delete_many(keys)?;
205 w.flush()?;
206 w.root_id()
207 };
208 *self.latest_root.write().unwrap() = new_root;
209 Ok(())
210 }
211}