Skip to content

Conversation

@zhjwpku
Copy link
Collaborator

@zhjwpku zhjwpku commented Dec 17, 2025

No description provided.

Copy link
Member

@wgtmac wgtmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't finished my review yet. Just post my findings so far. Will review it later.

const Table& table, int64_t snapshot_id) {
ICEBERG_ASSIGN_OR_RAISE(auto start, table.SnapshotById(snapshot_id));
if (!start) {
return InvalidArgument("Cannot find snapshot: {}", snapshot_id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return InvalidArgument("Cannot find snapshot: {}", snapshot_id);
return NotFound("Cannot find snapshot: {}", snapshot_id);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, perhaps this should be a ICEBERG_DCHECK.

break;
}
auto parent_result = table.SnapshotById(current->parent_snapshot_id.value());
if (!parent_result.has_value()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to check if the error is NotFound and return the original error for other kind of errors.

// Parent snapshot not found (e.g., expired), stop traversal
break;
}
current = parent_result.value();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
current = parent_result.value();
current = std::move(parent_result.value());

/// Snapshot.
///
/// \param table The table
/// \return The oldest snapshot, or nullopt if there is no current snapshot
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to document that all returned std::shared_ptr<Snapshot> cannot be nullptr.


Result<std::optional<std::shared_ptr<Snapshot>>> SnapshotUtil::OldestAncestorAfter(
const Table& table, TimePointMs timestamp_ms) {
ICEBERG_ASSIGN_OR_RAISE(auto current, table.current_snapshot());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it is not an error if current snapshot is not found. We can return std::nullopt when the result error is NotFound.

Result<std::optional<std::shared_ptr<Snapshot>>> SnapshotUtil::OldestAncestorAfter(
const Table& table, TimePointMs timestamp_ms) {
ICEBERG_ASSIGN_OR_RAISE(auto current, table.current_snapshot());
if (!current) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

table.current_snapshot() should not return a nullptr, so this should be an error instead.

Result<bool> SnapshotUtil::IsAncestorOf(const Table& table, int64_t snapshot_id,
int64_t ancestor_snapshot_id) {
ICEBERG_ASSIGN_OR_RAISE(auto ancestors, AncestorsOf(table, snapshot_id));
for (const auto& snapshot : ancestors) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use std::ranges for this kind of processing.

return std::nullopt;
}

std::shared_ptr<Snapshot> last_snapshot = nullptr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using std::optional<std::shared_ptr<Snapshot>> so we don't need to check at line 111.

return last_snapshot;
}

return ValidationFailed("Cannot find snapshot older than {}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return ValidationFailed("Cannot find snapshot older than {}",
return NotFound("Cannot find snapshot older than {}",

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm undecided which is better, ValidationFailed, NotFound or Invalid.

int64_t to_snapshot_id) {
ICEBERG_ASSIGN_OR_RAISE(auto to_snapshot, table.SnapshotById(to_snapshot_id));
if (!to_snapshot) {
return InvalidArgument("Cannot find snapshot: {}", to_snapshot_id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InvalidArgument should be used for input argument. This is an invalid state so perhaps return Invalid?

Copy link
Member

@wgtmac wgtmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this!

@wgtmac wgtmac merged commit dba8f92 into apache:main Dec 22, 2025
9 checks passed
@zhjwpku zhjwpku deleted the add_snapshot_util branch December 22, 2025 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants