@@ -617,6 +617,9 @@ class TableMetadataBuilder::Impl {
617617 Status SetBranchSnapshot (int64_t snapshot_id, const std::string& branch);
618618 Status SetBranchSnapshot (std::shared_ptr<Snapshot> snapshot, const std::string& branch);
619619 Status SetRef (const std::string& name, std::shared_ptr<SnapshotRef> ref);
620+ Status RemoveRef (const std::string& name);
621+ Status RemoveSnapshots (const std::vector<int64_t >& snapshot_ids);
622+ Status RemovePartitionSpecs (const std::vector<int32_t >& spec_ids);
620623
621624 Result<std::unique_ptr<TableMetadata>> Build ();
622625
@@ -1334,6 +1337,84 @@ int32_t TableMetadataBuilder::Impl::ReuseOrCreateNewSchemaId(
13341337 return new_schema_id;
13351338}
13361339
1340+ Status TableMetadataBuilder::Impl::RemoveRef (const std::string& name) {
1341+ if (name == SnapshotRef::kMainBranch ) {
1342+ metadata_.current_snapshot_id = kInvalidSnapshotId ;
1343+ }
1344+
1345+ if (metadata_.refs .erase (name) != 0 ) {
1346+ changes_.push_back (std::make_unique<table::RemoveSnapshotRef>(name));
1347+ }
1348+
1349+ return {};
1350+ }
1351+
1352+ Status TableMetadataBuilder::Impl::RemoveSnapshots (
1353+ const std::vector<int64_t >& snapshot_ids) {
1354+ if (snapshot_ids.empty ()) {
1355+ return {};
1356+ }
1357+
1358+ std::unordered_set<int64_t > ids_to_remove (snapshot_ids.begin (), snapshot_ids.end ());
1359+ std::vector<std::shared_ptr<Snapshot>> retained_snapshots;
1360+ retained_snapshots.reserve (metadata_.snapshots .size () - snapshot_ids.size ());
1361+ std::vector<int64_t > snapshot_ids_to_remove;
1362+ snapshot_ids_to_remove.reserve (snapshot_ids.size ());
1363+
1364+ for (auto & snapshot : metadata_.snapshots ) {
1365+ ICEBERG_CHECK (snapshot != nullptr , " Encountered null snapshot in metadata" );
1366+ const int64_t snapshot_id = snapshot->snapshot_id ;
1367+ if (ids_to_remove.contains (snapshot_id)) {
1368+ snapshots_by_id_.erase (snapshot_id);
1369+ snapshot_ids_to_remove.push_back (snapshot_id);
1370+ // FIXME: implement statistics removal and uncomment below
1371+ // ICEBERG_RETURN_UNEXPECTED(RemoveStatistics(snapshot_id));
1372+ // ICEBERG_RETURN_UNEXPECTED(RemovePartitionStatistics(snapshot_id));
1373+ } else {
1374+ retained_snapshots.push_back (std::move (snapshot));
1375+ }
1376+ }
1377+
1378+ if (!snapshot_ids_to_remove.empty ()) {
1379+ changes_.push_back (std::make_unique<table::RemoveSnapshots>(snapshot_ids_to_remove));
1380+ }
1381+
1382+ metadata_.snapshots = std::move (retained_snapshots);
1383+
1384+ // Remove any refs that are no longer valid (dangling refs)
1385+ std::vector<std::string> dangling_refs;
1386+ for (const auto & [ref_name, ref] : metadata_.refs ) {
1387+ if (!snapshots_by_id_.contains (ref->snapshot_id )) {
1388+ dangling_refs.push_back (ref_name);
1389+ }
1390+ }
1391+ for (const auto & ref_name : dangling_refs) {
1392+ ICEBERG_RETURN_UNEXPECTED (RemoveRef (ref_name));
1393+ }
1394+
1395+ return {};
1396+ }
1397+
1398+ Status TableMetadataBuilder::Impl::RemovePartitionSpecs (
1399+ const std::vector<int32_t >& spec_ids) {
1400+ if (spec_ids.empty ()) {
1401+ return {};
1402+ }
1403+
1404+ std::unordered_set<int32_t > spec_ids_to_remove (spec_ids.begin (), spec_ids.end ());
1405+ ICEBERG_PRECHECK (!spec_ids_to_remove.contains (metadata_.default_spec_id ),
1406+ " Cannot remove the default partition spec" );
1407+
1408+ metadata_.partition_specs =
1409+ metadata_.partition_specs | std::views::filter ([&](const auto & spec) {
1410+ return !spec_ids_to_remove.contains (spec->spec_id ());
1411+ }) |
1412+ std::ranges::to<std::vector<std::shared_ptr<PartitionSpec>>>();
1413+ changes_.push_back (std::make_unique<table::RemovePartitionSpecs>(spec_ids));
1414+
1415+ return {};
1416+ }
1417+
13371418TableMetadataBuilder::TableMetadataBuilder (int8_t format_version)
13381419 : impl_(std::make_unique<Impl>(format_version)) {}
13391420
@@ -1436,7 +1517,8 @@ TableMetadataBuilder& TableMetadataBuilder::AddPartitionSpec(
14361517
14371518TableMetadataBuilder& TableMetadataBuilder::RemovePartitionSpecs (
14381519 const std::vector<int32_t >& spec_ids) {
1439- throw IcebergError (std::format (" {} not implemented" , __FUNCTION__));
1520+ ICEBERG_BUILDER_RETURN_IF_ERROR (impl_->RemovePartitionSpecs (spec_ids));
1521+ return *this ;
14401522}
14411523
14421524TableMetadataBuilder& TableMetadataBuilder::RemoveSchemas (
@@ -1464,7 +1546,7 @@ TableMetadataBuilder& TableMetadataBuilder::AddSortOrder(
14641546
14651547TableMetadataBuilder& TableMetadataBuilder::AddSnapshot (
14661548 std::shared_ptr<Snapshot> snapshot) {
1467- ICEBERG_BUILDER_RETURN_IF_ERROR (impl_->AddSnapshot (snapshot));
1549+ ICEBERG_BUILDER_RETURN_IF_ERROR (impl_->AddSnapshot (std::move ( snapshot) ));
14681550 return *this ;
14691551}
14701552
@@ -1487,7 +1569,8 @@ TableMetadataBuilder& TableMetadataBuilder::SetRef(const std::string& name,
14871569}
14881570
14891571TableMetadataBuilder& TableMetadataBuilder::RemoveRef (const std::string& name) {
1490- throw IcebergError (std::format (" {} not implemented" , __FUNCTION__));
1572+ ICEBERG_BUILDER_RETURN_IF_ERROR (impl_->RemoveRef (name));
1573+ return *this ;
14911574}
14921575
14931576TableMetadataBuilder& TableMetadataBuilder::RemoveSnapshots (
@@ -1497,7 +1580,8 @@ TableMetadataBuilder& TableMetadataBuilder::RemoveSnapshots(
14971580
14981581TableMetadataBuilder& TableMetadataBuilder::RemoveSnapshots (
14991582 const std::vector<int64_t >& snapshot_ids) {
1500- throw IcebergError (std::format (" {} not implemented" , __FUNCTION__));
1583+ ICEBERG_BUILDER_RETURN_IF_ERROR (impl_->RemoveSnapshots (snapshot_ids));
1584+ return *this ;
15011585}
15021586
15031587TableMetadataBuilder& TableMetadataBuilder::SuppressHistoricalSnapshots () {
0 commit comments