2016-02-10 00:12:00 +01:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
2013-10-16 23:59:46 +02:00
|
|
|
// This source code is licensed under the BSD-style license found in the
|
|
|
|
// LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
// of patent rights can be found in the PATENTS file in the same directory.
|
2017-04-28 02:50:56 +02:00
|
|
|
// This source code is also licensed under the GPLv2 license found in the
|
|
|
|
// COPYING file in the root directory of this source tree.
|
2013-10-16 23:59:46 +02:00
|
|
|
//
|
2011-03-18 23:37:00 +01:00
|
|
|
// 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.
|
|
|
|
|
2013-10-05 07:32:05 +02:00
|
|
|
#pragma once
|
2013-08-23 17:38:13 +02:00
|
|
|
#include "rocksdb/statistics.h"
|
2013-02-15 20:53:17 +01:00
|
|
|
|
2013-01-29 21:23:31 +01:00
|
|
|
#include <cassert>
|
2011-03-18 23:37:00 +01:00
|
|
|
#include <string>
|
2013-01-29 21:23:31 +01:00
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
2016-03-12 01:54:25 +01:00
|
|
|
#include <mutex>
|
2015-07-02 02:21:38 +02:00
|
|
|
|
2013-10-04 06:49:15 +02:00
|
|
|
namespace rocksdb {
|
2011-03-18 23:37:00 +01:00
|
|
|
|
2013-01-29 21:23:31 +01:00
|
|
|
class HistogramBucketMapper {
|
|
|
|
public:
|
|
|
|
|
|
|
|
HistogramBucketMapper();
|
|
|
|
|
|
|
|
// converts a value to the bucket index.
|
2016-03-12 01:54:25 +01:00
|
|
|
size_t IndexForValue(uint64_t value) const;
|
2013-01-29 21:23:31 +01:00
|
|
|
// number of buckets required.
|
|
|
|
|
2014-09-04 16:04:37 +02:00
|
|
|
size_t BucketCount() const {
|
2013-01-29 21:23:31 +01:00
|
|
|
return bucketValues_.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t LastValue() const {
|
|
|
|
return maxBucketValue_;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t FirstValue() const {
|
|
|
|
return minBucketValue_;
|
|
|
|
}
|
|
|
|
|
2014-11-13 20:39:30 +01:00
|
|
|
uint64_t BucketLimit(const size_t bucketNumber) const {
|
2013-01-29 21:23:31 +01:00
|
|
|
assert(bucketNumber < BucketCount());
|
|
|
|
return bucketValues_[bucketNumber];
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const std::vector<uint64_t> bucketValues_;
|
|
|
|
const uint64_t maxBucketValue_;
|
|
|
|
const uint64_t minBucketValue_;
|
|
|
|
std::map<uint64_t, uint64_t> valueIndexMap_;
|
|
|
|
};
|
|
|
|
|
2016-03-12 01:54:25 +01:00
|
|
|
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_[138]; // 138==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 {
|
2011-03-18 23:37:00 +01:00
|
|
|
public:
|
2016-03-12 01:54:25 +01:00
|
|
|
HistogramImpl() { Clear(); }
|
|
|
|
|
|
|
|
HistogramImpl(const HistogramImpl&) = delete;
|
|
|
|
HistogramImpl& operator=(const HistogramImpl&) = delete;
|
2013-02-15 20:53:17 +01:00
|
|
|
|
2016-03-12 01:54:25 +01:00
|
|
|
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);
|
2013-02-15 20:53:17 +01:00
|
|
|
|
2016-03-12 01:54:25 +01:00
|
|
|
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;
|
2013-01-29 21:23:31 +01:00
|
|
|
|
2014-09-04 16:04:37 +02:00
|
|
|
virtual ~HistogramImpl() {}
|
|
|
|
|
2011-03-18 23:37:00 +01:00
|
|
|
private:
|
2016-03-12 01:54:25 +01:00
|
|
|
HistogramStat stats_;
|
|
|
|
std::mutex mutex_;
|
2011-03-18 23:37:00 +01:00
|
|
|
};
|
|
|
|
|
2016-03-12 01:54:25 +01:00
|
|
|
} // namespace rocksdb
|