diff --git a/db/column_family.cc b/db/column_family.cc index e63455aa26d785aae42f5cf067c57fa1fc2e04b2..619bd3360fba10b2272eb6bb3b8aab18afccd2e6 100644 --- a/db/column_family.cc +++ b/db/column_family.cc @@ -45,6 +45,11 @@ ColumnFamilyHandleImpl::ColumnFamilyHandleImpl( ColumnFamilyHandleImpl::~ColumnFamilyHandleImpl() { if (cfd_ != nullptr) { +#ifndef ROCKSDB_LITE + for (auto& listener : cfd_->ioptions()->listeners) { + listener->OnColumnFamilyHandleDeletionStarted(this); + } +#endif // ROCKSDB_LITE // Job id == 0 means that this is not our background process, but rather // user thread JobContext job_context(0); diff --git a/db/listener_test.cc b/db/listener_test.cc index 000fba683657652b248e749731027f5946bbea19..00cabb6a17bdfccb3be9b8b439567a61aa83d7e2 100644 --- a/db/listener_test.cc +++ b/db/listener_test.cc @@ -754,8 +754,43 @@ TEST_F(EventListenerTest, MemTableSealedListenerTest) { ASSERT_OK(Flush()); } } -} // namespace rocksdb +class ColumnFamilyHandleDeletionStartedListener : public EventListener { + private: + std::vector cfs_; + int counter; + + public: + explicit ColumnFamilyHandleDeletionStartedListener( + const std::vector& cfs) + : cfs_(cfs), counter(0) { + cfs_.insert(cfs_.begin(), kDefaultColumnFamilyName); + } + void OnColumnFamilyHandleDeletionStarted( + ColumnFamilyHandle* handle) override { + ASSERT_EQ(cfs_[handle->GetID()], handle->GetName()); + counter++; + } + int getCounter() { return counter; } +}; + +TEST_F(EventListenerTest, ColumnFamilyHandleDeletionStartedListenerTest) { + std::vector cfs{"pikachu", "eevee", "Mewtwo"}; + auto listener = + std::make_shared(cfs); + Options options; + options.create_if_missing = true; + options.listeners.push_back(listener); + CreateAndReopenWithCF(cfs, options); + ASSERT_EQ(handles_.size(), 4); + delete handles_[3]; + delete handles_[2]; + delete handles_[1]; + handles_.resize(1); + ASSERT_EQ(listener->getCounter(), 3); +} + +} // namespace rocksdb #endif // ROCKSDB_LITE diff --git a/include/rocksdb/listener.h b/include/rocksdb/listener.h index fde0db592df4969ee27bb416e36f5f6b6d65acc0..06a48cad273cf41d7fa1997952bcfcf051f78c8f 100644 --- a/include/rocksdb/listener.h +++ b/include/rocksdb/listener.h @@ -18,6 +18,7 @@ typedef std::unordered_map> TablePropertiesCollection; class DB; +class ColumnFamilyHandle; class Status; struct CompactionJobStats; enum CompressionType : unsigned char; @@ -265,7 +266,7 @@ class EventListener { // returned value. virtual void OnTableFileCreationStarted( const TableFileCreationBriefInfo& /*info*/) {} - + // A call-back function for RocksDB which will be called before // a memtable is made immutable. // @@ -279,6 +280,17 @@ class EventListener { virtual void OnMemTableSealed( const MemTableInfo& /*info*/) {} + // A call-back function for RocksDB which will be called before + // a column family handle is deleted. + // + // Note that the this function must be implemented in a way such that + // it should not run for an extended period of time before the function + // returns. Otherwise, RocksDB may be blocked. + // @param handle is a pointer to the column family handle to be deleted + // which will become a dangling pointer after the deletion. + virtual void OnColumnFamilyHandleDeletionStarted(ColumnFamilyHandle* handle) { + } + virtual ~EventListener() {} };