iceberg-cpp
Loading...
Searching...
No Matches
snapshot_update.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
24
25#include <atomic>
26#include <functional>
27#include <memory>
28#include <optional>
29#include <span>
30#include <string>
31#include <unordered_map>
32#include <unordered_set>
33#include <vector>
34
36#include "iceberg/result.h"
37#include "iceberg/snapshot.h"
38#include "iceberg/type_fwd.h"
41
42namespace iceberg {
43
49class ICEBERG_EXPORT SnapshotUpdate : public PendingUpdate {
50 public:
52 struct ApplyResult {
53 std::shared_ptr<Snapshot> snapshot;
54 std::string target_branch;
55 bool stage_only = false;
56 };
57
58 ~SnapshotUpdate() override;
59
60 Kind kind() const override { return Kind::kUpdateSnapshot; }
61 bool IsRetryable() const override { return true; }
62 Status Commit() override;
63
68 auto& ReportWith(this auto& self, std::shared_ptr<MetricsReporter> reporter) {
69 static_cast<SnapshotUpdate&>(self).reporter_ = std::move(reporter);
70 return self;
71 }
72
78 auto& DeleteWith(this auto& self,
79 std::function<Status(const std::string&)> delete_func) {
80 if (self.delete_func_) {
81 return self.AddError(ErrorKind::kInvalidArgument,
82 "Cannot set delete callback more than once");
83 }
84 self.delete_func_ = std::move(delete_func);
85 return self;
86 }
87
94 auto& StageOnly(this auto& self) {
95 self.stage_only_ = true;
96 return self;
97 }
98
103 auto& ScanManifestsWith(this auto& self, Executor& executor) {
104 self.plan_executor_ = std::ref(executor);
105 return self;
106 }
107
112 auto& ToBranch(this auto& self, const std::string& branch) {
113 if (branch.empty()) [[unlikely]] {
114 return self.AddError(ErrorKind::kInvalidArgument, "Branch name cannot be empty");
115 }
116
117 if (auto ref_it = self.base().refs.find(branch); ref_it != self.base().refs.end()) {
118 if (ref_it->second->type() != SnapshotRefType::kBranch) {
119 return self.AddError(ErrorKind::kInvalidArgument,
120 "{} is a tag, not a branch. Tags cannot be targets for "
121 "producing snapshots",
122 branch);
123 }
124 }
125
126 self.target_branch_ = branch;
127 return self;
128 }
129
135 auto& Set(this auto& self, const std::string& property, const std::string& value) {
136 static_cast<SnapshotUpdate&>(self).SetSummaryProperty(property, value);
137 return self;
138 }
139
147 auto& WriteManifestsWith(this auto& self, Executor& executor, int32_t parallelism) {
148 if (parallelism <= 0) [[unlikely]] {
149 return self.AddError(
150 ErrorKind::kInvalidArgument,
151 "Manifest write parallelism must be greater than 0, but was: {}", parallelism);
152 }
153
154 self.write_manifest_executor_ = std::ref(executor);
155 self.write_manifest_parallelism_ = parallelism;
156 return self;
157 }
158
168
170 Status Finalize(Result<const TableMetadata*> commit_result) override;
171
172 protected:
174 std::shared_ptr<DataFile> file;
175 std::optional<int64_t> data_sequence_number;
176 };
177
178 explicit SnapshotUpdate(std::shared_ptr<TransactionContext> ctx);
179
187 std::span<const std::shared_ptr<DataFile>> files,
188 const std::shared_ptr<PartitionSpec>& spec,
189 std::optional<int64_t> data_sequence_number = std::nullopt);
190
191 Result<std::vector<ManifestFile>> WriteDeleteManifests(
192 std::span<const ContentFileWithSequenceNumber> files,
193 const std::shared_ptr<PartitionSpec>& spec);
194
195 const std::string& target_branch() const { return target_branch_; }
196 bool can_inherit_snapshot_id() const { return can_inherit_snapshot_id_; }
197 const std::string& commit_uuid() const { return commit_uuid_; }
198 int32_t manifest_count() const {
199 return manifest_count_.load(std::memory_order_relaxed);
200 }
201 int32_t attempt() const { return attempt_.load(std::memory_order_relaxed); }
202 int64_t target_manifest_size_bytes() const { return target_manifest_size_bytes_; }
203
214 virtual Status CleanUncommitted(const std::unordered_set<std::string>& committed) = 0;
215
219 virtual std::string operation() = 0;
220
227 virtual Status Validate(const TableMetadata& current_metadata,
228 const std::shared_ptr<Snapshot>& snapshot) {
229 return {};
230 };
231
238 const TableMetadata& metadata_to_update,
239 const std::shared_ptr<Snapshot>& snapshot) = 0;
240
244 virtual std::unordered_map<std::string, std::string> Summary() = 0;
245
250 virtual void SetSummaryProperty(const std::string& property, const std::string& value);
251
255 virtual bool CleanupAfterCommit() const { return true; }
256
258 int64_t SnapshotId();
259
264 Status DeleteFile(const std::string& path);
265
266 std::string ManifestPath();
267 std::string ManifestListPath();
268 SnapshotSummaryBuilder& summary_builder() { return summary_; }
269 SnapshotSummaryBuilder BuildManifestCountSummary(
270 std::span<const ManifestFile> manifests, int32_t replaced_manifests_count);
271
272 private:
275 const TableMetadata& previous);
276
278 Status CleanAll();
279
281 void ReportCommit() const;
282
283 protected:
284 SnapshotSummaryBuilder summary_;
285
286 private:
287 const bool can_inherit_snapshot_id_{true};
288 const std::string commit_uuid_;
289 OptionalExecutor write_manifest_executor_;
290 int32_t write_manifest_parallelism_{1};
291 std::atomic<int32_t> manifest_count_{0};
292 std::atomic<int32_t> attempt_{0};
293 std::vector<std::string> manifest_lists_;
294 const int64_t target_manifest_size_bytes_;
295 std::optional<int64_t> snapshot_id_;
296 OptionalExecutor plan_executor_;
297 bool stage_only_{false};
298 std::function<Status(const std::string&)> delete_func_;
299 std::string target_branch_{SnapshotRef::kMainBranch};
300 std::shared_ptr<Snapshot> staged_snapshot_;
301 std::unique_ptr<CommitMetrics> commit_metrics_;
302 std::shared_ptr<MetricsReporter> reporter_;
303};
304
305} // namespace iceberg
Schedules iceberg-cpp internal planning tasks.
Definition executor.h:46
Base class for all kinds of table metadata updates.
Definition pending_update.h:41
Helper class for building snapshot summaries.
Definition snapshot.h:265
API for table changes that produce snapshots.
Definition snapshot_update.h:49
virtual Result< std::vector< ManifestFile > > Apply(const TableMetadata &metadata_to_update, const std::shared_ptr< Snapshot > &snapshot)=0
Apply the update's changes to the given metadata and snapshot.
virtual std::unordered_map< std::string, std::string > Summary()=0
Get the summary map for this operation.
auto & StageOnly(this auto &self)
Stage a snapshot in table metadata, but do not make it current.
Definition snapshot_update.h:94
virtual std::string operation()=0
A string that describes the action that produced the new snapshot.
virtual Status CleanUncommitted(const std::unordered_set< std::string > &committed)=0
Clean up any uncommitted manifests that were created.
Result< ApplyResult > Apply()
Apply the update's changes to create a new snapshot.
bool IsRetryable() const override
Whether this update can be retried after a commit conflict.
Definition snapshot_update.h:61
auto & ToBranch(this auto &self, const std::string &branch)
Perform operations on a particular branch.
Definition snapshot_update.h:112
virtual Status Validate(const TableMetadata &current_metadata, const std::shared_ptr< Snapshot > &snapshot)
Validate the current metadata.
Definition snapshot_update.h:227
int64_t SnapshotId()
Get or generate the snapshot ID for the new snapshot.
auto & ScanManifestsWith(this auto &self, Executor &executor)
Configure an executor for manifest planning work.
Definition snapshot_update.h:103
auto & WriteManifestsWith(this auto &self, Executor &executor, int32_t parallelism)
Configure an executor and max writer count for writing new manifests.
Definition snapshot_update.h:147
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.
Status Finalize(Result< const TableMetadata * > commit_result) override
Finalize the snapshot update, cleaning up any uncommitted files.
Kind kind() const override
Return the kind of this pending update.
Definition snapshot_update.h:60
auto & Set(this auto &self, const std::string &property, const std::string &value)
Set a summary property in the snapshot produced by this update.
Definition snapshot_update.h:135
virtual bool CleanupAfterCommit() const
Check if cleanup should happen after commit.
Definition snapshot_update.h:255
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.
Definition snapshot_update.h:78
Status Commit() override
Apply the pending changes and commit.
Status DeleteFile(const std::string &path)
Delete a file at the given path.
auto & ReportWith(this auto &self, std::shared_ptr< MetricsReporter > reporter)
Set the metrics reporter for this snapshot update.
Definition snapshot_update.h:68
virtual void SetSummaryProperty(const std::string &property, const std::string &value)
Set a summary property.
Define task executor interfaces.
Define symbol visibility macros for core Iceberg APIs.
Core Apache Iceberg C++ APIs.
Definition arrow_io_util.h:33
std::expected< T, E > Result
Result alias.
Definition result.h:88
Define Result, Status, and error helpers.
Define snapshot metadata types.
Result of applying a snapshot update.
Definition snapshot_update.h:52
Represents the metadata for an Iceberg table.
Definition table_metadata.h:73