rocksdb/monitoring/histogram.h
leipeng 97b30dee5b improve-histogram-performance: remove valueIndexMap_ (#8625)
Summary:
`valueIndexMap_` in histogram is redundant and search in `valueIndexMap_` is slower than search in `bucketValues_`.

this PR delete `valueIndexMap_` and search in `bucketValues_` by `std::lower_bound`

Pull Request resolved: https://github.com/facebook/rocksdb/pull/8625

Reviewed By: zhichao-cao

Differential Revision: D31613386

Pulled By: ajkr

fbshipit-source-id: d7415d724f5c8f41f80cbe82afd7467cfad6f009
2021-10-14 14:45:20 -07:00

149 lines
4.4 KiB
C++

// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// 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.
#pragma once
#include "rocksdb/statistics.h"
#include <cassert>
#include <string>
#include <vector>
#include <map>
#include <mutex>
namespace ROCKSDB_NAMESPACE {
class HistogramBucketMapper {
public:
HistogramBucketMapper();
// converts a value to the bucket index.
size_t IndexForValue(uint64_t value) const;
// number of buckets required.
size_t BucketCount() const {
return bucketValues_.size();
}
uint64_t LastValue() const {
return maxBucketValue_;
}
uint64_t FirstValue() const {
return minBucketValue_;
}
uint64_t BucketLimit(const size_t bucketNumber) const {
assert(bucketNumber < BucketCount());
return bucketValues_[bucketNumber];
}
private:
std::vector<uint64_t> bucketValues_;
uint64_t maxBucketValue_;
uint64_t minBucketValue_;
};
struct HistogramStat {
HistogramStat();
~HistogramStat() {}
HistogramStat(const HistogramStat&) = delete;
HistogramStat& operator=(const HistogramStat&) = delete;
void Clear();
bool Empty() const;
void Add(uint64_t value);
void Merge(const HistogramStat& other);
inline uint64_t min() const { return min_.load(std::memory_order_relaxed); }
inline uint64_t max() const { return max_.load(std::memory_order_relaxed); }
inline uint64_t num() const { return num_.load(std::memory_order_relaxed); }
inline uint64_t sum() const { return sum_.load(std::memory_order_relaxed); }
inline uint64_t sum_squares() const {
return sum_squares_.load(std::memory_order_relaxed);
}
inline uint64_t bucket_at(size_t b) const {
return buckets_[b].load(std::memory_order_relaxed);
}
double Median() const;
double Percentile(double p) const;
double Average() const;
double StandardDeviation() const;
void Data(HistogramData* const data) const;
std::string ToString() const;
// To be able to use HistogramStat as thread local variable, it
// cannot have dynamic allocated member. That's why we're
// using manually values from BucketMapper
std::atomic_uint_fast64_t min_;
std::atomic_uint_fast64_t max_;
std::atomic_uint_fast64_t num_;
std::atomic_uint_fast64_t sum_;
std::atomic_uint_fast64_t sum_squares_;
std::atomic_uint_fast64_t buckets_[109]; // 109==BucketMapper::BucketCount()
const uint64_t num_buckets_;
};
class Histogram {
public:
Histogram() {}
virtual ~Histogram() {};
virtual void Clear() = 0;
virtual bool Empty() const = 0;
virtual void Add(uint64_t value) = 0;
virtual void Merge(const Histogram&) = 0;
virtual std::string ToString() const = 0;
virtual const char* Name() const = 0;
virtual uint64_t min() const = 0;
virtual uint64_t max() const = 0;
virtual uint64_t num() const = 0;
virtual double Median() const = 0;
virtual double Percentile(double p) const = 0;
virtual double Average() const = 0;
virtual double StandardDeviation() const = 0;
virtual void Data(HistogramData* const data) const = 0;
};
class HistogramImpl : public Histogram {
public:
HistogramImpl() { Clear(); }
HistogramImpl(const HistogramImpl&) = delete;
HistogramImpl& operator=(const HistogramImpl&) = delete;
virtual void Clear() override;
virtual bool Empty() const override;
virtual void Add(uint64_t value) override;
virtual void Merge(const Histogram& other) override;
void Merge(const HistogramImpl& other);
virtual std::string ToString() const override;
virtual const char* Name() const override { return "HistogramImpl"; }
virtual uint64_t min() const override { return stats_.min(); }
virtual uint64_t max() const override { return stats_.max(); }
virtual uint64_t num() const override { return stats_.num(); }
virtual double Median() const override;
virtual double Percentile(double p) const override;
virtual double Average() const override;
virtual double StandardDeviation() const override;
virtual void Data(HistogramData* const data) const override;
virtual ~HistogramImpl() {}
private:
HistogramStat stats_;
std::mutex mutex_;
};
} // namespace ROCKSDB_NAMESPACE