Skip to main content

lsm_tree/runtime_config/
pin.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026-present, Dmitry Prudnikov
3
4//! The hold a write keeps on the policy it resolved its dictionaries from.
5
6use super::RuntimeConfig;
7use alloc::sync::Arc;
8
9/// Keeps the dictionaries a write's files name out of a dictionary collection
10/// until those files are installed.
11///
12/// A write resolves its dictionary from the policy snapshot it started under,
13/// and a collection spares every dictionary a still-held snapshot names, however
14/// the policy has changed since. The pin is that hold, owned by the operation
15/// rather than its writers, since finishing a writer comes before the install:
16/// drop it only once the files it covers are part of the tree, from which point
17/// the files name the dictionary themselves. A flush and an ingestion carry it
18/// from where their files are finished to where they are installed; a
19/// compaction, which does both in one call, holds its snapshot directly. Always
20/// empty in builds without zstd, which have no dictionaries to collect.
21///
22/// It also holds the filter bytes the write took in the tree's filter budget,
23/// when the tree sizes its filters by probe load: dropped before the install,
24/// the budget would hand that room to another rewrite while the files that
25/// take it are about to join the tree.
26#[derive(Default)]
27#[must_use = "dropping the pin before the files are installed lets a collection take their dictionary"]
28pub struct WritePin {
29    snapshot: Option<Arc<RuntimeConfig>>,
30    filter_sizing: Option<crate::filter_budget::FilterPlan>,
31}
32
33impl WritePin {
34    /// A pin on the snapshot a write resolves its dictionaries from. Empty when
35    /// the snapshot names no dictionary: its files name none either, and an
36    /// update never records such a snapshot for a collection to consult.
37    #[cfg(zstd_any)]
38    pub(crate) fn new(snapshot: &Arc<RuntimeConfig>) -> Self {
39        Self {
40            snapshot: snapshot
41                .write_dict_ids(true)
42                .next()
43                .map(|_| Arc::clone(snapshot)),
44            filter_sizing: None,
45        }
46    }
47
48    /// A pin on the snapshot a write resolves its dictionaries from: empty, as
49    /// a build without zstd resolves none.
50    #[cfg(not(zstd_any))]
51    pub(crate) fn new(_snapshot: &Arc<RuntimeConfig>) -> Self {
52        Self::default()
53    }
54
55    /// Also holds the filter budget `sizing` reserved until the install.
56    pub(crate) fn with_filter_sizing(
57        mut self,
58        sizing: Option<crate::filter_budget::FilterPlan>,
59    ) -> Self {
60        self.filter_sizing = sizing;
61        self
62    }
63}
64
65impl core::fmt::Debug for WritePin {
66    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
67        f.debug_struct("WritePin")
68            .field("holds", &self.snapshot.is_some())
69            .field("filter_budget", &self.filter_sizing.is_some())
70            .finish()
71    }
72}