libblobd_direct/
pages.rs

1use bufpool::buf::Buf;
2use bufpool::BufPool;
3use off64::usz;
4use std::ops::Deref;
5use std::sync::Arc;
6use tracing::trace;
7
8pub(crate) struct Inner {
9  pub lpage_size_pow2: u8,
10  pub spage_size_pow2: u8,
11  pool: BufPool,
12}
13
14#[derive(Clone)]
15pub(crate) struct Pages(Arc<Inner>);
16
17#[allow(unused)]
18impl Pages {
19  pub fn new(spage_size_pow2: u8, lpage_size_pow2: u8) -> Self {
20    Self(Arc::new(Inner {
21      lpage_size_pow2,
22      spage_size_pow2,
23      pool: BufPool::with_alignment(1 << spage_size_pow2),
24    }))
25  }
26
27  pub fn lpage_size(&self) -> u64 {
28    1 << self.lpage_size_pow2
29  }
30
31  pub fn spage_size(&self) -> u64 {
32    1 << self.spage_size_pow2
33  }
34
35  /// `cap` must be a multiple of the spage size.
36  pub fn allocate(&self, cap: u64) -> Buf {
37    trace!(cap, "allocating buffer");
38    let res = self.pool.allocate(usz!(cap));
39    trace!(cap, "allocated buffer");
40    res
41  }
42
43  /// `len` must be a multiple of the spage size.
44  // Prefer this over `allocate_with_zeros` as it's extremely slow. If you need it, use `slow_allocate_with_zeros`.
45  pub fn allocate_uninitialised(&self, len: u64) -> Buf {
46    self.pool.allocate_uninitialised(usz!(len))
47  }
48
49  /// This is slow, so avoid it in hot paths.
50  pub fn slow_allocate_with_zeros(&self, len: u64) -> Buf {
51    self.pool.allocate_with_zeros(usz!(len))
52  }
53
54  /// `data.len()` must be a multiple of the spage size.
55  pub fn allocate_from_data(&self, data: &[u8]) -> Buf {
56    self.pool.allocate_from_data(data)
57  }
58}
59
60impl Deref for Pages {
61  type Target = Inner;
62
63  fn deref(&self) -> &Self::Target {
64    &self.0
65  }
66}