iceberg-cpp
Loading...
Searching...
No Matches
Classes | Public Member Functions | Protected Member Functions | Static Protected Member Functions | List of all members
iceberg::MergingSnapshotUpdate Class Reference

Abstract base class for merge-based snapshot write operations. More...

#include <merging_snapshot_update.h>

Inheritance diagram for iceberg::MergingSnapshotUpdate:
iceberg::SnapshotUpdate iceberg::PendingUpdate iceberg::ErrorCollector iceberg::DeleteFiles iceberg::MergeAppend iceberg::OverwriteFiles iceberg::RewriteFiles iceberg::RowDelta iceberg::TestMergeAppend iceberg::TestOverwriteUpdate

Public Member Functions

Result< std::vector< ManifestFile > > Apply (const TableMetadata &metadata_to_update, const std::shared_ptr< Snapshot > &snapshot) override
 Apply the update's changes to the given metadata and snapshot.
 
Status CleanUncommitted (const std::unordered_set< std::string > &committed) override
 Clean up any uncommitted manifests that were created.
 
std::unordered_map< std::string, std::string > Summary () override
 Get the summary map for this operation.
 
- Public Member Functions inherited from iceberg::SnapshotUpdate
Kind kind () const override
 Return the kind of this pending update.
 
bool IsRetryable () const override
 Whether this update can be retried after a commit conflict.
 
auto & DeleteWith (this auto &self, std::function< Status(const std::string &)> delete_func)
 Set a callback to delete files instead of the table's default.
 
auto & StageOnly (this auto &self)
 Stage a snapshot in table metadata, but do not make it current.
 
auto & ScanManifestsWith (this auto &self, Executor &executor)
 Configure an executor for manifest planning work.
 
auto & ToBranch (this auto &self, const std::string &branch)
 Perform operations on a particular branch.
 
auto & Set (this auto &self, const std::string &property, const std::string &value)
 Set a summary property in the snapshot produced by this update.
 
auto & WriteManifestsWith (this auto &self, Executor &executor, int32_t parallelism)
 Configure an executor and max writer count for writing new manifests.
 
Result< ApplyResultApply ()
 Apply the update's changes to create a new snapshot.
 
Status Finalize (Result< const TableMetadata * > commit_result) override
 Finalize the snapshot update, cleaning up any uncommitted files.
 
- Public Member Functions inherited from iceberg::PendingUpdate
virtual Status Commit ()
 Apply the pending changes and commit.
 
 PendingUpdate (const PendingUpdate &)=delete
 
PendingUpdateoperator= (const PendingUpdate &)=delete
 
 PendingUpdate (PendingUpdate &&) noexcept=default
 
PendingUpdateoperator= (PendingUpdate &&) noexcept=default
 
- Public Member Functions inherited from iceberg::ErrorCollector
 ErrorCollector (ErrorCollector &&)=default
 
ErrorCollectoroperator= (ErrorCollector &&)=default
 
 ErrorCollector (const ErrorCollector &)=default
 
ErrorCollectoroperator= (const ErrorCollector &)=default
 
template<typename... Args>
auto & AddError (this auto &self, ErrorKind kind, const std::format_string< Args... > fmt, Args &&... args)
 Add a specific error and return reference to derived class.
 
auto & AddError (this auto &self, Error err)
 Add an existing error object and return reference to derived class.
 
auto & AddError (this auto &self, std::unexpected< Error > err)
 Add an unexpected result's error and return reference to derived class.
 
bool has_errors () const
 Check if any errors have been collected.
 
size_t error_count () const
 Get the number of errors collected.
 
Status CheckErrors () const
 Check for accumulated errors and return them if any exist.
 
void ClearErrors ()
 Clear all accumulated errors.
 
const std::vector< Error > & errors () const
 Get read-only access to all collected errors.
 

Protected Member Functions

 MergingSnapshotUpdate (std::string table_name, std::shared_ptr< TransactionContext > ctx)
 Constructor; reads merge configuration from table properties.
 
Status AddDataFile (std::shared_ptr< DataFile > file)
 Stage a data file to be added to the table.
 
Status AddDeleteFile (std::shared_ptr< DataFile > file)
 Stage a delete file to be added to the table.
 
Status ValidateNewDeleteFile (const TableMetadata &metadata, const DataFile &file)
 Validate a delete file against the table format version rules.
 
Status AddDeleteFile (std::shared_ptr< DataFile > file, int64_t data_sequence_number)
 Stage a delete file with an explicit data sequence number.
 
