ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, 0);
}
+TEST_F(DBStatisticsTest, ResetStats) {
+ Options options = CurrentOptions();
+ options.create_if_missing = true;
+ options.statistics = rocksdb::CreateDBStatistics();
+ DestroyAndReopen(options);
+ for (int i = 0; i < 2; ++i) {
+ // pick arbitrary ticker and histogram. On first iteration they're zero
+ // because db is unused. On second iteration they're zero due to Reset().
+ ASSERT_EQ(0, TestGetTickerCount(options, NUMBER_KEYS_WRITTEN));
+ HistogramData histogram_data;
+ options.statistics->histogramData(DB_WRITE, &histogram_data);
+ ASSERT_EQ(0.0, histogram_data.max);
+
+ if (i == 0) {
+ // The Put() makes some of the ticker/histogram stats nonzero until we
+ // Reset().
+ ASSERT_OK(Put("hello", "rocksdb"));
+ ASSERT_EQ(1, TestGetTickerCount(options, NUMBER_KEYS_WRITTEN));
+ options.statistics->histogramData(DB_WRITE, &histogram_data);
+ ASSERT_GT(histogram_data.max, 0.0);
+ options.statistics->Reset();
+ }
+ }
+}
+
} // namespace rocksdb
int main(int argc, char** argv) {
uint64_t StatisticsImpl::getTickerCount(uint32_t tickerType) const {
MutexLock lock(&aggregate_lock_);
+ return getTickerCountLocked(tickerType);
+}
+
+uint64_t StatisticsImpl::getTickerCountLocked(uint32_t tickerType) const {
assert(
enable_internal_stats_ ?
tickerType < INTERNAL_TICKER_ENUM_MAX :
void StatisticsImpl::histogramData(uint32_t histogramType,
HistogramData* const data) const {
+ MutexLock lock(&aggregate_lock_);
+ histogramDataLocked(histogramType, data);
+}
+
+void StatisticsImpl::histogramDataLocked(uint32_t histogramType,
+ HistogramData* const data) const {
assert(
enable_internal_stats_ ?
histogramType < INTERNAL_HISTOGRAM_ENUM_MAX :
}
std::string StatisticsImpl::getHistogramString(uint32_t histogramType) const {
+ MutexLock lock(&aggregate_lock_);
assert(enable_internal_stats_ ? histogramType < INTERNAL_HISTOGRAM_ENUM_MAX
: histogramType < HISTOGRAM_ENUM_MAX);
return histograms_[histogramType].getMergedHistogram()->ToString();
void StatisticsImpl::setTickerCount(uint32_t tickerType, uint64_t count) {
{
MutexLock lock(&aggregate_lock_);
- assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
- : tickerType < TICKER_ENUM_MAX);
- if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
- tickers_[tickerType].thread_value->Fold(
- [](void* curr_ptr, void* res) {
- static_cast<std::atomic<uint64_t>*>(curr_ptr)->store(
- 0, std::memory_order_relaxed);
- },
- nullptr /* res */);
- tickers_[tickerType].merged_sum.store(count, std::memory_order_relaxed);
- }
+ setTickerCountLocked(tickerType, count);
}
if (stats_ && tickerType < TICKER_ENUM_MAX) {
stats_->setTickerCount(tickerType, count);
}
}
+void StatisticsImpl::setTickerCountLocked(uint32_t tickerType, uint64_t count) {
+ assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
+ : tickerType < TICKER_ENUM_MAX);
+ if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
+ tickers_[tickerType].thread_value->Fold(
+ [](void* curr_ptr, void* res) {
+ static_cast<std::atomic<uint64_t>*>(curr_ptr)->store(
+ 0, std::memory_order_relaxed);
+ },
+ nullptr /* res */);
+ tickers_[tickerType].merged_sum.store(count, std::memory_order_relaxed);
+ }
+}
+
uint64_t StatisticsImpl::getAndResetTickerCount(uint32_t tickerType) {
uint64_t sum = 0;
{
}
}
+Status StatisticsImpl::Reset() {
+ MutexLock lock(&aggregate_lock_);
+ for (uint32_t i = 0; i < TICKER_ENUM_MAX; ++i) {
+ setTickerCountLocked(i, 0);
+ }
+ for (uint32_t i = 0; i < HISTOGRAM_ENUM_MAX; ++i) {
+ histograms_[i].thread_value->Fold(
+ [](void* curr_ptr, void* res) {
+ static_cast<HistogramImpl*>(curr_ptr)->Clear();
+ },
+ nullptr /* res */);
+ }
+ return Status::OK();
+}
+
namespace {
// a buffer size used for temp string buffers
} // namespace
std::string StatisticsImpl::ToString() const {
+ MutexLock lock(&aggregate_lock_);
std::string res;
res.reserve(20000);
for (const auto& t : TickersNameMap) {
if (t.first < TICKER_ENUM_MAX || enable_internal_stats_) {
char buffer[kTmpStrBufferSize];
snprintf(buffer, kTmpStrBufferSize, "%s COUNT : %" PRIu64 "\n",
- t.second.c_str(), getTickerCount(t.first));
+ t.second.c_str(), getTickerCountLocked(t.first));
res.append(buffer);
}
}
if (h.first < HISTOGRAM_ENUM_MAX || enable_internal_stats_) {
char buffer[kTmpStrBufferSize];
HistogramData hData;
- histogramData(h.first, &hData);
+ histogramDataLocked(h.first, &hData);
snprintf(
buffer, kTmpStrBufferSize,
"%s statistics Percentiles :=> 50 : %f 95 : %f 99 : %f 100 : %f\n",
virtual void recordTick(uint32_t ticker_type, uint64_t count) override;
virtual void measureTime(uint32_t histogram_type, uint64_t value) override;
+ virtual Status Reset() override;
virtual std::string ToString() const override;
virtual bool HistEnabledForType(uint32_t type) const override;
std::shared_ptr<Statistics> stats_shared_;
Statistics* stats_;
bool enable_internal_stats_;
- // Synchronizes setTickerCount()/getTickerCount() operations so partially
- // completed setTickerCount() won't be visible.
+ // Synchronizes anything that operates on other threads' thread-specific data
+ // such that operations like Reset() can be performed atomically.
mutable port::Mutex aggregate_lock_;
// Holds data maintained by each thread for implementing tickers.
std::unique_ptr<HistogramImpl> getMergedHistogram() const;
};
+ uint64_t getTickerCountLocked(uint32_t ticker_type) const;
+ void histogramDataLocked(uint32_t histogram_type,
+ HistogramData* const data) const;
+ void setTickerCountLocked(uint32_t ticker_type, uint64_t count);
+
// Returns the info for this tickerType/thread. It sets a new info with zeroed
// counter if none exists.
ThreadTickerInfo* getThreadTickerInfo(uint32_t ticker_type);