Skip to content

Commit 9b22f5e

Browse files
committed
feat: Impl InMemoryCatalog's UpdateTable
1 parent 09f26b6 commit 9b22f5e

File tree

13 files changed

+620
-40
lines changed

13 files changed

+620
-40
lines changed

src/iceberg/catalog/memory/in_memory_catalog.cc

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121

2222
#include <algorithm>
2323
#include <iterator> // IWYU pragma: keep
24+
#include <memory>
2425

25-
#include "iceberg/exception.h"
2626
#include "iceberg/table.h"
27+
#include "iceberg/table_identifier.h"
2728
#include "iceberg/table_metadata.h"
29+
#include "iceberg/table_requirement.h"
30+
#include "iceberg/table_update.h"
2831
#include "iceberg/util/macros.h"
2932

3033
namespace iceberg {
@@ -121,6 +124,13 @@ class ICEBERG_EXPORT InMemoryNamespace {
121124
/// \return The metadata location if the table exists; error otherwise.
122125
Result<std::string> GetTableMetadataLocation(const TableIdentifier& table_ident) const;
123126

127+
/// \brief Updates the metadata location for the specified table.
128+
///
129+
/// \param table_ident The identifier of the table.
130+
/// \param metadata_location The new metadata location.
131+
Status UpdateTableMetadataLocation(const TableIdentifier& table_ident,
132+
const std::string& metadata_location);
133+
124134
/// \brief Internal utility for retrieving a namespace node pointer from the tree.
125135
///
126136
/// \tparam NamespacePtr The type of the namespace node pointer.
@@ -279,7 +289,7 @@ Result<std::vector<std::string>> InMemoryNamespace::ListTables(
279289
return table_names;
280290
}
281291

282-
Status InMemoryNamespace::RegisterTable(TableIdentifier const& table_ident,
292+
Status InMemoryNamespace::RegisterTable(const TableIdentifier& table_ident,
283293
const std::string& metadata_location) {
284294
const auto ns = GetNamespace(this, table_ident.ns);
285295
ICEBERG_RETURN_UNEXPECTED(ns);
@@ -290,21 +300,21 @@ Status InMemoryNamespace::RegisterTable(TableIdentifier const& table_ident,
290300
return {};
291301
}
292302

293-
Status InMemoryNamespace::UnregisterTable(TableIdentifier const& table_ident) {
303+
Status InMemoryNamespace::UnregisterTable(const TableIdentifier& table_ident) {
294304
const auto ns = GetNamespace(this, table_ident.ns);
295305
ICEBERG_RETURN_UNEXPECTED(ns);
296306
ns.value()->table_metadata_locations_.erase(table_ident.name);
297307
return {};
298308
}
299309

300-
Result<bool> InMemoryNamespace::TableExists(TableIdentifier const& table_ident) const {
310+
Result<bool> InMemoryNamespace::TableExists(const TableIdentifier& table_ident) const {
301311
const auto ns = GetNamespace(this, table_ident.ns);
302312
ICEBERG_RETURN_UNEXPECTED(ns);
303313
return ns.value()->table_metadata_locations_.contains(table_ident.name);
304314
}
305315

306316
Result<std::string> InMemoryNamespace::GetTableMetadataLocation(
307-
TableIdentifier const& table_ident) const {
317+
const TableIdentifier& table_ident) const {
308318
const auto ns = GetNamespace(this, table_ident.ns);
309319
ICEBERG_RETURN_UNEXPECTED(ns);
310320
const auto it = ns.value()->table_metadata_locations_.find(table_ident.name);
@@ -314,17 +324,24 @@ Result<std::string> InMemoryNamespace::GetTableMetadataLocation(
314324
return it->second;
315325
}
316326

327+
Status InMemoryNamespace::UpdateTableMetadataLocation(
328+
const TableIdentifier& table_ident, const std::string& metadata_location) {
329+
ICEBERG_ASSIGN_OR_RAISE(auto ns, GetNamespace(this, table_ident.ns));
330+
ns->table_metadata_locations_[table_ident.name] = metadata_location;
331+
return {};
332+
}
333+
317334
std::shared_ptr<InMemoryCatalog> InMemoryCatalog::Make(
318-
std::string const& name, std::shared_ptr<FileIO> const& file_io,
319-
std::string const& warehouse_location,
320-
std::unordered_map<std::string, std::string> const& properties) {
335+
const std::string& name, const std::shared_ptr<FileIO>& file_io,
336+
const std::string& warehouse_location,
337+
const std::unordered_map<std::string, std::string>& properties) {
321338
return std::make_shared<InMemoryCatalog>(name, file_io, warehouse_location, properties);
322339
}
323340

324341
InMemoryCatalog::InMemoryCatalog(
325-
std::string const& name, std::shared_ptr<FileIO> const& file_io,
326-
std::string const& warehouse_location,
327-
std::unordered_map<std::string, std::string> const& properties)
342+
const std::string& name, const std::shared_ptr<FileIO>& file_io,
343+
const std::string& warehouse_location,
344+
const std::unordered_map<std::string, std::string>& properties)
328345
: catalog_name_(std::move(name)),
329346
properties_(std::move(properties)),
330347
file_io_(std::move(file_io)),
@@ -394,7 +411,32 @@ Result<std::unique_ptr<Table>> InMemoryCatalog::UpdateTable(
394411
const TableIdentifier& identifier,
395412
const std::vector<std::unique_ptr<TableRequirement>>& requirements,
396413
const std::vector<std::unique_ptr<TableUpdate>>& updates) {
397-
return NotImplemented("update table");
414+
std::unique_lock lock(mutex_);
415+
ICEBERG_ASSIGN_OR_RAISE(auto metadata_location,
416+
root_namespace_->GetTableMetadataLocation(identifier));
417+
418+
ICEBERG_ASSIGN_OR_RAISE(auto base,
419+
TableMetadataUtil::Read(*file_io_, metadata_location));
420+
base->metadata_file_location = std::move(metadata_location);
421+
422+
for (const auto& requirement : requirements) {
423+
ICEBERG_RETURN_UNEXPECTED(requirement->Validate(base.get()));
424+
}
425+
426+
auto builder = TableMetadataBuilder::BuildFrom(base.get());
427+
for (const auto& update : updates) {
428+
update->ApplyTo(*builder);
429+
}
430+
ICEBERG_ASSIGN_OR_RAISE(auto updated, builder->Build());
431+
432+
ICEBERG_RETURN_UNEXPECTED(
433+
TableMetadataUtil::Write(*file_io_, base.get(), updated.get()));
434+
ICEBERG_RETURN_UNEXPECTED(root_namespace_->UpdateTableMetadataLocation(
435+
identifier, updated->metadata_file_location));
436+
TableMetadataUtil::DeleteRemovedMetadataFiles(*file_io_, base.get(), updated.get());
437+
438+
return std::make_unique<Table>(identifier, std::move(updated), file_io_,
439+
std::static_pointer_cast<Catalog>(shared_from_this()));
398440
}
399441

400442
Result<std::shared_ptr<Transaction>> InMemoryCatalog::StageCreateTable(
@@ -435,9 +477,9 @@ Result<std::unique_ptr<Table>> InMemoryCatalog::LoadTable(
435477

436478
ICEBERG_ASSIGN_OR_RAISE(auto metadata,
437479
TableMetadataUtil::Read(*file_io_, metadata_location.value()));
480+
metadata->metadata_file_location = metadata_location.value();
438481

439-
return std::make_unique<Table>(identifier, std::move(metadata),
440-
metadata_location.value(), file_io_,
482+
return std::make_unique<Table>(identifier, std::move(metadata), file_io_,
441483
std::static_pointer_cast<Catalog>(shared_from_this()));
442484
}
443485

src/iceberg/table.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,16 @@
2828
#include "iceberg/table_scan.h"
2929
#include "iceberg/update/update_properties.h"
3030
#include "iceberg/util/macros.h"
31+
#include "iceberg/util/timepoint.h"
3132

3233
namespace iceberg {
3334

3435
Table::~Table() = default;
3536

3637
Table::Table(TableIdentifier identifier, std::shared_ptr<TableMetadata> metadata,
37-
std::string metadata_location, std::shared_ptr<FileIO> io,
38-
std::shared_ptr<Catalog> catalog)
38+
std::shared_ptr<FileIO> io, std::shared_ptr<Catalog> catalog)
3939
: identifier_(std::move(identifier)),
4040
metadata_(std::move(metadata)),
41-
metadata_location_(std::move(metadata_location)),
4241
io_(std::move(io)),
4342
catalog_(std::move(catalog)),
4443
properties_(TableProperties::FromMap(metadata_->properties)),
@@ -52,9 +51,9 @@ Status Table::Refresh() {
5251
}
5352

5453
ICEBERG_ASSIGN_OR_RAISE(auto refreshed_table, catalog_->LoadTable(identifier_));
55-
if (metadata_location_ != refreshed_table->metadata_location_) {
54+
if (metadata_->metadata_file_location !=
55+
refreshed_table->metadata_->metadata_file_location) {
5656
metadata_ = std::move(refreshed_table->metadata_);
57-
metadata_location_ = std::move(refreshed_table->metadata_location_);
5857
io_ = std::move(refreshed_table->io_);
5958
properties_ = std::move(refreshed_table->properties_);
6059
metadata_cache_ = std::make_unique<TableMetadataCache>(metadata_.get());
@@ -91,8 +90,14 @@ Table::sort_orders() const {
9190

9291
const TableProperties& Table::properties() const { return *properties_; }
9392

93+
const std::string& Table::metadata_file_location() const {
94+
return metadata_->metadata_file_location;
95+
}
96+
9497
const std::string& Table::location() const { return metadata_->location; }
9598

99+
const TimePointMs& Table::last_updated_ms() const { return metadata_->last_updated_ms; }
100+
96101
Result<std::shared_ptr<Snapshot>> Table::current_snapshot() const {
97102
return metadata_->Snapshot();
98103
}

src/iceberg/table.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "iceberg/snapshot.h"
3030
#include "iceberg/table_identifier.h"
3131
#include "iceberg/type_fwd.h"
32+
#include "iceberg/util/timepoint.h"
3233

3334
namespace iceberg {
3435

@@ -45,8 +46,7 @@ class ICEBERG_EXPORT Table {
4546
/// \param[in] catalog The catalog that this table belongs to. If null, the table will
4647
/// be read-only.
4748
Table(TableIdentifier identifier, std::shared_ptr<TableMetadata> metadata,
48-
std::string metadata_location, std::shared_ptr<FileIO> io,
49-
std::shared_ptr<Catalog> catalog);
49+
std::shared_ptr<FileIO> io, std::shared_ptr<Catalog> catalog);
5050

5151
/// \brief Return the identifier of this table
5252
const TableIdentifier& name() const { return identifier_; }
@@ -84,9 +84,17 @@ class ICEBERG_EXPORT Table {
8484
/// \brief Return a map of string properties for this table
8585
const TableProperties& properties() const;
8686

87+
/// \brief Return the table's metadata file location
88+
const std::string& metadata_file_location() const;
89+
8790
/// \brief Return the table's base location
8891
const std::string& location() const;
8992

93+
/// \brief Get the time when this table was last updated
94+
///
95+
/// \return the time when this table was last updated
96+
const TimePointMs& last_updated_ms() const;
97+
9098
/// \brief Return the table's current snapshot, return NotFoundError if not found
9199
Result<std::shared_ptr<Snapshot>> current_snapshot() const;
92100

@@ -127,7 +135,6 @@ class ICEBERG_EXPORT Table {
127135
private:
128136
const TableIdentifier identifier_;
129137
std::shared_ptr<TableMetadata> metadata_;
130-
std::string metadata_location_;
131138
std::shared_ptr<FileIO> io_;
132139
std::shared_ptr<Catalog> catalog_;
133140
std::unique_ptr<TableProperties> properties_;

0 commit comments

Comments
 (0)