Status AddManifest (ManifestFile manifest)
 Add all files in a pre-existing data manifest to the new snapshot.
 
Status DeleteDataFile (std::shared_ptr< DataFile > file)
 Register a data file (by object) to be deleted from the table.
 
Status DeleteDeleteFile (std::shared_ptr< DataFile > file)
 Register a delete file (by object) to be removed from the table.
 
Status DeleteByPath (std::string_view path)
 Register a data file path to be deleted from the table.
 
Status DeleteByRowFilter (std::shared_ptr< Expression > expr)
 Register an expression to delete matching rows.
 
Status DropPartition (int32_t spec_id, PartitionValues partition)
 Register a partition to be dropped.
 
void FailMissingDeletePaths ()
 Fail if any registered delete path is not found in any manifest.
 
void FailAnyDelete ()
 Fail if any manifest entry matches a delete condition.
 
void SetNewDataFilesDataSequenceNumber (int64_t sequence_number)
 Override the data sequence number assigned to all newly-added data files.
 
bool HasDataSequenceNumber () const
 Returns true if SetNewDataFilesDataSequenceNumber was called.
 
void CaseSensitive (bool case_sensitive)
 Set case sensitivity for row filter and expression evaluation.
 
bool IsCaseSensitive () const
 Returns true if case-sensitive matching is enabled (default: true).
 
bool AddsDataFiles () const
 Returns true if any data files have been staged for addition.
 
bool AddsDeleteFiles () const
 Returns true if any delete files have been staged for addition.
 
bool DeletesDataFiles () const
 Returns true if any data files have been registered for deletion.
 
bool DeletesDeleteFiles () const
 Returns true if any delete files have been registered for removal.
 
const std::shared_ptr< Expression > & RowFilter () const
 Returns the row-filter expression set via DeleteByRowFilter, or nullptr.
 
Result< std::shared_ptr< PartitionSpec > > DataSpec () const
 Returns the single partition spec for all staged data files.
 
std::vector< std::shared_ptr< DataFile > > AddedDataFiles () const
 Returns all data files staged for addition.
 
Status ValidateNoNewDeletesForDataFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, const DataFileSet &replaced_files, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io) const
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a delete file that covers a file in replaced_files.
 
Status ValidateAddedDVs (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, std::shared_ptr< Expression > conflict_filter, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io) const
 Return an error if a staged deletion vector conflicts with a deletion vector added since starting_snapshot_id.
 
- Protected Member Functions inherited from iceberg::SnapshotUpdate
 SnapshotUpdate (std::shared_ptr< TransactionContext > ctx)
 
Result< std::vector< ManifestFile > > WriteDataManifests (std::span< const std::shared_ptr< DataFile > > files, const std::shared_ptr< PartitionSpec > &spec, std::optional< int64_t > data_sequence_number=std::nullopt)
 Write data manifests for the given data files.
 
Result< std::vector< ManifestFile > > WriteDeleteManifests (std::span< const ContentFileWithSequenceNumber > files, const std::shared_ptr< PartitionSpec > &spec)
 
const std::string & target_branch () const
 
bool can_inherit_snapshot_id () const
 
const std::string & commit_uuid () const
 
int32_t manifest_count () const
 
int32_t attempt () const
 
int64_t target_manifest_size_bytes () const
 
virtual std::string operation ()=0
 A string that describes the action that produced the new snapshot.
 
virtual Status Validate (const TableMetadata &current_metadata, const std::shared_ptr< Snapshot > &snapshot)
 Validate the current metadata.
 
virtual bool CleanupAfterCommit () const
 Check if cleanup should happen after commit.
 
int64_t SnapshotId ()
 Get or generate the snapshot ID for the new snapshot.
 
Status DeleteFile (const std::string &path)
 Delete a file at the given path.
 
std::string ManifestPath ()
 
std::string ManifestListPath ()
 
SnapshotSummaryBuildersummary_builder ()
 
SnapshotSummaryBuilder BuildManifestCountSummary (std::span< const ManifestFile > manifests, int32_t replaced_manifests_count)
 
- Protected Member Functions inherited from iceberg::PendingUpdate
 PendingUpdate (std::shared_ptr< TransactionContext > ctx)
 
const TableMetadatabase () const
 

Static Protected Member Functions

static Status ValidateAddedDataFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, std::shared_ptr< Expression > filter, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io, bool case_sensitive=true)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a data file matching the given filter expression.
 
