Index: infra_libs/ts_mon/common/distribution.py |
diff --git a/infra_libs/ts_mon/common/distribution.py b/infra_libs/ts_mon/common/distribution.py |
deleted file mode 100644 |
index 44c28c1978b741f076f8771ef905f325b81f890e..0000000000000000000000000000000000000000 |
--- a/infra_libs/ts_mon/common/distribution.py |
+++ /dev/null |
@@ -1,124 +0,0 @@ |
-# Copyright 2015 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. |
- |
-import bisect |
-import collections |
- |
- |
-class Bucketer(object): |
- """Bucketing function for histograms recorded by the Distribution class.""" |
- |
- def __init__(self, width, growth_factor, num_finite_buckets): |
- """The bucket sizes are controlled by width and growth_factor, and the total |
- number of buckets is set by num_finite_buckets: |
- |
- Args: |
- width: fixed size of each bucket. |
- growth_factor: if non-zero, the size of each bucket increases by another |
- multiplicative factor of this factor (see lower bound formula below). |
- num_finite_buckets: the number of finite buckets. There are two |
- additional buckets - an underflow and an overflow bucket - that have |
- lower and upper bounds of Infinity. |
- |
- Specify a width for fixed-size buckets or specify a growth_factor for bucket |
- sizes that follow a geometric progression. Specifying both is valid as |
- well:: |
- |
- lower bound of bucket i = width * i + growth_factor ^ (i - 1) |
- """ |
- |
- if num_finite_buckets < 0: |
- raise ValueError('num_finite_buckets must be >= 0 (was %d)' % |
- num_finite_buckets) |
- |
- self.width = width |
- self.growth_factor = growth_factor |
- self.num_finite_buckets = num_finite_buckets |
- self.total_buckets = num_finite_buckets + 2 |
- self.underflow_bucket = 0 |
- self.overflow_bucket = self.total_buckets - 1 |
- |
- self._lower_bounds = list(self._generate_lower_bounds()) |
- |
- def _generate_lower_bounds(self): |
- yield float('-Inf') |
- yield 0 |
- |
- previous = 0 |
- for i in xrange(self.num_finite_buckets): |
- lower_bound = self.width * (i + 1) |
- if self.growth_factor != 0: |
- lower_bound += self.growth_factor ** i |
- |
- if lower_bound <= previous: |
- raise ValueError('bucket boundaries must be monotonically increasing') |
- yield lower_bound |
- previous = lower_bound |
- |
- def bucket_for_value(self, value): |
- """Returns the index of the bucket that this value belongs to.""" |
- |
- # bisect.bisect_left is wrong because the buckets are of [lower, upper) form |
- return bisect.bisect(self._lower_bounds, value) - 1 |
- |
- def bucket_boundaries(self, bucket): |
- """Returns a tuple that is the [lower, upper) bounds of this bucket. |
- |
- The lower bound of the first bucket is -Infinity, and the upper bound of the |
- last bucket is +Infinity. |
- """ |
- |
- if bucket < 0 or bucket >= self.total_buckets: |
- raise IndexError('bucket %d out of range' % bucket) |
- if bucket == self.total_buckets - 1: |
- return (self._lower_bounds[bucket], float('Inf')) |
- return (self._lower_bounds[bucket], self._lower_bounds[bucket + 1]) |
- |
- def all_bucket_boundaries(self): |
- """Generator that produces the [lower, upper) bounds of all buckets. |
- |
- This is equivalent to calling:: |
- |
- (b.bucket_boundaries(i) for i in xrange(b.total_buckets)) |
- |
- but is more efficient. |
- """ |
- |
- lower = self._lower_bounds[0] |
- for i in xrange(1, self.total_buckets): |
- upper = self._lower_bounds[i] |
- yield (lower, upper) |
- lower = upper |
- |
- yield (lower, float('Inf')) |
- |
- |
-def FixedWidthBucketer(width, num_finite_buckets=100): |
- """Convenience function that returns a fixed width Bucketer.""" |
- return Bucketer(width=width, growth_factor=0.0, |
- num_finite_buckets=num_finite_buckets) |
- |
- |
-def GeometricBucketer(growth_factor=10**0.2, num_finite_buckets=100): |
- """Convenience function that returns a geometric progression Bucketer.""" |
- return Bucketer(width=0, growth_factor=growth_factor, |
- num_finite_buckets=num_finite_buckets) |
- |
- |
-class Distribution(object): |
- """Holds a histogram distribution. |
- |
- Buckets are chosen for values by the provided Bucketer. |
- """ |
- |
- def __init__(self, bucketer): |
- self.bucketer = bucketer |
- self.sum = 0 |
- self.count = 0 |
- self.buckets = collections.defaultdict(int) |
- |
- def add(self, value): |
- self.buckets[self.bucketer.bucket_for_value(value)] += 1 |
- self.sum += value |
- self.count += 1 |