aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/run_tests/performance/massage_qps_stats_helpers.py
blob: 108451cd5522e637db3ea69938c5c7e01e0ef6c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import collections


def _threshold_for_count_below(buckets, boundaries, count_below):
    count_so_far = 0
    for lower_idx in range(0, len(buckets)):
        count_so_far += buckets[lower_idx]
        if count_so_far >= count_below:
            break
    if count_so_far == count_below:
        # this bucket hits the threshold exactly... we should be midway through
        # any run of zero values following the bucket
        for upper_idx in range(lower_idx + 1, len(buckets)):
            if buckets[upper_idx] != 0:
                break
        return (boundaries[lower_idx] + boundaries[upper_idx]) / 2.0
    else:
        # treat values as uniform throughout the bucket, and find where this value
        # should lie
        lower_bound = boundaries[lower_idx]
        upper_bound = boundaries[lower_idx + 1]
        return (upper_bound - (upper_bound - lower_bound) *
                (count_so_far - count_below) / float(buckets[lower_idx]))


def percentile(buckets, pctl, boundaries):
    return _threshold_for_count_below(buckets, boundaries,
                                      sum(buckets) * pctl / 100.0)


def counter(core_stats, name):
    for stat in core_stats['metrics']:
        if stat['name'] == name:
            return int(stat.get('count', 0))


Histogram = collections.namedtuple('Histogram', 'buckets boundaries')


def histogram(core_stats, name):
    for stat in core_stats['metrics']:
        if stat['name'] == name:
            buckets = []
            boundaries = []
            for b in stat['histogram']['buckets']:
                buckets.append(int(b.get('count', 0)))
                boundaries.append(int(b.get('start', 0)))
    return Histogram(buckets=buckets, boundaries=boundaries)