diff --git a/utilities/secondary_index/secondary_index_mixin.h b/utilities/secondary_index/secondary_index_mixin.h index ac1ffc38fa4..27b6c454f5b 100644 --- a/utilities/secondary_index/secondary_index_mixin.h +++ b/utilities/secondary_index/secondary_index_mixin.h @@ -74,30 +74,35 @@ class SecondaryIndexMixin : public Txn { } using Txn::Delete; - Status Delete(ColumnFamilyHandle* /* column_family */, const Slice& /* key */, - const bool /* assume_tracked */ = false) override { - return Status::NotSupported( - "Delete with secondary indices not yet supported"); + Status Delete(ColumnFamilyHandle* column_family, const Slice& key, + const bool assume_tracked = false) override { + return PerformWithSavePoint([&]() { + const bool do_validate = !assume_tracked; + return DeleteWithSecondaryIndices(column_family, key, do_validate); + }); } - Status Delete(ColumnFamilyHandle* /* column_family */, - const SliceParts& /* key */, - const bool /* assume_tracked */ = false) override { - return Status::NotSupported( - "Delete with secondary indices not yet supported"); + Status Delete(ColumnFamilyHandle* column_family, const SliceParts& key, + const bool assume_tracked = false) override { + std::string key_str; + const Slice key_slice(key, &key_str); + + return Delete(column_family, key_slice, assume_tracked); } using Txn::SingleDelete; - Status SingleDelete(ColumnFamilyHandle* /* column_family */, - const Slice& /* key */, - const bool /* assume_tracked */ = false) override { - return Status::NotSupported( - "SingleDelete with secondary indices not yet supported"); + Status SingleDelete(ColumnFamilyHandle* column_family, const Slice& key, + const bool assume_tracked = false) override { + return PerformWithSavePoint([&]() { + const bool do_validate = !assume_tracked; + return SingleDeleteWithSecondaryIndices(column_family, key, do_validate); + }); } - Status SingleDelete(ColumnFamilyHandle* /* column_family */, - const SliceParts& /* key */, - const bool /* assume_tracked */ = false) override { - return Status::NotSupported( - "SingleDelete with secondary indices not yet supported"); + Status SingleDelete(ColumnFamilyHandle* column_family, const SliceParts& key, + const bool assume_tracked = false) override { + std::string key_str; + const Slice key_slice(key, &key_str); + + return SingleDelete(column_family, key_slice, assume_tracked); } using Txn::PutUntracked; @@ -137,22 +142,28 @@ class SecondaryIndexMixin : public Txn { } using Txn::DeleteUntracked; - Status DeleteUntracked(ColumnFamilyHandle* /* column_family */, - const Slice& /* key */) override { - return Status::NotSupported( - "DeleteUntracked with secondary indices not yet supported"); + Status DeleteUntracked(ColumnFamilyHandle* column_family, + const Slice& key) override { + return PerformWithSavePoint([&]() { + constexpr bool do_validate = false; + return DeleteWithSecondaryIndices(column_family, key, do_validate); + }); } - Status DeleteUntracked(ColumnFamilyHandle* /* column_family */, - const SliceParts& /* key */) override { - return Status::NotSupported( - "DeleteUntracked with secondary indices not yet supported"); + Status DeleteUntracked(ColumnFamilyHandle* column_family, + const SliceParts& key) override { + std::string key_str; + const Slice key_slice(key, &key_str); + + return DeleteUntracked(column_family, key_slice); } using Txn::SingleDeleteUntracked; - Status SingleDeleteUntracked(ColumnFamilyHandle* /* column_family */, - const Slice& /* key */) override { - return Status::NotSupported( - "SingleDeleteUntracked with secondary indices not yet supported"); + Status SingleDeleteUntracked(ColumnFamilyHandle* column_family, + const Slice& key) override { + return PerformWithSavePoint([&]() { + constexpr bool do_validate = false; + return SingleDeleteWithSecondaryIndices(column_family, key, do_validate); + }); } private: @@ -448,8 +459,8 @@ class SecondaryIndexMixin : public Txn { [](const Slice& v) { return std::array<WideColumn, 1>{{{kDefaultWideColumnName, v}}}; }, - [this](ColumnFamilyHandle* cfh, const Slice& primary_key, - const std::array<WideColumn, 1>& primary_columns) { + [&](ColumnFamilyHandle* cfh, const Slice& primary_key, + const std::array<WideColumn, 1>& primary_columns) { assert(cfh); assert(!primary_columns.empty()); assert(primary_columns.front().name() == kDefaultWideColumnName); @@ -473,8 +484,8 @@ class SecondaryIndexMixin : public Txn { return primary_columns; }, - [this](ColumnFamilyHandle* cfh, const Slice& primary_key, - const WideColumns& primary_columns) { + [&](ColumnFamilyHandle* cfh, const Slice& primary_key, + const WideColumns& primary_columns) { assert(cfh); constexpr bool assume_tracked = true; @@ -484,6 +495,57 @@ class SecondaryIndexMixin : public Txn { }); } + template <typename DeletePrimaryEntry> + Status DeletelikeWithSecondaryIndices( + ColumnFamilyHandle* column_family, const Slice& key, bool do_validate, + DeletePrimaryEntry&& delete_primary_entry) { + if (!column_family) { + column_family = Txn::DefaultColumnFamily(); + } + + { + const Status s = RemoveSecondaryEntries(column_family, key, do_validate); + if (!s.ok()) { + return s; + } + } + + { + const Status s = delete_primary_entry(column_family, key); + if (!s.ok()) { + return s; + } + } + + return Status::OK(); + } + + Status DeleteWithSecondaryIndices(ColumnFamilyHandle* column_family, + const Slice& key, bool do_validate) { + return DeletelikeWithSecondaryIndices( + column_family, key, do_validate, + [&](ColumnFamilyHandle* cfh, const Slice& primary_key) { + assert(cfh); + + constexpr bool assume_tracked = true; + + return Txn::Delete(cfh, primary_key, assume_tracked); + }); + } + + Status SingleDeleteWithSecondaryIndices(ColumnFamilyHandle* column_family, + const Slice& key, bool do_validate) { + return DeletelikeWithSecondaryIndices( + column_family, key, do_validate, + [&](ColumnFamilyHandle* cfh, const Slice& primary_key) { + assert(cfh); + + constexpr bool assume_tracked = true; + + return Txn::SingleDelete(cfh, primary_key, assume_tracked); + }); + } + const std::vector<std::shared_ptr<SecondaryIndex>>* secondary_indices_; };