From f04356e660d0607548161657fb99750ba8fd9c52 Mon Sep 17 00:00:00 2001 From: sdong Date: Mon, 28 Jul 2014 15:28:53 -0700 Subject: [PATCH] Add DB::GetIntProperty() to return integer properties to be returned as integers Summary: We have quite some properties that are integers and we are adding more. Add a function to directly return them as an integer, instead of a string Test Plan: Add several unit test checks Reviewers: yhchiang, igor, dhruba, haobo, ljin Reviewed By: ljin Subscribers: yoshinorim, leveldb Differential Revision: https://reviews.facebook.net/D20637 --- HISTORY.md | 1 + db/db_impl.cc | 9 ++++++ db/db_impl.h | 3 ++ db/db_test.cc | 17 ++++++++++ db/internal_stats.cc | 40 ++++++++++++++++++------ db/internal_stats.h | 8 +++-- include/rocksdb/db.h | 8 +++++ include/rocksdb/utilities/stackable_db.h | 8 ++++- 8 files changed, 81 insertions(+), 13 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 02aa01695..034676b26 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -11,6 +11,7 @@ * Moved include/utilities/*.h to include/rocksdb/utilities/*.h * Statistics APIs now take uint32_t as type instead of Tickers. Also make two access functions getTickerCount and histogramData const * Add DB property rocksdb.estimate-num-keys, estimated number of live keys in DB. +* Add DB::GetIntProperty(), which returns DB properties that are integer as uint64_t. ## 3.3.0 (7/10/2014) ### New Features diff --git a/db/db_impl.cc b/db/db_impl.cc index ebf63a2fc..f57e8c687 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -4372,6 +4372,15 @@ bool DBImpl::GetProperty(ColumnFamilyHandle* column_family, return cfd->internal_stats()->GetProperty(property_type, property, value); } +bool DBImpl::GetIntProperty(ColumnFamilyHandle* column_family, + const Slice& property, uint64_t* value) { + auto cfh = reinterpret_cast(column_family); + auto cfd = cfh->cfd(); + DBPropertyType property_type = GetPropertyType(property); + MutexLock l(&mutex_); + return cfd->internal_stats()->GetIntProperty(property_type, property, value); +} + void DBImpl::GetApproximateSizes(ColumnFamilyHandle* column_family, const Range* range, int n, uint64_t* sizes) { // TODO(opt): better implementation diff --git a/db/db_impl.h b/db/db_impl.h index df0607059..7fcd550b0 100644 --- a/db/db_impl.h +++ b/db/db_impl.h @@ -96,6 +96,9 @@ class DBImpl : public DB { using DB::GetProperty; virtual bool GetProperty(ColumnFamilyHandle* column_family, const Slice& property, std::string* value); + using DB::GetIntProperty; + virtual bool GetIntProperty(ColumnFamilyHandle* column_family, + const Slice& property, uint64_t* value) override; using DB::GetApproximateSizes; virtual void GetApproximateSizes(ColumnFamilyHandle* column_family, const Range* range, int n, uint64_t* sizes); diff --git a/db/db_test.cc b/db/db_test.cc index ae5145266..b56308eec 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -2486,6 +2486,7 @@ TEST(DBTest, GetProperty) { std::string big_value(1000000 * 2, 'x'); std::string num; + uint64_t int_num; SetPerfLevel(kEnableTime); ASSERT_OK(dbfull()->Put(writeOpt, "k1", big_value)); @@ -2512,6 +2513,17 @@ TEST(DBTest, GetProperty) { ASSERT_EQ(num, "0"); ASSERT_TRUE(dbfull()->GetProperty("rocksdb.estimate-num-keys", &num)); ASSERT_EQ(num, "4"); + // Verify the same set of properties through GetIntProperty + ASSERT_TRUE( + dbfull()->GetIntProperty("rocksdb.num-immutable-mem-table", &int_num)); + ASSERT_EQ(int_num, 2U); + ASSERT_TRUE( + dbfull()->GetIntProperty("rocksdb.mem-table-flush-pending", &int_num)); + ASSERT_EQ(int_num, 1U); + ASSERT_TRUE(dbfull()->GetIntProperty("rocksdb.compaction-pending", &int_num)); + ASSERT_EQ(int_num, 0); + ASSERT_TRUE(dbfull()->GetIntProperty("rocksdb.estimate-num-keys", &int_num)); + ASSERT_EQ(int_num, 4); sleeping_task_high.WakeUp(); sleeping_task_high.WaitUntilDone(); @@ -6604,6 +6616,11 @@ class ModelDB: public DB { const Slice& property, std::string* value) { return false; } + using DB::GetIntProperty; + virtual bool GetIntProperty(ColumnFamilyHandle* column_family, + const Slice& property, uint64_t* value) override { + return false; + } using DB::GetApproximateSizes; virtual void GetApproximateSizes(ColumnFamilyHandle* column_family, const Range* range, int n, uint64_t* sizes) { diff --git a/db/internal_stats.cc b/db/internal_stats.cc index bc5799245..730e36b52 100644 --- a/db/internal_stats.cc +++ b/db/internal_stats.cc @@ -126,6 +126,15 @@ DBPropertyType GetPropertyType(const Slice& property) { bool InternalStats::GetProperty(DBPropertyType property_type, const Slice& property, std::string* value) { + if (property_type > kStartIntTypes) { + uint64_t int_value; + bool ret_value = GetIntProperty(property_type, property, &int_value); + if (ret_value) { + *value = std::to_string(int_value); + } + return ret_value; + } + Version* current = cfd_->current(); Slice in = property; @@ -179,40 +188,51 @@ bool InternalStats::GetProperty(DBPropertyType property_type, case kSsTables: *value = current->DebugString(); return true; + default: + return false; + } +} + +bool InternalStats::GetIntProperty(DBPropertyType property_type, + const Slice& property, + uint64_t* value) const { + Version* current = cfd_->current(); + + switch (property_type) { case kNumImmutableMemTable: - *value = std::to_string(cfd_->imm()->size()); + *value = cfd_->imm()->size(); return true; case kMemtableFlushPending: // Return number of mem tables that are ready to flush (made immutable) - *value = std::to_string(cfd_->imm()->IsFlushPending() ? 1 : 0); + *value = (cfd_->imm()->IsFlushPending() ? 1 : 0); return true; case kCompactionPending: // 1 if the system already determines at least one compacdtion is needed. // 0 otherwise, - *value = std::to_string(current->NeedsCompaction() ? 1 : 0); + *value = (current->NeedsCompaction() ? 1 : 0); return true; case kBackgroundErrors: // Accumulated number of errors in background flushes or compactions. - *value = std::to_string(GetBackgroundErrorCount()); + *value = GetBackgroundErrorCount(); return true; case kCurSizeActiveMemTable: // Current size of the active memtable - *value = std::to_string(cfd_->mem()->ApproximateMemoryUsage()); + *value = cfd_->mem()->ApproximateMemoryUsage(); return true; case kNumEntriesInMutableMemtable: // Current size of the active memtable - *value = std::to_string(cfd_->mem()->GetNumEntries()); + *value = cfd_->mem()->GetNumEntries(); return true; case kNumEntriesInImmutableMemtable: // Current size of the active memtable - *value = std::to_string(cfd_->imm()->current()->GetTotalNumEntries()); + *value = cfd_->imm()->current()->GetTotalNumEntries(); return true; case kEstimatedNumKeys: // Estimate number of entries in the column family: // Use estimated entries in tables + total entries in memtables. - *value = std::to_string(cfd_->mem()->GetNumEntries() + - cfd_->imm()->current()->GetTotalNumEntries() + - current->GetEstimatedActiveKeys()); + *value = cfd_->mem()->GetNumEntries() + + cfd_->imm()->current()->GetTotalNumEntries() + + current->GetEstimatedActiveKeys(); return true; default: return false; diff --git a/db/internal_stats.h b/db/internal_stats.h index 25ed871b4..8490937dc 100644 --- a/db/internal_stats.h +++ b/db/internal_stats.h @@ -21,13 +21,15 @@ namespace rocksdb { class MemTableList; class DBImpl; -enum DBPropertyType { +enum DBPropertyType : uint32_t { + kUnknown, kNumFilesAtLevel, // Number of files at a specific level kLevelStats, // Return number of files and total sizes of each level kCFStats, // Return general statitistics of CF kDBStats, // Return general statitistics of DB kStats, // Return general statitistics of both DB and CF kSsTables, // Return a human readable string of current SST files + kStartIntTypes, // ---- Dummy value to indicate the start of integer values kNumImmutableMemTable, // Return number of immutable mem tables kMemtableFlushPending, // Return 1 if mem table flushing is pending, // otherwise 0. @@ -39,7 +41,6 @@ enum DBPropertyType { kNumEntriesInImmutableMemtable, // Return sum of number of entries in all // the immutable mem tables. kEstimatedNumKeys, // Estimated total number of keys in the database. - kUnknown, }; extern DBPropertyType GetPropertyType(const Slice& property); @@ -193,6 +194,9 @@ class InternalStats { bool GetProperty(DBPropertyType property_type, const Slice& property, std::string* value); + bool GetIntProperty(DBPropertyType property_type, const Slice& property, + uint64_t* value) const; + private: void DumpDBStats(std::string* value); void DumpCFStats(std::string* value); diff --git a/include/rocksdb/db.h b/include/rocksdb/db.h index c83e4d7ad..d9be6b427 100644 --- a/include/rocksdb/db.h +++ b/include/rocksdb/db.h @@ -307,6 +307,14 @@ class DB { return GetProperty(DefaultColumnFamily(), property, value); } + // Similar to GetProperty(), but only works for a subset of properties whose + // return value is an integer. Return the value by integer. + virtual bool GetIntProperty(ColumnFamilyHandle* column_family, + const Slice& property, uint64_t* value) = 0; + virtual bool GetIntProperty(const Slice& property, uint64_t* value) { + return GetIntProperty(DefaultColumnFamily(), property, value); + } + // For each i in [0,n-1], store in "sizes[i]", the approximate // file system space used by keys in "[range[i].start .. range[i].limit)". // diff --git a/include/rocksdb/utilities/stackable_db.h b/include/rocksdb/utilities/stackable_db.h index 5c8c7fe6e..417378f5d 100644 --- a/include/rocksdb/utilities/stackable_db.h +++ b/include/rocksdb/utilities/stackable_db.h @@ -107,7 +107,13 @@ class StackableDB : public DB { using DB::GetProperty; virtual bool GetProperty(ColumnFamilyHandle* column_family, const Slice& property, std::string* value) override { - return db_->GetProperty(column_family, property, value); + return db_->GetProperty(column_family, property, value); + } + + using DB::GetIntProperty; + virtual bool GetIntProperty(ColumnFamilyHandle* column_family, + const Slice& property, uint64_t* value) override { + return db_->GetIntProperty(column_family, property, value); } using DB::GetApproximateSizes;