static Status ValidateAddedDataFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, const PartitionSet &partition_set, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a data file in any partition of the given partition set.
 
static Status ValidateDataFilesExist (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, const std::unordered_set< std::string > &file_paths, bool skip_deletes, std::shared_ptr< Expression > filter, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io, bool case_sensitive=true)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, removed a file whose path is in file_paths (and skip_deletes is false).
 
static Status ValidateNoNewDeletesForDataFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, const DataFileSet &replaced_files, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io, bool ignore_equality_deletes=false)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a delete file that covers a file in replaced_files.
 
static Status ValidateNoNewDeletesForDataFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, std::shared_ptr< Expression > data_filter, const DataFileSet &replaced_files, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io, bool case_sensitive=true)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a delete file matching the data filter that covers a file in replaced_files.
 
static Status ValidateNoNewDeleteFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, std::shared_ptr< Expression > data_filter, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io, bool case_sensitive=true)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a delete file matching the given row filter.
 
static Status ValidateNoNewDeleteFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, const PartitionSet &partition_set, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a delete file matching any partition in the given partition set.
 
static Status ValidateDeletedDataFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, std::shared_ptr< Expression > data_filter, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io, bool case_sensitive=true)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, deleted a data file matching the given row filter.
 
static Status ValidateDeletedDataFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, const PartitionSet &partition_set, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, deleted a data file in any partition of the given partition set.
 
static Result< std::unique_ptr< DeleteFileIndex > > AddedDeleteFiles (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, std::shared_ptr< Expression > data_filter, std::shared_ptr< PartitionSet > partition_set, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io, bool case_sensitive=true)
 Build a DeleteFileIndex of delete files added since starting_snapshot_id.
 
static Status ValidateAddedDVs (const TableMetadata &metadata, std::optional< int64_t > starting_snapshot_id, std::shared_ptr< Expression > conflict_filter, const std::unordered_set< std::string > &referenced_data_files, const std::shared_ptr< Snapshot > &parent, std::shared_ptr< FileIO > io, bool case_sensitive=true)
 Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a deletion vector that conflicts with DVs being written.
 

Additional Inherited Members

- Public Types inherited from iceberg::PendingUpdate
enum class  Kind : uint8_t {
  kExpireSnapshots , kSetSnapshot , kUpdateLocation , kUpdatePartitionSpec ,
  kUpdatePartitionStatistics , kUpdateProperties , kUpdateSchema , kUpdateSnapshot ,
  kUpdateSnapshotReference , kUpdateSortOrder , kUpdateStatistics
}
 
- Protected Attributes inherited from iceberg::SnapshotUpdate
SnapshotSummaryBuilder summary_
 
- Protected Attributes inherited from iceberg::PendingUpdate
std::shared_ptr< TransactionContextctx_
 
- Protected Attributes inherited from iceberg::ErrorCollector
std::vector< Errorerrors_
 

Detailed Description

Abstract base class for merge-based snapshot write operations.

This class is the C++ counterpart of Java's MergingSnapshotProducer. It provides the shared filter, write, and merge pipeline used by operations that accumulate file additions and deletions, produce a new Snapshot, and commit that snapshot as current. Commit conflicts are resolved by applying the same staged changes to the new latest snapshot and reattempting the commit.

Subclasses describe their changes by calling the protected primitive API and implement operation() to set the snapshot operation summary.

The Apply() pipeline:

  1. Filter data manifests (via data_filter_manager_)
  2. Compute min data sequence number and set up delete filter cleanup
  3. Filter delete manifests (via delete_filter_manager_)
  4. Write new data manifests (cached for commit retry)
  5. Write new delete manifests (cached for commit retry)
  6. Merge data manifests (via data_merge_manager_)
  7. Merge delete manifests (via delete_merge_manager_)

TODO(Guotao): Java MergingSnapshotProducer overrides updateEvent() to return a CreateSnapshotEvent(tableName, operation, snapshotId, sequenceNumber, summary) for commit listeners. The C++ update framework does not yet have an event notification mechanism, so this is intentionally not implemented here. Add it once an equivalent CreateSnapshotEvent / listener facility exists.

Member Function Documentation

◆ AddManifest()

Status iceberg::MergingSnapshotUpdate::AddManifest ( ManifestFile  manifest)
protected

Add all files in a pre-existing data manifest to the new snapshot.

The manifest must contain only appended data files. If snapshot ID inheritance is enabled and the manifest has no snapshot ID assigned, it is used directly; otherwise it is copied with the current snapshot ID.

