0
# Core Histogram Operations
1
2
Core histogram functionality for recording integer values and performing basic statistical analysis. These classes provide the foundation for all HdrHistogram operations.
3
4
## AbstractHistogram
5
6
The abstract base class providing core histogram functionality.
7
8
```java { .api }
9
public abstract class AbstractHistogram
10
extends AbstractHistogramBase
11
implements EncodableHistogram, ValueRecorder, Serializable {
12
13
// Constructors
14
protected AbstractHistogram(int numberOfSignificantValueDigits);
15
protected AbstractHistogram(long lowestDiscernibleValue,
16
long highestTrackableValue,
17
int numberOfSignificantValueDigits);
18
protected AbstractHistogram(AbstractHistogram source);
19
}
20
```
21
22
### Recording Values
23
24
```java { .api }
25
// Basic recording methods
26
void recordValue(long value);
27
void recordValueWithCount(long value, long count);
28
void recordValueWithExpectedInterval(long value, long expectedInterval);
29
void recordConvertedDoubleValueWithCount(double value, long count);
30
```
31
32
**Usage Examples:**
33
34
```java
35
// Record individual values
36
histogram.recordValue(1234); // Single measurement
37
histogram.recordValueWithCount(5678, 10); // Value occurred 10 times
38
39
// Record double values (automatically converted to integer representation)
40
histogram.recordConvertedDoubleValueWithCount(12.34, 5); // Convert 12.34 to int
41
42
// Coordinated omission correction
43
// If expecting measurements every 100ms, but got 1500ms due to pause
44
histogram.recordValueWithExpectedInterval(1500, 100);
45
```
46
47
### Statistical Analysis
48
49
```java { .api }
50
// Count and basic statistics
51
long getTotalCount();
52
long getMaxValue();
53
double getMaxValueAsDouble();
54
long getMinValue();
55
long getMinNonZeroValue();
56
double getMean();
57
double getStdDeviation();
58
59
// Percentile queries
60
long getValueAtPercentile(double percentile);
61
double getPercentileAtOrBelowValue(long value);
62
63
// Value-specific queries
64
long getCountAtValue(long value);
65
long getCountBetweenValues(long lowValue, long highValue);
66
```
67
68
**Usage Examples:**
69
70
```java
71
// Basic statistics
72
long totalSamples = histogram.getTotalCount();
73
double averageLatency = histogram.getMean();
74
long maxLatency = histogram.getMaxValue();
75
76
// Percentile analysis
77
long p50 = histogram.getValueAtPercentile(50.0); // Median
78
long p95 = histogram.getValueAtPercentile(95.0); // 95th percentile
79
long p99 = histogram.getValueAtPercentile(99.0); // 99th percentile
80
long p999 = histogram.getValueAtPercentile(99.9); // 99.9th percentile
81
82
// Value analysis
83
long countAt1000 = histogram.getCountAtValue(1000);
84
long countBelow2000 = histogram.getCountBetweenValues(0, 2000);
85
double percentileOf1500 = histogram.getPercentileAtOrBelowValue(1500);
86
```
87
88
### Configuration and Metadata
89
90
```java { .api }
91
// Configuration queries
92
long getLowestDiscernibleValue();
93
long getHighestTrackableValue();
94
int getNumberOfSignificantValueDigits();
95
int getEstimatedFootprintInBytes();
96
97
// Auto-resize support
98
void setAutoResize(boolean autoResize);
99
boolean isAutoResize();
100
boolean supportsAutoResize();
101
102
// Timestamp and tagging
103
long getStartTimeStamp();
104
void setStartTimeStamp(long timestamp);
105
long getEndTimeStamp();
106
void setEndTimeStamp(long timestamp);
107
String getTag();
108
void setTag(String tag);
109
```
110
111
### Histogram Operations
112
113
```java { .api }
114
// Histogram manipulation
115
void reset();
116
void add(AbstractHistogram other);
117
void subtract(AbstractHistogram other);
118
abstract AbstractHistogram copy();
119
abstract AbstractHistogram copyCorrectedForCoordinatedOmission(long expectedInterval);
120
121
// Coordinated omission correction operations
122
void addWhileCorrectingForCoordinatedOmission(AbstractHistogram otherHistogram,
123
long expectedIntervalBetweenValueSamples);
124
void copyInto(AbstractHistogram targetHistogram);
125
void copyIntoCorrectedForCoordinatedOmission(AbstractHistogram targetHistogram,
126
long expectedIntervalBetweenValueSamples);
127
128
// Value shifting (multiply/divide by powers of 2)
129
void shiftValuesLeft(int numberOfBinaryOrdersOfMagnitude);
130
void shiftValuesRight(int numberOfBinaryOrdersOfMagnitude);
131
132
// Comparison operations
133
boolean equals(Object other);
134
int hashCode();
135
String toString();
136
```
137
138
**Usage Examples:**
139
140
```java
141
// Combine histograms
142
AbstractHistogram combined = histogram1.copy();
143
combined.add(histogram2); // Add histogram2's data to combined
144
145
// Coordinated omission correction
146
AbstractHistogram corrected = histogram.copyCorrectedForCoordinatedOmission(100);
147
148
// Add another histogram with coordinated omission correction
149
combined.addWhileCorrectingForCoordinatedOmission(histogram3, 100);
150
151
// Copy into existing histogram (reuse target histogram instance)
152
AbstractHistogram target = new Histogram(3);
153
histogram.copyInto(target); // Copy histogram data into target
154
155
// Copy with coordinated omission correction into existing histogram
156
histogram.copyIntoCorrectedForCoordinatedOmission(target, 100);
157
158
// Scale values (multiply by 2^3 = 8)
159
histogram.shiftValuesLeft(3);
160
161
// Object methods
162
String description = histogram.toString(); // String representation
163
boolean same = histogram1.equals(histogram2); // Compare histograms
164
int hash = histogram.hashCode(); // Hash code for collections
165
166
// Reset for reuse
167
histogram.reset();
168
```
169
170
### Value Equivalence Analysis
171
172
```java { .api }
173
// Value equivalence methods
174
long sizeOfEquivalentValueRange(long value);
175
long lowestEquivalentValue(long value);
176
long highestEquivalentValue(long value);
177
long medianEquivalentValue(long value);
178
long nextNonEquivalentValue(long value);
179
boolean valuesAreEquivalent(long value1, long value2);
180
```
181
182
**Usage Examples:**
183
184
```java
185
// Understand histogram precision
186
long value = 1000;
187
long rangeSize = histogram.sizeOfEquivalentValueRange(value);
188
long lowest = histogram.lowestEquivalentValue(value);
189
long highest = histogram.highestEquivalentValue(value);
190
191
System.out.println("Value " + value + " represents range [" + lowest + ", " + highest + "]");
192
System.out.println("Range size: " + rangeSize);
193
```
194
195
### Iterator Factory Methods
196
197
```java { .api }
198
// Iterator factory methods for data analysis
199
Percentiles percentiles(int percentileTicksPerHalfDistance);
200
LinearBucketValues linearBucketValues(long valueUnitsPerBucket);
201
LogarithmicBucketValues logarithmicBucketValues(long valueUnitsInFirstBucket, double logBase);
202
RecordedValues recordedValues();
203
AllValues allValues();
204
```
205
206
**Usage Examples:**
207
208
```java
209
// Create different iterators for data analysis
210
Percentiles percentiles = histogram.percentiles(5); // 5 ticks per half distance
211
LinearBucketValues linear = histogram.linearBucketValues(1000); // 1000 unit buckets
212
LogarithmicBucketValues log = histogram.logarithmicBucketValues(1000, 2.0); // Base 2
213
RecordedValues recorded = histogram.recordedValues(); // Only recorded values
214
AllValues all = histogram.allValues(); // All possible values
215
216
// Use iterators in for-each loops
217
for (HistogramIterationValue value : percentiles) {
218
System.out.printf("Percentile: %.2f%%, Value: %d%n",
219
value.getPercentile(), value.getValueIteratedTo());
220
}
221
```
222
223
## Histogram
224
225
The standard concrete implementation of AbstractHistogram.
226
227
```java { .api }
228
public class Histogram extends AbstractHistogram {
229
230
// Constructors
231
public Histogram(int numberOfSignificantValueDigits);
232
public Histogram(long highestTrackableValue, int numberOfSignificantValueDigits);
233
public Histogram(long lowestDiscernibleValue,
234
long highestTrackableValue,
235
int numberOfSignificantValueDigits);
236
public Histogram(AbstractHistogram source);
237
238
// Factory methods for deserialization
239
static Histogram decodeFromByteBuffer(ByteBuffer buffer,
240
long minBarForHighestTrackableValue);
241
static Histogram decodeFromCompressedByteBuffer(ByteBuffer buffer,
242
long minBarForHighestTrackableValue);
243
static Histogram fromString(String base64CompressedHistogramString);
244
245
// Implementation methods
246
public Histogram copy();
247
public Histogram copyCorrectedForCoordinatedOmission(long expectedInterval);
248
}
249
```
250
251
**Usage Examples:**
252
253
```java
254
// Create different histogram configurations
255
Histogram autoResize = new Histogram(3); // Auto-resizing, 3 significant digits
256
Histogram fixedRange = new Histogram(1_000_000, 3); // Max value 1M, 3 digits
257
Histogram fullSpec = new Histogram(1, 1_000_000, 3); // Min 1, max 1M, 3 digits
258
259
// Copy constructors
260
Histogram copy = new Histogram(original);
261
Histogram corrected = original.copyCorrectedForCoordinatedOmission(1000);
262
263
// Deserialization
264
byte[] data = getHistogramData();
265
ByteBuffer buffer = ByteBuffer.wrap(data);
266
Histogram restored = Histogram.decodeFromByteBuffer(buffer, 2);
267
```
268
269
## ValueRecorder Interface
270
271
Core interface for value recording functionality.
272
273
```java { .api }
274
public interface ValueRecorder {
275
void recordValue(long value) throws ArrayIndexOutOfBoundsException;
276
void recordValueWithCount(long value, long count) throws ArrayIndexOutOfBoundsException;
277
void recordValueWithExpectedInterval(long value, long expectedInterval)
278
throws ArrayIndexOutOfBoundsException;
279
void reset();
280
}
281
```
282
283
## Encoding and Serialization
284
285
```java { .api }
286
// Encoding methods for data persistence
287
int getNeededByteBufferCapacity();
288
int encodeIntoByteBuffer(ByteBuffer buffer);
289
int encodeIntoCompressedByteBuffer(ByteBuffer targetBuffer, int compressionLevel);
290
int encodeIntoCompressedByteBuffer(ByteBuffer targetBuffer);
291
```
292
293
**Usage Examples:**
294
295
```java
296
// Encode histogram to byte buffer for storage/transmission
297
ByteBuffer buffer = ByteBuffer.allocate(histogram.getNeededByteBufferCapacity());
298
int bytesWritten = histogram.encodeIntoByteBuffer(buffer);
299
300
// Encode with compression
301
ByteBuffer compressedBuffer = ByteBuffer.allocate(histogram.getNeededByteBufferCapacity());
302
int compressedBytes = histogram.encodeIntoCompressedByteBuffer(compressedBuffer, 9);
303
304
// Default compression level
305
int defaultCompressed = histogram.encodeIntoCompressedByteBuffer(compressedBuffer);
306
```
307
308
## Output and Reporting
309
310
```java { .api }
311
// Output methods
312
void outputPercentileDistribution(PrintStream printStream,
313
Double outputValueUnitScalingRatio);
314
void outputPercentileDistribution(PrintStream printStream,
315
int percentileTicksPerHalfDistance,
316
Double outputValueUnitScalingRatio);
317
void outputPercentileDistribution(PrintStream printStream,
318
int percentileTicksPerHalfDistance,
319
Double outputValueUnitScalingRatio,
320
boolean useCsvFormat);
321
```
322
323
**Usage Examples:**
324
325
```java
326
// Output percentile distribution to console
327
histogram.outputPercentileDistribution(System.out, 1000.0); // Scale to milliseconds
328
329
// Output to file with CSV format
330
try (PrintStream out = new PrintStream(new FileOutputStream("latencies.csv"))) {
331
histogram.outputPercentileDistribution(out, 5, 1000.0, true);
332
}
333
```
334
335
## Constructor Parameter Guidelines
336
337
### numberOfSignificantValueDigits (0-5)
338
- **1-2**: Low precision, minimal memory usage
339
- **3**: Good balance for most applications
340
- **4-5**: High precision, increased memory usage
341
342
### Value Range Selection
343
- **Auto-resize**: Use single parameter constructor for dynamic ranges
344
- **Fixed range**: Specify when maximum value is known for memory optimization
345
- **lowestDiscernibleValue**: Usually 1, increase for better precision on larger values
346
347
**Example Configurations:**
348
349
```java
350
// Latency measurement (microseconds): expect 1μs to 1 second
351
Histogram latency = new Histogram(1, 1_000_000, 3);
352
353
// Throughput measurement (operations/second): auto-resize
354
Histogram throughput = new Histogram(3);
355
356
// High precision latency (nanoseconds): 1ns to 10 seconds
357
Histogram preciseLatency = new Histogram(1, 10_000_000_000L, 4);
358
```
359
360
## Thread Safety
361
362
**Histogram** class is **NOT thread-safe**. For concurrent access:
363
- Use external synchronization
364
- Use thread-safe variants like `ConcurrentHistogram`
365
- Use recording patterns like `Recorder` for producer-consumer scenarios
366
367
## Memory Considerations
368
369
Memory usage depends on:
370
- **numberOfSignificantValueDigits**: Higher values use exponentially more memory
371
- **Value range**: Wider ranges require more buckets
372
- **Auto-resize**: Can grow memory usage dynamically
373
374
Estimate memory usage with `getEstimatedFootprintInBytes()` method.