tab_count_metrics.cc 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/tab_count_metrics/tab_count_metrics.h"
  5. #include <limits>
  6. #include "base/check_op.h"
  7. #include "base/notreached.h"
  8. namespace tab_count_metrics {
  9. // These values represent the lower bound for each bucket, and define the
  10. // tab count buckets. The final bucket has no upper bound, and each other
  11. // bucket, i, is bounded above by the lower bound of bucket i + 1.
  12. //
  13. // The buckets were determined from the Tabs.MaxTabsInADay histogram,
  14. // approximating the 25th, 50th, 75th, 95th, and 99th percentiles, but with the
  15. // single and zero tab cases separated.
  16. //
  17. // If adding or removing a bucket, update |kNumTabCountBuckets|,
  18. // |kTabCountBucketMins|, and |kTabCountBucketNames|. If adding,
  19. // removing, or changing bucket ranges, the existing metrics that use these
  20. // functions for emitting histograms should be marked as obsolete, and new
  21. // metrics should be created. This can be accomplished by versioning
  22. // |kTabCountBucketNames|, e.g. ".ByTabCount2.0Tabs", etc., and
  23. // updating the histogram suffixes section of histograms.xml, creating a new
  24. // entry for the new suffixes and marking the old suffixes obsolete.
  25. constexpr size_t kTabCountBucketMins[] = {0, 1, 2, 3, 5, 8, 20, 40};
  26. constexpr const char* kTabBucketNamePrefix[]{".ByTabCount", ".ByLiveTabCount2"};
  27. // Text for the tab count portion of metric names. These need to be kept
  28. // in sync with |kTabCountBucketMins|.
  29. constexpr const char* kTabCountBucketNames[]{
  30. ".0Tabs", ".1Tab", ".2Tabs", ".3To4Tabs",
  31. ".5To7Tabs", ".8To19Tabs", ".20To39Tabs", ".40OrMoreTabs"};
  32. std::string HistogramName(const std::string prefix,
  33. bool live_tabs_only,
  34. size_t bucket) {
  35. static_assert(std::size(kTabCountBucketMins) == kNumTabCountBuckets,
  36. "kTabCountBucketMins must have kNumTabCountBuckets elements.");
  37. static_assert(std::size(kTabCountBucketNames) == kNumTabCountBuckets,
  38. "kTabCountBucketNames must have kNumTabCountBuckets elements.");
  39. DCHECK_LT(bucket, kNumTabCountBuckets);
  40. DCHECK(prefix.length());
  41. return prefix + kTabBucketNamePrefix[live_tabs_only ? 1u : 0u] +
  42. kTabCountBucketNames[bucket];
  43. }
  44. size_t BucketForTabCount(size_t num_tabs) {
  45. for (size_t bucket = 0; bucket < kNumTabCountBuckets; bucket++) {
  46. if (internal::IsInBucket(num_tabs, bucket))
  47. return bucket;
  48. }
  49. // There should be a bucket for any number of tabs >= 0.
  50. NOTREACHED();
  51. return kNumTabCountBuckets;
  52. }
  53. namespace internal {
  54. size_t BucketMin(size_t bucket) {
  55. DCHECK_LT(bucket, kNumTabCountBuckets);
  56. return kTabCountBucketMins[bucket];
  57. }
  58. size_t BucketMax(size_t bucket) {
  59. DCHECK_LT(bucket, kNumTabCountBuckets);
  60. // The last bucket includes everything after the min bucket value.
  61. if (bucket == kNumTabCountBuckets - 1)
  62. return std::numeric_limits<size_t>::max();
  63. return kTabCountBucketMins[bucket + 1] - 1;
  64. }
  65. bool IsInBucket(size_t num_tabs, size_t bucket) {
  66. DCHECK_LT(bucket, kNumTabCountBuckets);
  67. return num_tabs >= BucketMin(bucket) && num_tabs <= BucketMax(bucket);
  68. }
  69. } // namespace internal
  70. } // namespace tab_count_metrics