diff --git a/db/db_bench.cc b/db/db_bench.cc index c33179a94d..792b3255f5 100644 --- a/db/db_bench.cc +++ b/db/db_bench.cc @@ -574,10 +574,13 @@ class Benchmark { void PrintStatistics() { if (FLAGS_statistics) { - fprintf(stdout, "File opened:%ld closed:%ld errors:%ld\n", + fprintf(stdout, "File opened:%ld closed:%ld errors:%ld\n" + "Block Cache Hit Count:%ld Block Cache Miss Count:%ld\n", dbstats->getNumFileOpens(), dbstats->getNumFileCloses(), - dbstats->getNumFileErrors()); + dbstats->getNumFileErrors(), + dbstats->getTickerCount(BLOCK_CACHE_HIT), + dbstats->getTickerCount(BLOCK_CACHE_MISS)); } } diff --git a/db/db_statistics.h b/db/db_statistics.h index 350d52c2a5..612817e7a4 100644 --- a/db/db_statistics.h +++ b/db/db_statistics.h @@ -2,16 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. +#include #include +#include + #include "leveldb/statistics.h" #include "port/port.h" #include "util/mutexlock.h" - namespace leveldb { class DBStatistics: public Statistics { public: - DBStatistics() { } + DBStatistics() : allTickers_(TICKER_ENUM_MAX) { } void incNumFileOpens() { MutexLock l(&mu_); @@ -28,8 +30,19 @@ class DBStatistics: public Statistics { numFileErrors_++; } + long getTickerCount(Tickers tickerType) { + assert(tickerType < MAX_NO_TICKERS); + return allTickers_[tickerType].getCount(); + } + + void recordTick(Tickers tickerType) { + assert(tickerType < MAX_NO_TICKERS); + allTickers_[tickerType].recordTick(); + } + private: - port::Mutex mu_; + port::Mutex mu_; + std::vector allTickers_; }; } diff --git a/include/leveldb/statistics.h b/include/leveldb/statistics.h index 3286daa322..77280d879e 100644 --- a/include/leveldb/statistics.h +++ b/include/leveldb/statistics.h @@ -7,9 +7,43 @@ namespace leveldb { +/** + * Keep adding ticker's here. + * Any ticker should have a value less than TICKER_ENUM_MAX. + * Add a new ticker by assigning it the current value of TICKER_ENUM_MAX + * And incrementing TICKER_ENUM_MAX. + */ +enum Tickers { + BLOCK_CACHE_MISS = 0, + BLOCK_CACHE_HIT = 1, + TICKER_ENUM_MAX = 2, +}; + + +/** + * A dumb ticker which keeps incrementing through its life time. + * Not thread safe. Locking is currently managed by external leveldb lock + */ +class Ticker { + public: + Ticker() : count_(0) { } + + inline void recordTick() { + count_++; + } + + inline uint64_t getCount() { + return count_; + } + + private: + uint64_t count_; + +}; + // Analyze the performance of a db class Statistics { - public: + public: // Create an Statistics object with default values for all fields. Statistics() : numFileOpens_(0), numFileCloses_(0), numFileErrors_(0) {} @@ -23,12 +57,21 @@ class Statistics { virtual long getNumFileErrors() { return numFileErrors_;} virtual ~Statistics() {} + virtual long getTickerCount(Tickers tickerType) = 0; + virtual void recordTick(Tickers tickerType) = 0; + protected: long numFileOpens_; long numFileCloses_; long numFileErrors_; }; +// Ease of Use functions +inline void RecordTick(Statistics* const statistics, Tickers ticker) { + if (statistics != NULL) { + statistics->recordTick(ticker); + } +}; } // namespace leveldb #endif // STORAGE_LEVELDB_INCLUDE_STATISTICS_H_ diff --git a/table/table.cc b/table/table.cc index 59117ddcbe..3f255204d7 100644 --- a/table/table.cc +++ b/table/table.cc @@ -9,6 +9,7 @@ #include "leveldb/env.h" #include "leveldb/filter_policy.h" #include "leveldb/options.h" +#include "leveldb/statistics.h" #include "table/block.h" #include "table/filter_block.h" #include "table/format.h" @@ -157,6 +158,7 @@ Iterator* Table::BlockReader(void* arg, bool* didIO) { Table* table = reinterpret_cast(arg); Cache* block_cache = table->rep_->options.block_cache; + Statistics* const statistics = table->rep_->options.statistics; Block* block = NULL; Cache::Handle* cache_handle = NULL; @@ -176,6 +178,8 @@ Iterator* Table::BlockReader(void* arg, cache_handle = block_cache->Lookup(key); if (cache_handle != NULL) { block = reinterpret_cast(block_cache->Value(cache_handle)); + + RecordTick(statistics, BLOCK_CACHE_HIT); } else { s = ReadBlock(table->rep_->file, options, handle, &contents); if (s.ok()) { @@ -188,6 +192,8 @@ Iterator* Table::BlockReader(void* arg, if (didIO != NULL) { *didIO = true; // we did some io from storage } + + RecordTick(statistics, BLOCK_CACHE_MISS); } } else { s = ReadBlock(table->rep_->file, options, handle, &contents);