12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // Copyright 2018 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.
- #include "components/tab_count_metrics/tab_count_metrics.h"
- #include <limits>
- #include "base/check_op.h"
- #include "base/notreached.h"
- namespace tab_count_metrics {
- // These values represent the lower bound for each bucket, and define the
- // tab count buckets. The final bucket has no upper bound, and each other
- // bucket, i, is bounded above by the lower bound of bucket i + 1.
- //
- // The buckets were determined from the Tabs.MaxTabsInADay histogram,
- // approximating the 25th, 50th, 75th, 95th, and 99th percentiles, but with the
- // single and zero tab cases separated.
- //
- // If adding or removing a bucket, update |kNumTabCountBuckets|,
- // |kTabCountBucketMins|, and |kTabCountBucketNames|. If adding,
- // removing, or changing bucket ranges, the existing metrics that use these
- // functions for emitting histograms should be marked as obsolete, and new
- // metrics should be created. This can be accomplished by versioning
- // |kTabCountBucketNames|, e.g. ".ByTabCount2.0Tabs", etc., and
- // updating the histogram suffixes section of histograms.xml, creating a new
- // entry for the new suffixes and marking the old suffixes obsolete.
- constexpr size_t kTabCountBucketMins[] = {0, 1, 2, 3, 5, 8, 20, 40};
- constexpr const char* kTabBucketNamePrefix[]{".ByTabCount", ".ByLiveTabCount2"};
- // Text for the tab count portion of metric names. These need to be kept
- // in sync with |kTabCountBucketMins|.
- constexpr const char* kTabCountBucketNames[]{
- ".0Tabs", ".1Tab", ".2Tabs", ".3To4Tabs",
- ".5To7Tabs", ".8To19Tabs", ".20To39Tabs", ".40OrMoreTabs"};
- std::string HistogramName(const std::string prefix,
- bool live_tabs_only,
- size_t bucket) {
- static_assert(std::size(kTabCountBucketMins) == kNumTabCountBuckets,
- "kTabCountBucketMins must have kNumTabCountBuckets elements.");
- static_assert(std::size(kTabCountBucketNames) == kNumTabCountBuckets,
- "kTabCountBucketNames must have kNumTabCountBuckets elements.");
- DCHECK_LT(bucket, kNumTabCountBuckets);
- DCHECK(prefix.length());
- return prefix + kTabBucketNamePrefix[live_tabs_only ? 1u : 0u] +
- kTabCountBucketNames[bucket];
- }
- size_t BucketForTabCount(size_t num_tabs) {
- for (size_t bucket = 0; bucket < kNumTabCountBuckets; bucket++) {
- if (internal::IsInBucket(num_tabs, bucket))
- return bucket;
- }
- // There should be a bucket for any number of tabs >= 0.
- NOTREACHED();
- return kNumTabCountBuckets;
- }
- namespace internal {
- size_t BucketMin(size_t bucket) {
- DCHECK_LT(bucket, kNumTabCountBuckets);
- return kTabCountBucketMins[bucket];
- }
- size_t BucketMax(size_t bucket) {
- DCHECK_LT(bucket, kNumTabCountBuckets);
- // The last bucket includes everything after the min bucket value.
- if (bucket == kNumTabCountBuckets - 1)
- return std::numeric_limits<size_t>::max();
- return kTabCountBucketMins[bucket + 1] - 1;
- }
- bool IsInBucket(size_t num_tabs, size_t bucket) {
- DCHECK_LT(bucket, kNumTabCountBuckets);
- return num_tabs >= BucketMin(bucket) && num_tabs <= BucketMax(bucket);
- }
- } // namespace internal
- } // namespace tab_count_metrics
|