1919
2020#include " iceberg/snapshot.h"
2121
22- #include < charconv>
23-
2422#include " iceberg/file_io.h"
2523#include " iceberg/manifest/manifest_list.h"
2624#include " iceberg/manifest/manifest_reader.h"
@@ -52,6 +50,78 @@ SnapshotRefType SnapshotRef::type() const noexcept {
5250 retention);
5351}
5452
53+ Status SnapshotRef::MinSnapshotsToKeep (std::optional<int32_t > value) {
54+ ICEBERG_PRECHECK (this ->type () != SnapshotRefType::kTag ,
55+ " Tags do not support setting minSnapshotsToKeep" );
56+ ICEBERG_PRECHECK (!value.has_value () || value.value () > 0 ,
57+ " Min snapshots to keep must be greater than 0" );
58+ std::get<Branch>(this ->retention ).min_snapshots_to_keep = value;
59+ return {};
60+ }
61+
62+ Status SnapshotRef::MaxSnapshotAgeMs (std::optional<int64_t > value) {
63+ ICEBERG_PRECHECK (this ->type () != SnapshotRefType::kTag ,
64+ " Tags do not support setting maxSnapshotAgeMs" );
65+ ICEBERG_PRECHECK (!value.has_value () || value.value () > 0 ,
66+ " Max snapshot age must be greater than 0 ms" );
67+ std::get<Branch>(this ->retention ).max_snapshot_age_ms = value;
68+ return {};
69+ }
70+
71+ Status SnapshotRef::MaxRefAgeMs (std::optional<int64_t > value) {
72+ ICEBERG_PRECHECK (!value.has_value () || value.value () > 0 ,
73+ " Max reference age must be greater than 0" );
74+ if (this ->type () == SnapshotRefType::kBranch ) {
75+ std::get<Branch>(this ->retention ).max_ref_age_ms = value;
76+ } else {
77+ std::get<Tag>(this ->retention ).max_ref_age_ms = value;
78+ }
79+ return {};
80+ }
81+
82+ Result<std::unique_ptr<SnapshotRef>> SnapshotRef::MakeBranch (
83+ int64_t snapshot_id, std::optional<int32_t > min_snapshots_to_keep,
84+ std::optional<int64_t > max_snapshot_age_ms, std::optional<int64_t > max_ref_age_ms) {
85+ // Validate optional parameters
86+ if (min_snapshots_to_keep.has_value () && min_snapshots_to_keep.value () <= 0 ) {
87+ return InvalidArgument (" Min snapshots to keep must be greater than 0" );
88+ }
89+ if (max_snapshot_age_ms.has_value () && max_snapshot_age_ms.value () <= 0 ) {
90+ return InvalidArgument (" Max snapshot age must be greater than 0 ms" );
91+ }
92+ if (max_ref_age_ms.has_value () && max_ref_age_ms.value () <= 0 ) {
93+ return InvalidArgument (" Max reference age must be greater than 0" );
94+ }
95+
96+ auto ref = std::make_unique<SnapshotRef>();
97+ ref->snapshot_id = snapshot_id;
98+ ref->retention = Branch{.min_snapshots_to_keep = min_snapshots_to_keep,
99+ .max_snapshot_age_ms = max_snapshot_age_ms,
100+ .max_ref_age_ms = max_ref_age_ms};
101+ return ref;
102+ }
103+
104+ Result<std::unique_ptr<SnapshotRef>> SnapshotRef::MakeTag (
105+ int64_t snapshot_id, std::optional<int64_t > max_ref_age_ms) {
106+ // Validate optional parameter
107+ if (max_ref_age_ms.has_value () && max_ref_age_ms.value () <= 0 ) {
108+ return InvalidArgument (" Max reference age must be greater than 0" );
109+ }
110+
111+ auto ref = std::make_unique<SnapshotRef>();
112+ ref->snapshot_id = snapshot_id;
113+ ref->retention = Tag{.max_ref_age_ms = max_ref_age_ms};
114+ return ref;
115+ }
116+
117+ std::unique_ptr<SnapshotRef> SnapshotRef::Clone (
118+ std::optional<int64_t > new_snapshot_id) const {
119+ auto ref = std::make_unique<SnapshotRef>();
120+ ref->snapshot_id = new_snapshot_id.value_or (snapshot_id);
121+ ref->retention = retention;
122+ return ref;
123+ }
124+
55125bool SnapshotRef::Equals (const SnapshotRef& other) const {
56126 if (this == &other) {
57127 return true ;
@@ -78,17 +148,17 @@ std::optional<std::string_view> Snapshot::operation() const {
78148 return std::nullopt ;
79149}
80150
81- std::optional<int64_t > Snapshot::FirstRowId () const {
82- auto it = summary.find (" first-row-id " );
151+ Result< std::optional<int64_t > > Snapshot::FirstRowId () const {
152+ auto it = summary.find (SnapshotSummaryFields:: kFirstRowId );
83153 if (it == summary.end ()) {
84154 return std::nullopt ;
85155 }
86156
87157 return StringUtils::ParseInt<int64_t >(it->second );
88158}
89159
90- std::optional<int64_t > Snapshot::AddedRows () const {
91- auto it = summary.find (" added-rows " );
160+ Result< std::optional<int64_t > > Snapshot::AddedRows () const {
161+ auto it = summary.find (SnapshotSummaryFields:: kAddedRows );
92162 if (it == summary.end ()) {
93163 return std::nullopt ;
94164 }
@@ -162,103 +232,4 @@ Result<std::span<ManifestFile>> SnapshotCache::DeleteManifests(
162232 return std::span<ManifestFile>(cache.first .data () + delete_start, delete_count);
163233}
164234
165- // SnapshotRef::Builder implementation
166-
167- SnapshotRef::Builder::Builder (SnapshotRefType type, int64_t snapshot_id)
168- : type_(type), snapshot_id_(snapshot_id) {}
169-
170- SnapshotRef::Builder SnapshotRef::Builder::TagBuilder (int64_t snapshot_id) {
171- return Builder (SnapshotRefType::kTag , snapshot_id);
172- }
173-
174- SnapshotRef::Builder SnapshotRef::Builder::BranchBuilder (int64_t snapshot_id) {
175- return Builder (SnapshotRefType::kBranch , snapshot_id);
176- }
177-
178- SnapshotRef::Builder SnapshotRef::Builder::BuilderFor (int64_t snapshot_id,
179- SnapshotRefType type) {
180- return Builder (type, snapshot_id);
181- }
182-
183- SnapshotRef::Builder SnapshotRef::Builder::BuilderFrom (const SnapshotRef& ref) {
184- Builder builder (ref.type (), ref.snapshot_id );
185- if (ref.type () == SnapshotRefType::kBranch ) {
186- const auto & branch = std::get<SnapshotRef::Branch>(ref.retention );
187- builder.min_snapshots_to_keep_ = branch.min_snapshots_to_keep ;
188- builder.max_snapshot_age_ms_ = branch.max_snapshot_age_ms ;
189- builder.max_ref_age_ms_ = branch.max_ref_age_ms ;
190- } else {
191- const auto & tag = std::get<SnapshotRef::Tag>(ref.retention );
192- builder.max_ref_age_ms_ = tag.max_ref_age_ms ;
193- }
194- return builder;
195- }
196-
197- SnapshotRef::Builder SnapshotRef::Builder::BuilderFrom (const SnapshotRef& ref,
198- int64_t snapshot_id) {
199- Builder builder (ref.type (), snapshot_id);
200- if (ref.type () == SnapshotRefType::kBranch ) {
201- const auto & branch = std::get<SnapshotRef::Branch>(ref.retention );
202- builder.min_snapshots_to_keep_ = branch.min_snapshots_to_keep ;
203- builder.max_snapshot_age_ms_ = branch.max_snapshot_age_ms ;
204- builder.max_ref_age_ms_ = branch.max_ref_age_ms ;
205- } else {
206- const auto & tag = std::get<SnapshotRef::Tag>(ref.retention );
207- builder.max_ref_age_ms_ = tag.max_ref_age_ms ;
208- }
209- return builder;
210- }
211-
212- SnapshotRef::Builder& SnapshotRef::Builder::MinSnapshotsToKeep (
213- std::optional<int32_t > value) {
214- if (type_ == SnapshotRefType::kTag && value.has_value ()) {
215- return AddError (ErrorKind::kInvalidArgument ,
216- " Tags do not support setting minSnapshotsToKeep" );
217- }
218- if (value.has_value () && value.value () <= 0 ) {
219- return AddError (ErrorKind::kInvalidArgument ,
220- " Min snapshots to keep must be greater than 0" );
221- }
222- min_snapshots_to_keep_ = value;
223- return *this ;
224- }
225-
226- SnapshotRef::Builder& SnapshotRef::Builder::MaxSnapshotAgeMs (
227- std::optional<int64_t > value) {
228- if (type_ == SnapshotRefType::kTag && value.has_value ()) {
229- return AddError (ErrorKind::kInvalidArgument ,
230- " Tags do not support setting maxSnapshotAgeMs" );
231- }
232- if (value.has_value () && value.value () <= 0 ) {
233- return AddError (ErrorKind::kInvalidArgument ,
234- " Max snapshot age must be greater than 0 ms" );
235- }
236- max_snapshot_age_ms_ = value;
237- return *this ;
238- }
239-
240- SnapshotRef::Builder& SnapshotRef::Builder::MaxRefAgeMs (std::optional<int64_t > value) {
241- if (value.has_value () && value.value () <= 0 ) {
242- return AddError (ErrorKind::kInvalidArgument ,
243- " Max reference age must be greater than 0" );
244- }
245- max_ref_age_ms_ = value;
246- return *this ;
247- }
248-
249- Result<SnapshotRef> SnapshotRef::Builder::Build () const {
250- ICEBERG_RETURN_UNEXPECTED (CheckErrors ());
251-
252- if (type_ == SnapshotRefType::kBranch ) {
253- return SnapshotRef{
254- .snapshot_id = snapshot_id_,
255- .retention = SnapshotRef::Branch{.min_snapshots_to_keep = min_snapshots_to_keep_,
256- .max_snapshot_age_ms = max_snapshot_age_ms_,
257- .max_ref_age_ms = max_ref_age_ms_}};
258- } else {
259- return SnapshotRef{.snapshot_id = snapshot_id_,
260- .retention = SnapshotRef::Tag{.max_ref_age_ms = max_ref_age_ms_}};
261- }
262- }
263-
264235} // namespace iceberg
0 commit comments