◆ Apply()

Result< std::vector< ManifestFile > > iceberg::MergingSnapshotUpdate::Apply ( const TableMetadata metadata_to_update,
const std::shared_ptr< Snapshot > &  snapshot 
)
overridevirtual

Apply the update's changes to the given metadata and snapshot.

Parameters
metadata_to_updateThe base table metadata to apply changes to
snapshotSnapshot to apply the changes to
Returns
A vector of manifest files for the new snapshot

Implements iceberg::SnapshotUpdate.

◆ CleanUncommitted()

Status iceberg::MergingSnapshotUpdate::CleanUncommitted ( const std::unordered_set< std::string > &  committed)
overridevirtual

Clean up any uncommitted manifests that were created.

Manifests may not be committed if Apply is called multiple times because a commit conflict has occurred. Implementations may keep around manifests because the same changes will be made by both Apply calls. This method instructs the implementation to clean up those manifests and passes the paths of the manifests that were actually committed.

Parameters
committedA set of manifest paths that were actually committed

Implements iceberg::SnapshotUpdate.

◆ DataSpec()

Result< std::shared_ptr< PartitionSpec > > iceberg::MergingSnapshotUpdate::DataSpec ( ) const
protected

Returns the single partition spec for all staged data files.

Precondition: exactly one partition spec ID must be represented among staged data files.

◆ DeleteByPath()

Status iceberg::MergingSnapshotUpdate::DeleteByPath ( std::string_view  path)
protected

Register a data file path to be deleted from the table.

Note
Only applies to data files. To remove delete files, use DeleteDeleteFile().

◆ DeleteByRowFilter()

Status iceberg::MergingSnapshotUpdate::DeleteByRowFilter ( std::shared_ptr< Expression expr)
protected

Register an expression to delete matching rows.

Both data and delete filter managers receive the expression: delete files that match the row filter can also be removed because those rows will be deleted.

◆ DropPartition()

Status iceberg::MergingSnapshotUpdate::DropPartition ( int32_t  spec_id,
PartitionValues  partition 
)
protected

Register a partition to be dropped.

Both data and delete filter managers receive the partition drop, since dropping data in a partition also drops all delete files in that partition.

◆ Summary()

std::unordered_map< std::string, std::string > iceberg::MergingSnapshotUpdate::Summary ( )
overridevirtual

Get the summary map for this operation.

Returns
A map of summary properties

Implements iceberg::SnapshotUpdate.

◆ ValidateNewDeleteFile()

Status iceberg::MergingSnapshotUpdate::ValidateNewDeleteFile ( const TableMetadata metadata,
const DataFile file 
)
protected

Validate a delete file against the table format version rules.

  • Format v1: deletes are not supported.
  • Format v2: position deletes must NOT be deletion vectors (DVs).
  • Format v3+: position deletes MUST be deletion vectors (DVs).

◆ ValidateNoNewDeletesForDataFiles() [1/2]

Status iceberg::MergingSnapshotUpdate::ValidateNoNewDeletesForDataFiles ( const TableMetadata metadata,
std::optional< int64_t >  starting_snapshot_id,
const DataFileSet replaced_files,
const std::shared_ptr< Snapshot > &  parent,
std::shared_ptr< FileIO io 
) const
inlineprotected

Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a delete file that covers a file in replaced_files.

Whether equality deletes are checked is derived automatically from whether a custom data sequence number was set via SetNewDataFilesDataSequenceNumber(): if set, equality deletes are ignored because they still apply to the rewritten files and are not a conflict.

Subclasses should prefer this overload over the static one.

◆ ValidateNoNewDeletesForDataFiles() [2/2]

Status iceberg::MergingSnapshotUpdate::ValidateNoNewDeletesForDataFiles ( const TableMetadata metadata,
std::optional< int64_t >  starting_snapshot_id,
const DataFileSet replaced_files,
const std::shared_ptr< Snapshot > &  parent,
std::shared_ptr< FileIO io,
bool  ignore_equality_deletes = false 
)
staticprotected

Return an error if any snapshot after starting_snapshot_id, or from the beginning if unset, added a delete file that covers a file in replaced_files.

Parameters
ignore_equality_deletesIf true, only position deletes are checked. Set to true when replaced data files have the same sequence number as the new files (e.g. RewriteFiles), so equality deletes at higher sequence numbers still apply and are not a conflict.

The documentation for this class was generated from the following files: