Skip to main content

lance_table/transaction/
prepare.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright The Lance Authors
3
4//! What a commit attempt settles about the index list before the manifest
5//! is built.
6//!
7//! The commit layer decides index validity; the manifest builder assembles.
8//! Once per attempt, against the manifest current at that attempt,
9//! [`Transaction::prepare_indices`](crate::transaction::Transaction::prepare_indices)
10//! reads the index list as it is, keeps that original list untouched, and
11//! derives a prepared list on which an in-place column rewrite has already
12//! withdrawn or pruned the coverage it invalidates (on a table with a tagged
13//! fragment reuse history along the lineage, on any other table by fragment
14//! id). The builder then applies the operation to the prepared list and
15//! publishes only the final list; the original list is what MemWAL coverage
16//! is compared against. Both lists are in-memory metadata of one attempt:
17//! nothing is copied on disk and a retry prepares afresh from the list it
18//! reads then.
19
20use crate::format::IndexMetadata;
21use crate::transaction::TaggedRewriteAssembly;
22use std::sync::Arc;
23
24/// What the commit path settled about the fragment reuse entry for one
25/// attempt. In-memory only, like the rewrite intent it carries.
26#[derive(Debug, Clone, Default)]
27#[non_exhaustive]
28pub enum FragReuseUpdate {
29    /// Nothing was prepared for the entry. A tagged entry arriving on a
30    /// `Rewrite`, or a `CreateIndex` touching a tagged entry, is refused:
31    /// without the commit path's derivation such a shape is a pre-assembled
32    /// snapshot that may splice away records a concurrent writer appended.
33    #[default]
34    None,
35    /// A `Rewrite` on a tagged history: the entry the commit path assembled
36    /// for THIS manifest, merging the records the operation's entry adds
37    /// onto the current entry and validating them.
38    Rewrite(Arc<TaggedRewriteAssembly>),
39    /// A trim of the tagged entry derived by the reuse index cleanup against
40    /// the current entry at commit time.
41    Trim,
42}
43
44/// The index lists of one commit attempt: the list as read from the
45/// manifest current at the attempt, the prepared list the builder starts
46/// from, and what was settled about the fragment reuse entry.
47///
48/// Only [`Transaction::prepare_indices`](crate::transaction::Transaction::prepare_indices)
49/// builds one, so a value always went through the tagged-table write gate
50/// and the unified withdrawal step; the manifest it was prepared against is
51/// recorded so the builder refuses a result carried over to another attempt.
52#[derive(Debug, Clone)]
53pub struct PreparedIndices {
54    manifest_version: Option<u64>,
55    original: Vec<IndexMetadata>,
56    prepared: Vec<IndexMetadata>,
57    frag_reuse: FragReuseUpdate,
58}
59
60impl PreparedIndices {
61    pub(crate) fn new(
62        manifest_version: Option<u64>,
63        original: Vec<IndexMetadata>,
64        prepared: Vec<IndexMetadata>,
65        frag_reuse: FragReuseUpdate,
66    ) -> Self {
67        Self {
68            manifest_version,
69            original,
70            prepared,
71            frag_reuse,
72        }
73    }
74
75    /// The version of the manifest the lists were prepared against; `None`
76    /// when the dataset is being created.
77    pub fn manifest_version(&self) -> Option<u64> {
78        self.manifest_version
79    }
80
81    /// The index list as read from the current manifest, never mutated.
82    pub fn original(&self) -> &[IndexMetadata] {
83        &self.original
84    }
85
86    /// The original list with the in-place rewrite step applied: the list
87    /// the manifest builder starts from.
88    pub fn prepared(&self) -> &[IndexMetadata] {
89        &self.prepared
90    }
91
92    /// What the commit path settled about the fragment reuse entry.
93    pub fn frag_reuse_update(&self) -> &FragReuseUpdate {
94        &self.frag_reuse
95    }
96
97    pub(crate) fn into_parts(self) -> (Vec<IndexMetadata>, Vec<IndexMetadata>, FragReuseUpdate) {
98        (self.original, self.prepared, self.frag_reuse)
99    }
100}