98 lines
2.8 KiB
Java
98 lines
2.8 KiB
Java
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* 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.
|
|
*/
|
|
package com.android.internal.util;
|
|
|
|
import android.annotation.IntRange;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.util.Log;
|
|
|
|
import java.util.Arrays;
|
|
|
|
/**
|
|
* A histogram for positive integers where each bucket is twice the size of the previous one.
|
|
*/
|
|
public class ExponentiallyBucketedHistogram {
|
|
@NonNull
|
|
private final int[] mData;
|
|
|
|
/**
|
|
* Create a new histogram.
|
|
*
|
|
* @param numBuckets The number of buckets. The highest bucket is for all value >=
|
|
* 2<sup>numBuckets - 1</sup>
|
|
*/
|
|
public ExponentiallyBucketedHistogram(@IntRange(from = 1, to = 31) int numBuckets) {
|
|
numBuckets = Preconditions.checkArgumentInRange(numBuckets, 1, 31, "numBuckets");
|
|
|
|
mData = new int[numBuckets];
|
|
}
|
|
|
|
/**
|
|
* Add a new value to the histogram.
|
|
*
|
|
* All values <= 0 are in the first bucket. The last bucket contains all values >=
|
|
* 2<sup>numBuckets - 1</sup>
|
|
*
|
|
* @param value The value to add
|
|
*/
|
|
public void add(int value) {
|
|
if (value <= 0) {
|
|
mData[0]++;
|
|
} else {
|
|
mData[Math.min(mData.length - 1, 32 - Integer.numberOfLeadingZeros(value))]++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear all data from the histogram
|
|
*/
|
|
public void reset() {
|
|
Arrays.fill(mData, 0);
|
|
}
|
|
|
|
/**
|
|
* Write the histogram to the log.
|
|
*
|
|
* @param tag The tag to use when logging
|
|
* @param prefix A custom prefix that is printed in front of the histogram
|
|
*/
|
|
public void log(@NonNull String tag, @Nullable CharSequence prefix) {
|
|
StringBuilder builder = new StringBuilder(prefix);
|
|
builder.append('[');
|
|
|
|
for (int i = 0; i < mData.length; i++) {
|
|
if (i != 0) {
|
|
builder.append(", ");
|
|
}
|
|
|
|
if (i < mData.length - 1) {
|
|
builder.append("<");
|
|
builder.append(1 << i);
|
|
} else {
|
|
builder.append(">=");
|
|
builder.append(1 << (i - 1));
|
|
}
|
|
|
|
builder.append(": ");
|
|
builder.append(mData[i]);
|
|
}
|
|
builder.append("]");
|
|
|
|
Log.d(tag, builder.toString());
|
|
}
|
|
}
|