1use crate::sealed::Sealed;
2use crate::tree_store::{
3 AccessGuardMut, Btree, BtreeDrain, BtreeDrainFilter, BtreeMut, BtreeRangeIter, Checksum,
4 PageHint, PageNumber, RawBtree, TransactionalMemory, MAX_VALUE_LENGTH,
5};
6use crate::types::{MutInPlaceValue, RedbKey, RedbValue};
7use crate::{AccessGuard, StorageError, WriteTransaction};
8use crate::{Result, TableHandle};
9use std::borrow::Borrow;
10use std::fmt::{Debug, Formatter};
11use std::ops::RangeBounds;
12use std::sync::{Arc, Mutex};
13
14#[derive(Debug)]
16pub struct TableStats {
17 pub(crate) tree_height: u32,
18 pub(crate) leaf_pages: u64,
19 pub(crate) branch_pages: u64,
20 pub(crate) stored_leaf_bytes: u64,
21 pub(crate) metadata_bytes: u64,
22 pub(crate) fragmented_bytes: u64,
23}
24
25impl TableStats {
26 pub fn tree_height(&self) -> u32 {
28 self.tree_height
29 }
30
31 pub fn leaf_pages(&self) -> u64 {
33 self.leaf_pages
34 }
35
36 pub fn branch_pages(&self) -> u64 {
38 self.branch_pages
39 }
40
41 pub fn stored_bytes(&self) -> u64 {
44 self.stored_leaf_bytes
45 }
46
47 pub fn metadata_bytes(&self) -> u64 {
49 self.metadata_bytes
50 }
51
52 pub fn fragmented_bytes(&self) -> u64 {
54 self.fragmented_bytes
55 }
56}
57
58pub struct Table<'db, 'txn, K: RedbKey + 'static, V: RedbValue + 'static> {
60 name: String,
61 transaction: &'txn WriteTransaction<'db>,
62 tree: BtreeMut<'txn, K, V>,
63}
64
65impl<K: RedbKey + 'static, V: RedbValue + 'static> TableHandle for Table<'_, '_, K, V> {
66 fn name(&self) -> &str {
67 &self.name
68 }
69}
70
71impl<'db, 'txn, K: RedbKey + 'static, V: RedbValue + 'static> Table<'db, 'txn, K, V> {
72 pub(crate) fn new(
73 name: &str,
74 table_root: Option<(PageNumber, Checksum)>,
75 freed_pages: Arc<Mutex<Vec<PageNumber>>>,
76 mem: &'db TransactionalMemory,
77 transaction: &'txn WriteTransaction<'db>,
78 ) -> Table<'db, 'txn, K, V> {
79 Table {
80 name: name.to_string(),
81 transaction,
82 tree: BtreeMut::new(table_root, mem, freed_pages),
83 }
84 }
85
86 #[allow(dead_code)]
87 pub(crate) fn print_debug(&self, include_values: bool) -> Result {
88 self.tree.print_debug(include_values)
89 }
90
91 pub fn pop_first(&mut self) -> Result<Option<(AccessGuard<K>, AccessGuard<V>)>> {
93 let first = self
95 .iter()?
96 .next()
97 .map(|x| x.map(|(key, _)| K::as_bytes(&key.value()).as_ref().to_vec()));
98 if let Some(owned_key) = first {
99 let owned_key = owned_key?;
100 let key = K::from_bytes(&owned_key);
101 let value = self.remove(&key)?.unwrap();
102 drop(key);
103 Ok(Some((AccessGuard::with_owned_value(owned_key), value)))
104 } else {
105 Ok(None)
106 }
107 }
108
109 pub fn pop_last(&mut self) -> Result<Option<(AccessGuard<K>, AccessGuard<V>)>> {
111 let last = self
113 .iter()?
114 .next_back()
115 .map(|x| x.map(|(key, _)| K::as_bytes(&key.value()).as_ref().to_vec()));
116 if let Some(owned_key) = last {
117 let owned_key = owned_key?;
118 let key = K::from_bytes(&owned_key);
119 let value = self.remove(&key)?.unwrap();
120 drop(key);
121 Ok(Some((AccessGuard::with_owned_value(owned_key), value)))
122 } else {
123 Ok(None)
124 }
125 }
126
127 pub fn drain<'a, KR>(&mut self, range: impl RangeBounds<KR> + 'a) -> Result<Drain<K, V>>
131 where
132 K: 'a,
133 KR: Borrow<K::SelfType<'a>> + 'a,
134 {
135 self.tree.drain(&range).map(Drain::new)
136 }
137
138 pub fn drain_filter<'a, KR, F: for<'f> Fn(K::SelfType<'f>, V::SelfType<'f>) -> bool>(
143 &mut self,
144 range: impl RangeBounds<KR> + 'a,
145 predicate: F,
146 ) -> Result<DrainFilter<K, V, F>>
147 where
148 K: 'a,
149 KR: Borrow<K::SelfType<'a>> + 'a,
150 {
151 self.tree
152 .drain_filter(&range, predicate)
153 .map(DrainFilter::new)
154 }
155
156 pub fn insert<'k, 'v>(
160 &mut self,
161 key: impl Borrow<K::SelfType<'k>>,
162 value: impl Borrow<V::SelfType<'v>>,
163 ) -> Result<Option<AccessGuard<V>>> {
164 let value_len = V::as_bytes(value.borrow()).as_ref().len();
165 if value_len > MAX_VALUE_LENGTH {
166 return Err(StorageError::ValueTooLarge(value_len));
167 }
168 let key_len = K::as_bytes(key.borrow()).as_ref().len();
169 if key_len > MAX_VALUE_LENGTH {
170 return Err(StorageError::ValueTooLarge(key_len));
171 }
172 self.tree.insert(key.borrow(), value.borrow())
173 }
174
175 pub fn remove<'a>(
179 &mut self,
180 key: impl Borrow<K::SelfType<'a>>,
181 ) -> Result<Option<AccessGuard<V>>>
182 where
183 K: 'a,
184 {
185 self.tree.remove(key.borrow())
186 }
187}
188
189impl<'db, 'txn, K: RedbKey + 'static, V: MutInPlaceValue + 'static> Table<'db, 'txn, K, V> {
190 pub fn insert_reserve<'a>(
193 &mut self,
194 key: impl Borrow<K::SelfType<'a>>,
195 value_length: u32,
196 ) -> Result<AccessGuardMut<V>>
197 where
198 K: 'a,
199 {
200 if value_length as usize > MAX_VALUE_LENGTH {
201 return Err(StorageError::ValueTooLarge(value_length as usize));
202 }
203 let key_len = K::as_bytes(key.borrow()).as_ref().len();
204 if key_len > MAX_VALUE_LENGTH {
205 return Err(StorageError::ValueTooLarge(key_len));
206 }
207 self.tree.insert_reserve(key.borrow(), value_length)
208 }
209}
210
211impl<'db, 'txn, K: RedbKey + 'static, V: RedbValue + 'static> ReadableTable<K, V>
212 for Table<'db, 'txn, K, V>
213{
214 fn get<'a>(&self, key: impl Borrow<K::SelfType<'a>>) -> Result<Option<AccessGuard<V>>>
215 where
216 K: 'a,
217 {
218 self.tree.get(key.borrow())
219 }
220
221 fn range<'a, KR>(&self, range: impl RangeBounds<KR> + 'a) -> Result<Range<K, V>>
222 where
223 K: 'a,
224 KR: Borrow<K::SelfType<'a>> + 'a,
225 {
226 self.tree.range(&range).map(Range::new)
227 }
228
229 fn stats(&self) -> Result<TableStats> {
230 let tree_stats = self.tree.stats()?;
231
232 Ok(TableStats {
233 tree_height: tree_stats.tree_height,
234 leaf_pages: tree_stats.leaf_pages,
235 branch_pages: tree_stats.branch_pages,
236 stored_leaf_bytes: tree_stats.stored_leaf_bytes,
237 metadata_bytes: tree_stats.metadata_bytes,
238 fragmented_bytes: tree_stats.fragmented_bytes,
239 })
240 }
241
242 fn len(&self) -> Result<u64> {
243 self.tree.len()
244 }
245
246 fn is_empty(&self) -> Result<bool> {
247 self.len().map(|x| x == 0)
248 }
249}
250
251impl<K: RedbKey, V: RedbValue> Sealed for Table<'_, '_, K, V> {}
252
253impl<'db, 'txn, K: RedbKey + 'static, V: RedbValue + 'static> Drop for Table<'db, 'txn, K, V> {
254 fn drop(&mut self) {
255 self.transaction.close_table(&self.name, &self.tree);
256 }
257}
258
259fn debug_helper<K: RedbKey + 'static, V: RedbValue + 'static>(
260 f: &mut Formatter<'_>,
261 name: &str,
262 len: Result<u64>,
263 first: Result<Option<(AccessGuard<K>, AccessGuard<V>)>>,
264 last: Result<Option<(AccessGuard<K>, AccessGuard<V>)>>,
265) -> std::fmt::Result {
266 write!(f, "Table [ name: \"{}\", ", name)?;
267 if let Ok(len) = len {
268 if len == 0 {
269 write!(f, "No entries")?;
270 } else if len == 1 {
271 if let Ok(first) = first {
272 let (key, value) = first.as_ref().unwrap();
273 write!(f, "One key-value: {:?} = {:?}", key.value(), value.value())?;
274 } else {
275 write!(f, "I/O Error accessing table!")?;
276 }
277 } else {
278 if let Ok(first) = first {
279 let (key, value) = first.as_ref().unwrap();
280 write!(f, "first: {:?} = {:?}, ", key.value(), value.value())?;
281 } else {
282 write!(f, "I/O Error accessing table!")?;
283 }
284 if len > 2 {
285 write!(f, "...{} more entries..., ", len - 2)?;
286 }
287 if let Ok(last) = last {
288 let (key, value) = last.as_ref().unwrap();
289 write!(f, "last: {:?} = {:?}", key.value(), value.value())?;
290 } else {
291 write!(f, "I/O Error accessing table!")?;
292 }
293 }
294 } else {
295 write!(f, "I/O Error accessing table!")?;
296 }
297 write!(f, " ]")?;
298
299 Ok(())
300}
301
302impl<K: RedbKey + 'static, V: RedbValue + 'static> Debug for Table<'_, '_, K, V> {
303 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
304 debug_helper(f, &self.name, self.len(), self.first(), self.last())
305 }
306}
307
308pub trait ReadableTable<K: RedbKey + 'static, V: RedbValue + 'static>: Sealed {
309 fn get<'a>(&self, key: impl Borrow<K::SelfType<'a>>) -> Result<Option<AccessGuard<V>>>
311 where
312 K: 'a;
313
314 fn range<'a, KR>(&self, range: impl RangeBounds<KR> + 'a) -> Result<Range<K, V>>
347 where
348 K: 'a,
349 KR: Borrow<K::SelfType<'a>> + 'a;
350
351 fn first(&self) -> Result<Option<(AccessGuard<K>, AccessGuard<V>)>> {
353 self.iter()?.next().transpose()
354 }
355
356 fn last(&self) -> Result<Option<(AccessGuard<K>, AccessGuard<V>)>> {
358 self.iter()?.next_back().transpose()
359 }
360
361 fn stats(&self) -> Result<TableStats>;
363
364 fn len(&self) -> Result<u64>;
366
367 fn is_empty(&self) -> Result<bool>;
369
370 fn iter(&self) -> Result<Range<K, V>> {
372 self.range::<K::SelfType<'_>>(..)
373 }
374}
375
376pub struct ReadOnlyUntypedTable<'txn> {
378 tree: RawBtree<'txn>,
379}
380
381impl<'txn> ReadOnlyUntypedTable<'txn> {
382 pub(crate) fn new(
383 root_page: Option<(PageNumber, Checksum)>,
384 fixed_key_size: Option<usize>,
385 fixed_value_size: Option<usize>,
386 mem: &'txn TransactionalMemory,
387 ) -> Self {
388 Self {
389 tree: RawBtree::new(root_page, fixed_key_size, fixed_value_size, mem),
390 }
391 }
392
393 pub fn stats(&self) -> Result<TableStats> {
395 let tree_stats = self.tree.stats()?;
396
397 Ok(TableStats {
398 tree_height: tree_stats.tree_height,
399 leaf_pages: tree_stats.leaf_pages,
400 branch_pages: tree_stats.branch_pages,
401 stored_leaf_bytes: tree_stats.stored_leaf_bytes,
402 metadata_bytes: tree_stats.metadata_bytes,
403 fragmented_bytes: tree_stats.fragmented_bytes,
404 })
405 }
406}
407
408pub struct ReadOnlyTable<'txn, K: RedbKey + 'static, V: RedbValue + 'static> {
410 name: String,
411 tree: Btree<'txn, K, V>,
412}
413
414impl<'txn, K: RedbKey + 'static, V: RedbValue + 'static> ReadOnlyTable<'txn, K, V> {
415 pub(crate) fn new(
416 name: String,
417 root_page: Option<(PageNumber, Checksum)>,
418 hint: PageHint,
419 mem: &'txn TransactionalMemory,
420 ) -> Result<ReadOnlyTable<'txn, K, V>> {
421 Ok(ReadOnlyTable {
422 name,
423 tree: Btree::new(root_page, hint, mem)?,
424 })
425 }
426}
427
428impl<'txn, K: RedbKey + 'static, V: RedbValue + 'static> ReadableTable<K, V>
429 for ReadOnlyTable<'txn, K, V>
430{
431 fn get<'a>(&self, key: impl Borrow<K::SelfType<'a>>) -> Result<Option<AccessGuard<V>>>
432 where
433 K: 'a,
434 {
435 self.tree.get(key.borrow())
436 }
437
438 fn range<'a, KR>(&self, range: impl RangeBounds<KR> + 'a) -> Result<Range<K, V>>
439 where
440 K: 'a,
441 KR: Borrow<K::SelfType<'a>> + 'a,
442 {
443 self.tree.range(&range).map(Range::new)
444 }
445
446 fn stats(&self) -> Result<TableStats> {
447 let tree_stats = self.tree.stats()?;
448
449 Ok(TableStats {
450 tree_height: tree_stats.tree_height,
451 leaf_pages: tree_stats.leaf_pages,
452 branch_pages: tree_stats.branch_pages,
453 stored_leaf_bytes: tree_stats.stored_leaf_bytes,
454 metadata_bytes: tree_stats.metadata_bytes,
455 fragmented_bytes: tree_stats.fragmented_bytes,
456 })
457 }
458
459 fn len(&self) -> Result<u64> {
460 self.tree.len()
461 }
462
463 fn is_empty(&self) -> Result<bool> {
464 self.len().map(|x| x == 0)
465 }
466}
467
468impl<K: RedbKey, V: RedbValue> Sealed for ReadOnlyTable<'_, K, V> {}
469
470impl<K: RedbKey + 'static, V: RedbValue + 'static> Debug for ReadOnlyTable<'_, K, V> {
471 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
472 debug_helper(f, &self.name, self.len(), self.first(), self.last())
473 }
474}
475
476pub struct Drain<'a, K: RedbKey + 'static, V: RedbValue + 'static> {
477 inner: BtreeDrain<'a, K, V>,
478}
479
480impl<'a, K: RedbKey + 'static, V: RedbValue + 'static> Drain<'a, K, V> {
481 fn new(inner: BtreeDrain<'a, K, V>) -> Self {
482 Self { inner }
483 }
484}
485
486impl<'a, K: RedbKey + 'static, V: RedbValue + 'static> Iterator for Drain<'a, K, V> {
487 type Item = Result<(AccessGuard<'a, K>, AccessGuard<'a, V>)>;
488
489 fn next(&mut self) -> Option<Self::Item> {
490 let entry = self.inner.next()?;
491 Some(entry.map(|entry| {
492 let (page, key_range, value_range) = entry.into_raw();
493 let key = AccessGuard::with_page(page.clone(), key_range);
494 let value = AccessGuard::with_page(page, value_range);
495 (key, value)
496 }))
497 }
498}
499
500impl<'a, K: RedbKey + 'static, V: RedbValue + 'static> DoubleEndedIterator for Drain<'a, K, V> {
501 fn next_back(&mut self) -> Option<Self::Item> {
502 let entry = self.inner.next_back()?;
503 Some(entry.map(|entry| {
504 let (page, key_range, value_range) = entry.into_raw();
505 let key = AccessGuard::with_page(page.clone(), key_range);
506 let value = AccessGuard::with_page(page, value_range);
507 (key, value)
508 }))
509 }
510}
511
512pub struct DrainFilter<
513 'a,
514 K: RedbKey + 'static,
515 V: RedbValue + 'static,
516 F: for<'f> FnMut(K::SelfType<'f>, V::SelfType<'f>) -> bool,
517> {
518 inner: BtreeDrainFilter<'a, K, V, F>,
519}
520
521impl<
522 'a,
523 K: RedbKey + 'static,
524 V: RedbValue + 'static,
525 F: for<'f> FnMut(K::SelfType<'f>, V::SelfType<'f>) -> bool,
526 > DrainFilter<'a, K, V, F>
527{
528 fn new(inner: BtreeDrainFilter<'a, K, V, F>) -> Self {
529 Self { inner }
530 }
531}
532
533impl<
534 'a,
535 K: RedbKey + 'static,
536 V: RedbValue + 'static,
537 F: for<'f> FnMut(K::SelfType<'f>, V::SelfType<'f>) -> bool,
538 > Iterator for DrainFilter<'a, K, V, F>
539{
540 type Item = Result<(AccessGuard<'a, K>, AccessGuard<'a, V>)>;
541
542 fn next(&mut self) -> Option<Self::Item> {
543 let entry = self.inner.next()?;
544 Some(entry.map(|entry| {
545 let (page, key_range, value_range) = entry.into_raw();
546 let key = AccessGuard::with_page(page.clone(), key_range);
547 let value = AccessGuard::with_page(page, value_range);
548 (key, value)
549 }))
550 }
551}
552
553impl<
554 'a,
555 K: RedbKey + 'static,
556 V: RedbValue + 'static,
557 F: for<'f> FnMut(K::SelfType<'f>, V::SelfType<'f>) -> bool,
558 > DoubleEndedIterator for DrainFilter<'a, K, V, F>
559{
560 fn next_back(&mut self) -> Option<Self::Item> {
561 let entry = self.inner.next_back()?;
562 Some(entry.map(|entry| {
563 let (page, key_range, value_range) = entry.into_raw();
564 let key = AccessGuard::with_page(page.clone(), key_range);
565 let value = AccessGuard::with_page(page, value_range);
566 (key, value)
567 }))
568 }
569}
570
571pub struct Range<'a, K: RedbKey + 'static, V: RedbValue + 'static> {
572 inner: BtreeRangeIter<'a, K, V>,
573}
574
575impl<'a, K: RedbKey + 'static, V: RedbValue + 'static> Range<'a, K, V> {
576 pub(super) fn new(inner: BtreeRangeIter<'a, K, V>) -> Self {
577 Self { inner }
578 }
579}
580
581impl<'a, K: RedbKey + 'static, V: RedbValue + 'static> Iterator for Range<'a, K, V> {
582 type Item = Result<(AccessGuard<'a, K>, AccessGuard<'a, V>)>;
583
584 fn next(&mut self) -> Option<Self::Item> {
585 self.inner.next().map(|x| {
586 x.map(|entry| {
587 let (page, key_range, value_range) = entry.into_raw();
588 let key = AccessGuard::with_page(page.clone(), key_range);
589 let value = AccessGuard::with_page(page, value_range);
590 (key, value)
591 })
592 })
593 }
594}
595
596impl<'a, K: RedbKey + 'static, V: RedbValue + 'static> DoubleEndedIterator for Range<'a, K, V> {
597 fn next_back(&mut self) -> Option<Self::Item> {
598 self.inner.next_back().map(|x| {
599 x.map(|entry| {
600 let (page, key_range, value_range) = entry.into_raw();
601 let key = AccessGuard::with_page(page.clone(), key_range);
602 let value = AccessGuard::with_page(page, value_range);
603 (key, value)
604 })
605 })
606 }
607}