com.twitter.common.stats.PrintableHistogram.java Source code

Java tutorial

Introduction

Here is the source code for com.twitter.common.stats.PrintableHistogram.java

Source

// =================================================================================================
// Copyright 2011 Twitter, Inc.
// -------------------------------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this work except in compliance with the License.
// You may obtain a copy of the License in the LICENSE file, or 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.
// =================================================================================================

package com.twitter.common.stats;

import com.google.common.base.Preconditions;

public class PrintableHistogram {
    private double[] bucketBoundaries;
    private int[] bucketCounts;
    private int totalCount = 0;

    /**
     * Creates a histogram with the given bucket boundaries.  The boundaries
     * 0 and infinity are implicitly added.
     *
     * @param buckets Boundaries for histogram buckets.
     */
    public PrintableHistogram(double... buckets) {
        Preconditions.checkState(buckets[0] != 0);

        bucketBoundaries = new double[buckets.length + 2];
        bucketBoundaries[0] = 0;
        bucketCounts = new int[buckets.length + 2];
        for (int i = 0; i < buckets.length; i++) {
            if (i > 0) {
                Preconditions.checkState(buckets[i] > buckets[i - 1], "Bucket %f must be greater than %f.",
                        buckets[i], buckets[i - 1]);
            }
            bucketCounts[i] = 0;
            bucketBoundaries[i + 1] = buckets[i];
        }

        bucketBoundaries[bucketBoundaries.length - 1] = Integer.MAX_VALUE;
    }

    public void addValue(double value) {
        addValue(value, 1);
    }

    public void addValue(double value, int count) {
        Preconditions.checkState(value >= 0);
        Preconditions.checkState(count >= 0);
        Preconditions.checkState(bucketBoundaries.length > 1);
        int bucketId = -1;
        for (double boundary : bucketBoundaries) {
            if (value <= boundary) {
                break;
            }
            bucketId++;
        }

        bucketId = Math.max(0, bucketId);
        bucketId = Math.min(bucketCounts.length - 1, bucketId);
        bucketCounts[bucketId] += count;
        totalCount += count;
    }

    public double getBucketRatio(int bucketId) {
        Preconditions.checkState(bucketId >= 0);
        Preconditions.checkState(bucketId < bucketCounts.length);
        return (double) bucketCounts[bucketId] / totalCount;
    }

    public String toString() {
        StringBuilder display = new StringBuilder();
        display.append("Histogram: ");
        for (int bucketId = 0; bucketId < bucketCounts.length - 1; bucketId++) {
            display.append(
                    String.format("\n(%g - %g]\n\t", bucketBoundaries[bucketId], bucketBoundaries[bucketId + 1]));
            for (int i = 0; i < getBucketRatio(bucketId) * 100; i++) {
                display.append('#');
            }
            display.append(String.format(" %.2g%% (%d)", getBucketRatio(bucketId) * 100, bucketCounts[bucketId]));
        }

        return display.toString();
    }
}