123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- // SampleVector implements HistogramSamples interface. It is used by all
- // Histogram based classes to store samples.
- #ifndef BASE_METRICS_SAMPLE_VECTOR_H_
- #define BASE_METRICS_SAMPLE_VECTOR_H_
- #include <stddef.h>
- #include <stdint.h>
- #include <memory>
- #include <vector>
- #include "base/atomicops.h"
- #include "base/compiler_specific.h"
- #include "base/gtest_prod_util.h"
- #include "base/metrics/bucket_ranges.h"
- #include "base/metrics/histogram_base.h"
- #include "base/metrics/histogram_samples.h"
- #include "base/metrics/persistent_memory_allocator.h"
- namespace base {
- class BucketRanges;
- class BASE_EXPORT SampleVectorBase : public HistogramSamples {
- public:
- SampleVectorBase(uint64_t id,
- Metadata* meta,
- const BucketRanges* bucket_ranges);
- SampleVectorBase(const SampleVectorBase&) = delete;
- SampleVectorBase& operator=(const SampleVectorBase&) = delete;
- ~SampleVectorBase() override;
- // HistogramSamples:
- void Accumulate(HistogramBase::Sample value,
- HistogramBase::Count count) override;
- HistogramBase::Count GetCount(HistogramBase::Sample value) const override;
- HistogramBase::Count TotalCount() const override;
- std::unique_ptr<SampleCountIterator> Iterator() const override;
- // Get count of a specific bucket.
- HistogramBase::Count GetCountAtIndex(size_t bucket_index) const;
- // Access the bucket ranges held externally.
- const BucketRanges* bucket_ranges() const { return bucket_ranges_; }
- protected:
- bool AddSubtractImpl(
- SampleCountIterator* iter,
- HistogramSamples::Operator op) override; // |op| is ADD or SUBTRACT.
- virtual size_t GetBucketIndex(HistogramBase::Sample value) const;
- // Moves the single-sample value to a mounted "counts" array.
- void MoveSingleSampleToCounts();
- // Mounts (creating if necessary) an array of "counts" for multi-value
- // storage.
- void MountCountsStorageAndMoveSingleSample();
- // Mounts "counts" storage that already exists. This does not attempt to move
- // any single-sample information to that storage as that would violate the
- // "const" restriction that is often used to indicate read-only memory.
- virtual bool MountExistingCountsStorage() const = 0;
- // Creates "counts" storage and returns a pointer to it. Ownership of the
- // array remains with the called method but will never change. This must be
- // called while some sort of lock is held to prevent reentry.
- virtual HistogramBase::Count* CreateCountsStorageWhileLocked() = 0;
- HistogramBase::AtomicCount* counts() {
- return reinterpret_cast<HistogramBase::AtomicCount*>(
- subtle::Acquire_Load(&counts_));
- }
- const HistogramBase::AtomicCount* counts() const {
- return reinterpret_cast<HistogramBase::AtomicCount*>(
- subtle::Acquire_Load(&counts_));
- }
- void set_counts(const HistogramBase::AtomicCount* counts) const {
- subtle::Release_Store(&counts_, reinterpret_cast<uintptr_t>(counts));
- }
- size_t counts_size() const { return bucket_ranges_->bucket_count(); }
- private:
- friend class SampleVectorTest;
- FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts);
- FRIEND_TEST_ALL_PREFIXES(SharedHistogramTest, CorruptSampleCounts);
- // |counts_| is actually a pointer to a HistogramBase::AtomicCount array but
- // is held as an AtomicWord for concurrency reasons. When combined with the
- // single_sample held in the metadata, there are four possible states:
- // 1) single_sample == zero, counts_ == null
- // 2) single_sample != zero, counts_ == null
- // 3) single_sample != zero, counts_ != null BUT IS EMPTY
- // 4) single_sample == zero, counts_ != null and may have data
- // Once |counts_| is set, it can never revert and any existing single-sample
- // must be moved to this storage. It is mutable because changing it doesn't
- // change the (const) data but must adapt if a non-const object causes the
- // storage to be allocated and updated.
- mutable subtle::AtomicWord counts_ = 0;
- // Shares the same BucketRanges with Histogram object.
- const BucketRanges* const bucket_ranges_;
- };
- // A sample vector that uses local memory for the counts array.
- class BASE_EXPORT SampleVector : public SampleVectorBase {
- public:
- explicit SampleVector(const BucketRanges* bucket_ranges);
- SampleVector(uint64_t id, const BucketRanges* bucket_ranges);
- SampleVector(const SampleVector&) = delete;
- SampleVector& operator=(const SampleVector&) = delete;
- ~SampleVector() override;
- private:
- // SampleVectorBase:
- bool MountExistingCountsStorage() const override;
- HistogramBase::Count* CreateCountsStorageWhileLocked() override;
- // Simple local storage for counts.
- mutable std::vector<HistogramBase::AtomicCount> local_counts_;
- };
- // A sample vector that uses persistent memory for the counts array.
- class BASE_EXPORT PersistentSampleVector : public SampleVectorBase {
- public:
- PersistentSampleVector(uint64_t id,
- const BucketRanges* bucket_ranges,
- Metadata* meta,
- const DelayedPersistentAllocation& counts);
- PersistentSampleVector(const PersistentSampleVector&) = delete;
- PersistentSampleVector& operator=(const PersistentSampleVector&) = delete;
- ~PersistentSampleVector() override;
- private:
- // SampleVectorBase:
- bool MountExistingCountsStorage() const override;
- HistogramBase::Count* CreateCountsStorageWhileLocked() override;
- // Persistent storage for counts.
- DelayedPersistentAllocation persistent_counts_;
- };
- // An iterator for sample vectors. This could be defined privately in the .cc
- // file but is here for easy testing.
- class BASE_EXPORT SampleVectorIterator : public SampleCountIterator {
- public:
- SampleVectorIterator(const std::vector<HistogramBase::AtomicCount>* counts,
- const BucketRanges* bucket_ranges);
- SampleVectorIterator(const HistogramBase::AtomicCount* counts,
- size_t counts_size,
- const BucketRanges* bucket_ranges);
- ~SampleVectorIterator() override;
- // SampleCountIterator implementation:
- bool Done() const override;
- void Next() override;
- void Get(HistogramBase::Sample* min,
- int64_t* max,
- HistogramBase::Count* count) const override;
- // SampleVector uses predefined buckets, so iterator can return bucket index.
- bool GetBucketIndex(size_t* index) const override;
- private:
- void SkipEmptyBuckets();
- const HistogramBase::AtomicCount* counts_;
- size_t counts_size_;
- const BucketRanges* bucket_ranges_;
- size_t index_;
- };
- } // namespace base
- #endif // BASE_METRICS_SAMPLE_VECTOR_H_
|