Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Written by Gil Tene of Azul Systems, and released to the public domain, as explained at http://creativecommons.org/publicdomain/zero/1.0/

Author(s):
Gil Tene
   
   
   package org.HdrHistogram;
   
  import java.io.*;

A floating point values High Dynamic Range (HDR) Histogram

It is important to note that DoubleHistogram is not thread-safe, and does not support safe concurrent recording by multiple threads. If concurrent operation is required, consider usings ConcurrentDoubleHistogram, SynchronizedDoubleHistogram, or(recommended) DoubleRecorder, which are intended for this purpose.

DoubleHistogram supports the recording and analyzing sampled data value counts across a configurable dynamic range of floating point (double) values, with configurable value precision within the range. Dynamic range is expressed as a ratio between the highest and lowest non-zero values trackable within the histogram at any given time. Value precision is expressed as the number of significant [decimal] digits in the value recording, and provides control over value quantization behavior across the value range and the subsequent value resolution at any given level.

Auto-ranging: Unlike integer value based histograms, the specific value range tracked by a DoubleHistogram is not specified upfront. Only the dynamic range of values that the histogram can cover is (optionally) specified. E.g. When a DoubleHistogram is created to track a dynamic range of 3600000000000 (enough to track values from a nanosecond to an hour), values could be recorded into into it in any consistent unit of time as long as the ratio between the highest and lowest non-zero values stays within the specified dynamic range, so recording in units of nanoseconds (1.0 thru 3600000000000.0), milliseconds (0.000001 thru 3600000.0) seconds (0.000000001 thru 3600.0), hours (1/3.6E12 thru 1.0) will all work just as well.

Auto-resizing: When constructed with no specified dynamic range (or when auto-resize is turned on with setAutoResize(boolean)) a DoubleHistogram will auto-resize its dynamic range to include recorded values as they are encountered. Note that recording calls that cause auto-resizing may take longer to execute, as resizing incurs allocation and copying of internal data structures.

Attempts to record non-zero values that range outside of the specified dynamic range (or exceed the limits of of dynamic range when auto-resizing) may results in java.lang.ArrayIndexOutOfBoundsException exceptions, either due to overflow or underflow conditions. These exceptions will only be thrown if recording the value would have resulted in discarding or losing the required value precision of values already recorded in the histogram.

See package description for org.HdrHistogram for details.

  
  public class DoubleHistogram extends EncodableHistogram implements Serializable {
      static final double highestAllowedValueEver// A value that will keep us from multiplying into infinity.
  
      private long configuredHighestToLowestValueRatio;
  
      private volatile double currentLowestValueInAutoRange;
      private volatile double currentHighestValueLimitInAutoRange;
  
  
      volatile double doubleToIntegerValueConversionRatio;
      volatile double integerToDoubleValueConversionRatio;
  
      private boolean autoResize = false;

    
Construct a new auto-resizing DoubleHistogram using a precision stated as a number of significant decimal digits.

Parameters:
numberOfSignificantValueDigits Specifies the precision to use. This is the number of significant decimal digits to which the histogram will maintain value resolution and separation. Must be a non-negative integer between 0 and 5.
  
      public DoubleHistogram(final int numberOfSignificantValueDigits) {
          this(2, numberOfSignificantValueDigitsHistogram.classnull);
          setAutoResize(true);
      }

    
Construct a new DoubleHistogram with the specified dynamic range (provided in highestToLowestValueRatio) and using a precision stated as a number of significant decimal digits.

Parameters:
highestToLowestValueRatio specifies the dynamic range to use
numberOfSignificantValueDigits Specifies the precision to use. This is the number of significant decimal digits to which the histogram will maintain value resolution and separation. Must be a non-negative integer between 0 and 5.
  
      public DoubleHistogram(final long highestToLowestValueRatiofinal int numberOfSignificantValueDigits) {
          this(highestToLowestValueRationumberOfSignificantValueDigitsHistogram.class);
      }

    
Construct a new DoubleHistogram with the specified dynamic range (provided in highestToLowestValueRatio) and using a precision stated as a number of significant decimal digits. The DoubleHistogram will use the specified AbstractHistogram subclass for tracking internal counts (e.g. Histogram, ConcurrentHistogram, SynchronizedHistogram, IntCountsHistogram, ShortCountsHistogram).

Parameters:
highestToLowestValueRatio specifies the dynamic range to use.
numberOfSignificantValueDigits Specifies the precision to use. This is the number of significant decimal digits to which the histogram will maintain value resolution and separation. Must be a non-negative integer between 0 and 5.
internalCountsHistogramClass The class to use for internal counts tracking
 
     protected DoubleHistogram(final long highestToLowestValueRatio,
                            final int numberOfSignificantValueDigits,
                            final Class<? extends AbstractHistograminternalCountsHistogramClass) {
         this(highestToLowestValueRationumberOfSignificantValueDigitsinternalCountsHistogramClassnull);
     }
 
     private DoubleHistogram(final long highestToLowestValueRatio,
                             final int numberOfSignificantValueDigits,
                             final Class<? extends AbstractHistograminternalCountsHistogramClass,
                             AbstractHistogram internalCountsHistogram) {
         this(
                 highestToLowestValueRatio,
                 numberOfSignificantValueDigits,
                 internalCountsHistogramClass,
                 internalCountsHistogram,
                 false
         );
     }
 
     private DoubleHistogram(final long highestToLowestValueRatio,
                            final int numberOfSignificantValueDigits,
                            final Class<? extends AbstractHistograminternalCountsHistogramClass,
                            AbstractHistogram internalCountsHistogram,
                            boolean mimicInternalModel) {
         try {
             if (highestToLowestValueRatio < 2) {
                 throw new IllegalArgumentException("highestToLowestValueRatio must be >= 2");
             }
 
             if ((highestToLowestValueRatio * Math.pow(10.0, numberOfSignificantValueDigits)) >= (1L << 61)) {
                 throw new IllegalArgumentException(
                         "highestToLowestValueRatio * (10^numberOfSignificantValueDigits) must be < (1L << 61)");
             }
             if (internalCountsHistogramClass == AtomicHistogram.class) {
                 throw new IllegalArgumentException(
                         "AtomicHistogram cannot be used as an internal counts histogram (does not support shifting)." +
                                 " Use ConcurrentHistogram instead.");
             }
 
             long integerValueRange = deriveIntegerValueRange(highestToLowestValueRationumberOfSignificantValueDigits);
 
             final AbstractHistogram valuesHistogram;
             double initialLowestValueInAutoRange;
 
             if (internalCountsHistogram == null) {
                 // Create the internal counts histogram:
                 Constructor<? extends AbstractHistogramhistogramConstructor =
                                 internalCountsHistogramClass.getConstructor(long.classlong.classint.class);
 
                 valuesHistogram =
                         histogramConstructor.newInstance(
                                 1L,
                                 (integerValueRange - 1),
                                 numberOfSignificantValueDigits
                         );
 
                 // We want the auto-ranging to tend towards using a value range that will result in using the
                 // lower tracked value ranges and leave the higher end empty unless the range is actually used.
                 // This is most easily done by making early recordings force-shift the lower value limit to
                 // accommodate them (forcing a force-shift for the higher values would achieve the opposite).
                 // We will therefore start with a very high value range, and let the recordings autoAdjust
                 // downwards from there:
                 initialLowestValueInAutoRange = Math.pow(2.0, 800);
             } else if (mimicInternalModel) {
                 Constructor<? extends AbstractHistogramhistogramConstructor =
                                 internalCountsHistogramClass.getConstructor(AbstractHistogram.class);
 
                 valuesHistogram = histogramConstructor.newInstance(internalCountsHistogram);
 
                 initialLowestValueInAutoRange = Math.pow(2.0, 800);
             } else {
                 // Verify that the histogram we got matches:
                 if ((internalCountsHistogram.getLowestDiscernibleValue() != 1) ||
                         (internalCountsHistogram.getHighestTrackableValue() != integerValueRange - 1) ||
                         internalCountsHistogram.getNumberOfSignificantValueDigits() != numberOfSignificantValueDigits) {
                     throw new IllegalStateException("integer values histogram does not match stated parameters.");
                 }
                 valuesHistogram = internalCountsHistogram;
                 // Derive initialLowestValueInAutoRange from valuesHistogram's integerToDoubleValueConversionRatio:
                 initialLowestValueInAutoRange =
                         internalCountsHistogram.getIntegerToDoubleValueConversionRatio() *
                                 internalCountsHistogram.subBucketHalfCount;
             }
 
             // Set our double tracking range and internal histogram:
             init(highestToLowestValueRatioinitialLowestValueInAutoRangevaluesHistogram);
 
         } catch (NoSuchMethodException ex) {
             throw new IllegalArgumentException(ex);
         } catch (IllegalAccessException ex) {
             throw new IllegalArgumentException(ex);
         } catch (InstantiationException ex) {
             throw new IllegalArgumentException(ex);
         } catch (InvocationTargetException ex) {
             throw new IllegalArgumentException(ex);
         }
     }

    
Construct a DoubleHistogram with the same range settings as a given source, duplicating the source's start/end timestamps (but NOT it's contents)

Parameters:
source The source histogram to duplicate
 
     public DoubleHistogram(final DoubleHistogram source) {
         this(source.configuredHighestToLowestValueRatio,
                 source.getNumberOfSignificantValueDigits(),
                 source.integerValuesHistogram.getClass(),
                 source.integerValuesHistogram,
                 true);
         this. = source.autoResize;
         setTrackableValueRange(source.currentLowestValueInAutoRangesource.currentHighestValueLimitInAutoRange);
     }
 
     private void init(final long configuredHighestToLowestValueRatiofinal double lowestTrackableUnitValue,
                       final AbstractHistogram integerValuesHistogram) {
         this. = configuredHighestToLowestValueRatio;
         this. = integerValuesHistogram;
         long internalHighestToLowestValueRatio =
                 deriveInternalHighestToLowestValueRatio(configuredHighestToLowestValueRatio);
         setTrackableValueRange(lowestTrackableUnitValuelowestTrackableUnitValue * internalHighestToLowestValueRatio);
     }
 
     private void setTrackableValueRange(final double lowestValueInAutoRangefinal double highestValueInAutoRange) {
         this. = lowestValueInAutoRange;
         this. = highestValueInAutoRange;
         this. = lowestValueInAutoRange / getLowestTrackingIntegerValue();
     }
 
     //
     //
     // Auto-resizing control:
     //
     //
 
     public boolean isAutoResize() {
         return ;
     }
 
     public void setAutoResize(boolean autoResize) {
         this. = autoResize;
     }
 
     //
     //
     //
     // Value recording support:
     //
     //
     //
 
    
Record a value in the histogram

Parameters:
value The value to be recorded
Throws:
java.lang.ArrayIndexOutOfBoundsException (may throw) if value is cannot be covered by the histogram's range
 
     public void recordValue(final double valuethrows ArrayIndexOutOfBoundsException {
         recordSingleValue(value);
     }

    
Record a value in the histogram (adding to the value's current count)

Parameters:
value The value to be recorded
count The number of occurrences of this value to record
Throws:
java.lang.ArrayIndexOutOfBoundsException (may throw) if value is cannot be covered by the histogram's range
 
     public void recordValueWithCount(final double valuefinal long countthrows ArrayIndexOutOfBoundsException {
         recordCountAtValue(countvalue);
     }

    
Record a value in the histogram.

To compensate for the loss of sampled values when a recorded value is larger than the expected interval between value samples, Histogram will auto-generate an additional series of decreasingly-smaller (down to the expectedIntervalBetweenValueSamples) value records.

Note: This is a at-recording correction method, as opposed to the post-recording correction method provided by copyCorrectedForCoordinatedOmission(double). The use cases for these two methods are mutually exclusive, and only one of the two should be be used on a given data set to correct for the same coordinated omission issue.

See notes in the description of the Histogram calls for an illustration of why this corrective behavior is important.

Parameters:
value The value to record
expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add auto-generated value records as appropriate if value is larger than expectedIntervalBetweenValueSamples
Throws:
java.lang.ArrayIndexOutOfBoundsException (may throw) if value is cannot be covered by the histogram's range
 
     public void recordValueWithExpectedInterval(final double valuefinal double expectedIntervalBetweenValueSamples)
             throws ArrayIndexOutOfBoundsException {
         recordValueWithCountAndExpectedInterval(value, 1, expectedIntervalBetweenValueSamples);
     }
 
     private void recordCountAtValue(final long countfinal double valuethrows ArrayIndexOutOfBoundsException {
         if ((value < ) || (value >= )) {
             // Zero is valid and needs no auto-ranging, but also rare enough that we should deal
             // with it on the slow path...
             autoAdjustRangeForValue(value);
         }
 
         long integerValue = (long) (value * );
         .recordValueWithCount(integerValuecount);
     }
 
     private void recordSingleValue(final double valuethrows ArrayIndexOutOfBoundsException {
         if ((value < ) || (value >= )) {
             // Zero is valid and needs no auto-ranging, but also rare enough that we should deal
             // with it on the slow path...
             autoAdjustRangeForValue(value);
         }
 
         long integerValue = (long) (value * );
         .recordValue(integerValue);
     }
 
     private void recordValueWithCountAndExpectedInterval(final double valuefinal long count,
                                                            final double expectedIntervalBetweenValueSamples)
             throws ArrayIndexOutOfBoundsException {
         recordCountAtValue(countvalue);
         if (expectedIntervalBetweenValueSamples <= 0)
             return;
         for (double missingValue = value - expectedIntervalBetweenValueSamples;
              missingValue >= expectedIntervalBetweenValueSamples;
              missingValue -= expectedIntervalBetweenValueSamples) {
             recordCountAtValue(countmissingValue);
         }
     }
 
     //
     //
     //
     // Shift and auto-ranging support:
     //
     //
     //
 
     private void autoAdjustRangeForValue(final double value) {
         // Zero is always valid, and doesn't need auto-range adjustment:
         if (value == 0.0) {
             return;
         }
         autoAdjustRangeForValueSlowPath(value);
     }
 
     private synchronized void autoAdjustRangeForValueSlowPath(final double value) {
         if (value < ) {
             if (value < 0.0) {
                 throw new ArrayIndexOutOfBoundsException("Negative values cannot be recorded");
             }
             do {
                 int shiftAmount =
                         findCappedContainingBinaryOrderOfMagnitude(
                                 Math.ceil( / value) - 1.0);
                 shiftCoveredRangeToTheRight(shiftAmount);
             } while (value < );
         } else if (value >= ) {
             if (value > ) {
                 throw new ArrayIndexOutOfBoundsException(
                         "Values above " +  + " cannot be recorded");
             }
             do {
                 // If value is an exact whole multiple of currentHighestValueLimitInAutoRange, it "belongs" with
                 // the next level up, as it crosses the limit. With floating point values, the simplest way to
                 // make this shift on exact multiple values happen (but not for any just-smaller-than-exact-multiple
                 // values) is to use a value that is 1 ulp bigger in computing the ratio for the shift amount:
                 int shiftAmount =
                         findCappedContainingBinaryOrderOfMagnitude(
                                 Math.ceil((value + Math.ulp(value)) / ) - 1.0);
                 shiftCoveredRangeToTheLeft(shiftAmount);
             } while (value >= );
         }
     }
 
     private void shiftCoveredRangeToTheRight(final int numberOfBinaryOrdersOfMagnitude) {
         // We are going to adjust the tracked range by effectively shifting it to the right
         // (in the integer shift sense).
         //
         // To counter the right shift of the value multipliers, we need to left shift the internal
         // representation such that the newly shifted integer values will continue to return the
         // same double values.
 
         // Initially, new range is the same as current range, to make sure we correctly recover
         // from a shift failure if one happens:
         double newLowestValueInAutoRange = ;
         double newHighestValueLimitInAutoRange = ;
 
         try {
             double shiftMultiplier = 1.0 / (1L << numberOfBinaryOrdersOfMagnitude);
 
             // First, temporarily change the highest value in auto-range without changing conversion ratios.
             // This is done to force new values higher than the new expected highest value to attempt an
             // adjustment (which is synchronized and will wait behind this one). This ensures that we will
             // not end up with any concurrently recorded values that would need to be discarded if the shift
             // fails. If this shift succeeds, the pending adjustment attempt will end up doing nothing.
              *= shiftMultiplier;
 
             // First shift the values, to give the shift a chance to fail:
 
             // Shift integer histogram left, increasing the recorded integer values for current recordings
             // by a factor of (1 << numberOfBinaryOrdersOfMagnitude):
 
             // (no need to shift any values if all recorded values are at the 0 value level:)
             if (getTotalCount() > .getCountAtIndex(0)) {
                 // Apply the shift:
                 try {
                     .shiftValuesLeft(numberOfBinaryOrdersOfMagnitude);
                 } catch (ArrayIndexOutOfBoundsException ex) {
                     // Failed to shift, try to expand size instead:
                     handleShiftValuesException(numberOfBinaryOrdersOfMagnitudeex);
                     // First expand the highest limit to reflect successful size expansion:
                     newHighestValueLimitInAutoRange /= shiftMultiplier;
                     // Successfully expanded histogram range by numberOfBinaryOrdersOfMagnitude, but not
                     // by shifting (shifting failed because there was not room to shift left into). Instead,
                     // we grew the max value without changing the value mapping. Since we were trying to
                     // shift values left to begin with, trying to shift the left again will work (we now
                     // have room to shift into):
                     .shiftValuesLeft(numberOfBinaryOrdersOfMagnitude);
                 }
             }
             // Shift (or resize) was successful. Adjust new range to reflect:
             newLowestValueInAutoRange *= shiftMultiplier;
             newHighestValueLimitInAutoRange *= shiftMultiplier;
         } finally {
             // Set the new range to either the successfully changed one, or the original one:
             setTrackableValueRange(newLowestValueInAutoRangenewHighestValueLimitInAutoRange);
         }
     }
 
     private void shiftCoveredRangeToTheLeft(final int numberOfBinaryOrdersOfMagnitude) {
         // We are going to adjust the tracked range by effectively shifting it to the right
         // (in the integer shift sense).
         //
         // To counter the left shift of the value multipliers, we need to right shift the internal
         // representation such that the newly shifted integer values will continue to return the
         // same double values.
 
         // Initially, new range is the same as current range, to make sure we correctly recover
         // from a shift failure if one happens:
         double newLowestValueInAutoRange = ;
         double newHighestValueLimitInAutoRange = ;
 
         try {
             double shiftMultiplier = 1.0 * (1L << numberOfBinaryOrdersOfMagnitude);
 
             // First, temporarily change the lowest value in auto-range without changing conversion ratios.
             // This is done to force new values lower than the new expected lowest value to attempt an
             // adjustment (which is synchronized and will wait behind this one). This ensures that we will
             // not end up with any concurrently recorded values that would need to be discarded if the shift
             // fails. If this shift succeeds, the pending adjustment attempt will end up doing nothing.
              *= shiftMultiplier;
 
             // First shift the values, to give the shift a chance to fail:
 
             // Shift integer histogram right, decreasing the recorded integer values for current recordings
             // by a factor of (1 << numberOfBinaryOrdersOfMagnitude):
 
             // (no need to shift any values if all recorded values are at the 0 value level:)
             if (getTotalCount() > .getCountAtIndex(0)) {
                 // Apply the shift:
                 try {
                     .shiftValuesRight(numberOfBinaryOrdersOfMagnitude);
                     // Shift was successful. Adjust new range to reflect:
                     newLowestValueInAutoRange *= shiftMultiplier;
                     newHighestValueLimitInAutoRange *= shiftMultiplier;
                 } catch (ArrayIndexOutOfBoundsException ex) {
                     // Failed to shift, try to expand size instead:
                     handleShiftValuesException(numberOfBinaryOrdersOfMagnitudeex);
                     // Successfully expanded histogram range by numberOfBinaryOrdersOfMagnitude, but not
                     // by shifting (shifting failed because there was not room to shift right into). Instead,
                     // we grew the max value without changing the value mapping. Since we were trying to
                     // shift values right to begin with to make room for a larger value than we had had
                     // been able to fit before, no shift is needed, as the value should now fit. So rather
                     // than shifting and adjusting both lowest and highest limits, we'll end up just
                     // expanding newHighestValueLimitInAutoRange to indicate the newly expanded range.
                     // We therefore reverse-scale the newLowestValueInAutoRange before lating the later
                     // code scale both up:
                     newLowestValueInAutoRange /= shiftMultiplier;
                 }
             }
             // Shift (or resize) was successful. Adjust new range to reflect:
             newLowestValueInAutoRange *= shiftMultiplier;
             newHighestValueLimitInAutoRange *= shiftMultiplier;
         } finally {
             // Set the new range to either the successfully changed one, or the original one:
             setTrackableValueRange(newLowestValueInAutoRangenewHighestValueLimitInAutoRange);
         }
     }
 
     private void handleShiftValuesException(final int numberOfBinaryOrdersOfMagnitudeException ex) {
         if (!) {
             throw new ArrayIndexOutOfBoundsException("value outside of histogram covered range. Caused by: " + ex);
         }
 
         long highestTrackableValue = .getHighestTrackableValue();
         int highestTrackableValueContainingOrderOfMagnitude =
                 findContainingBinaryOrderOfMagnitude(highestTrackableValue);
         long newHighestTrackableValue =
                 (1L << (numberOfBinaryOrdersOfMagnitude + highestTrackableValueContainingOrderOfMagnitude)) - 1;
         if (newHighestTrackableValue < highestTrackableValue) {
             throw new ArrayIndexOutOfBoundsException(
                     "cannot resize histogram covered range beyond (1L << 63) / (1L << " +
                             (.) + ") - 1.\n" +
                             "Caused by:" + ex);
         }
         .resize(newHighestTrackableValue);
         . = newHighestTrackableValue;
          <<= numberOfBinaryOrdersOfMagnitude;
     }
 
     //
     //
     //
     // Clearing support:
     //
     //
     //
 
    
Reset the contents and stats of this histogram
 
     public void reset() {
     }
 
     //
     //
     //
     // Copy support:
     //
     //
     //
 
    
Create a copy of this histogram, complete with data and everything.

Returns:
A distinct copy of this histogram.
 
     public DoubleHistogram copy() {
         final DoubleHistogram targetHistogram =
         .copyInto(targetHistogram.integerValuesHistogram);
         return targetHistogram;
     }

    
Get a copy of this histogram, corrected for coordinated omission.

To compensate for the loss of sampled values when a recorded value is larger than the expected interval between value samples, the new histogram will include an auto-generated additional series of decreasingly-smaller (down to the expectedIntervalBetweenValueSamples) value records for each count found in the current histogram that is larger than the expectedIntervalBetweenValueSamples. Note: This is a post-correction method, as opposed to the at-recording correction method provided by recordValueWithExpectedInterval. The two methods are mutually exclusive, and only one of the two should be be used on a given data set to correct for the same coordinated omission issue. by

See notes in the description of the Histogram calls for an illustration of why this corrective behavior is important.

Parameters:
expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add auto-generated value records as appropriate if value is larger than expectedIntervalBetweenValueSamples
Returns:
a copy of this histogram, corrected for coordinated omission.
 
     public DoubleHistogram copyCorrectedForCoordinatedOmission(final double expectedIntervalBetweenValueSamples) {
         final DoubleHistogram targetHistogram =
         targetHistogram.addWhileCorrectingForCoordinatedOmission(thisexpectedIntervalBetweenValueSamples);
         return targetHistogram;
     }

    
Copy this histogram into the target histogram, overwriting it's contents.

Parameters:
targetHistogram the histogram to copy into
 
     public void copyInto(final DoubleHistogram targetHistogram) {
         targetHistogram.reset();
         targetHistogram.add(this);
         targetHistogram.setEndTimeStamp(.);
     }

    
Copy this histogram, corrected for coordinated omission, into the target histogram, overwriting it's contents. (see copyCorrectedForCoordinatedOmission(double) for more detailed explanation about how correction is applied)

Parameters:
targetHistogram the histogram to copy into
expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add auto-generated value records as appropriate if value is larger than expectedIntervalBetweenValueSamples
 
     public void copyIntoCorrectedForCoordinatedOmission(final DoubleHistogram targetHistogram,
                                                         final double expectedIntervalBetweenValueSamples) {
         targetHistogram.reset();
         targetHistogram.addWhileCorrectingForCoordinatedOmission(thisexpectedIntervalBetweenValueSamples);
         targetHistogram.setEndTimeStamp(.);
     }
 
     //
     //
     //
     // Add support:
     //
     //
     //
 
    
Add the contents of another histogram to this one.

Parameters:
fromHistogram The other histogram.
Throws:
java.lang.ArrayIndexOutOfBoundsException (may throw) if values in fromHistogram's cannot be covered by this histogram's range
 
     public void add(final DoubleHistogram fromHistogramthrows ArrayIndexOutOfBoundsException {
         int arrayLength = fromHistogram.integerValuesHistogram.countsArrayLength;
         AbstractHistogram fromIntegerHistogram = fromHistogram.integerValuesHistogram;
         for (int i = 0; i < arrayLengthi++) {
             long count = fromIntegerHistogram.getCountAtIndex(i);
             if (count > 0) {
                 recordValueWithCount(
                         fromIntegerHistogram.valueFromIndex(i) *
                                 fromHistogram.integerToDoubleValueConversionRatio,
                         count);
             }
         }
     }

    
Add the contents of another histogram to this one, while correcting the incoming data for coordinated omission.

To compensate for the loss of sampled values when a recorded value is larger than the expected interval between value samples, the values added will include an auto-generated additional series of decreasingly-smaller (down to the expectedIntervalBetweenValueSamples) value records for each count found in the current histogram that is larger than the expectedIntervalBetweenValueSamples. Note: This is a post-recording correction method, as opposed to the at-recording correction method provided by recordValueWithExpectedInterval. The two methods are mutually exclusive, and only one of the two should be be used on a given data set to correct for the same coordinated omission issue. by

See notes in the description of the Histogram calls for an illustration of why this corrective behavior is important.

Parameters:
fromHistogram Other histogram. highestToLowestValueRatio and numberOfSignificantValueDigits must match.
expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add auto-generated value records as appropriate if value is larger than expectedIntervalBetweenValueSamples
Throws:
java.lang.ArrayIndexOutOfBoundsException (may throw) if values exceed highestTrackableValue
 
     public void addWhileCorrectingForCoordinatedOmission(final DoubleHistogram fromHistogram,
                                                          final double expectedIntervalBetweenValueSamples) {
         final DoubleHistogram toHistogram = this;
 
         for (HistogramIterationValue v : fromHistogram.integerValuesHistogram.recordedValues()) {
             toHistogram.recordValueWithCountAndExpectedInterval(
                     v.getValueIteratedTo() * ,
                     v.getCountAtValueIteratedTo(), expectedIntervalBetweenValueSamples);
         }
     }

    
Subtract the contents of another histogram from this one.

Parameters:
otherHistogram The other histogram.
Throws:
java.lang.ArrayIndexOutOfBoundsException (may throw) if values in fromHistogram's cannot be covered by this histogram's range
 
     public void subtract(final DoubleHistogram otherHistogram) {
         int arrayLength = otherHistogram.integerValuesHistogram.countsArrayLength;
         AbstractHistogram otherIntegerHistogram = otherHistogram.integerValuesHistogram;
         for (int i = 0; i < arrayLengthi++) {
             long otherCount = otherIntegerHistogram.getCountAtIndex(i);
             if (otherCount > 0) {
                 double otherValue = otherIntegerHistogram.valueFromIndex(i) *
                         otherHistogram.integerToDoubleValueConversionRatio;
                 if (getCountAtValue(otherValue) < otherCount) {
                     throw new IllegalArgumentException("otherHistogram count (" + otherCount + ") at value " +
                             otherValue + " is larger than this one's (" + getCountAtValue(otherValue) + ")");
                 }
                 recordValueWithCount(otherValue, -otherCount);
             }
         }
     }
 
     //
     //
     //
     // Comparison support:
     //
     //
     //
 
    
Determine if this histogram is equivalent to another.

Parameters:
other the other histogram to compare to
Returns:
True if this histogram are equivalent with the other.
 
     public boolean equals(final Object other){
         if ( this == other ) {
             return true;
         }
         if ( !(other instanceof DoubleHistogram) ) {
             return false;
         }
         DoubleHistogram that = (DoubleHistogramother;
         if (( != that.currentLowestValueInAutoRange) ||
                 ( != that.currentHighestValueLimitInAutoRange) ||
                 (getNumberOfSignificantValueDigits() != that.getNumberOfSignificantValueDigits())) {
             return false;
         }
         if (. != that.integerValuesHistogram.countsArrayLength) {
             return false;
         }
         if (getTotalCount() != that.getTotalCount()) {
             return false;
         }
         for (int i = 0; i < .i++) {
             if (.getCountAtIndex(i) != that.integerValuesHistogram.getCountAtIndex(i)) {
                 return false;
             }
         }
         return true;
     }
 
     //
     //
     //
     // Histogram structure querying support:
     //
     //
     //
 
    
Get the total count of all recorded values in the histogram

Returns:
the total count of all recorded values in the histogram
 
     public long getTotalCount() {
         return .getTotalCount();
     }

    
get the current lowest (non zero) trackable value the automatically determined range (keep in mind that this can change because it is auto ranging)

Returns:
current lowest trackable value the automatically determined range
 
         return ;
     }

    
get the current highest trackable value in the automatically determined range (keep in mind that this can change because it is auto ranging)

Returns:
current highest trackable value in the automatically determined range
 
     double getCurrentHighestTrackableValue() {
         return ;
     }

    
Get the current conversion ratio from interval integer value representation to double units. (keep in mind that this can change because it is auto ranging). This ratio can be useful for converting integer values found in iteration, although the preferred form for accessing iteration values would be to use the getDoubleValueIteratedTo() and getDoubleValueIteratedFrom() accessors to HistogramIterationValue iterated values.

Returns:
the current conversion ratio from interval integer value representation to double units.
 
     public double getIntegerToDoubleValueConversionRatio() {
         return ;
     }

    
get the configured numberOfSignificantValueDigits

Returns:
numberOfSignificantValueDigits
 
     public int getNumberOfSignificantValueDigits() {
     }

    
get the Dynamic range of the histogram: the configured ratio between the highest trackable value and the lowest trackable non zero value at any given time.

Returns:
the dynamic range of the histogram, expressed as the ratio between the highest trackable value and the lowest trackable non zero value at any given time.
 
     public long getHighestToLowestValueRatio() {
         return ;
     }

    
Get the size (in value units) of the range of values that are equivalent to the given value within the histogram's resolution. Where "equivalent" means that value samples recorded for any two equivalent values are counted in a common total count.

Parameters:
value The given value
Returns:
The lowest value that is equivalent to the given value within the histogram's resolution.
 
     public double sizeOfEquivalentValueRange(final double value) {
                 ;
     }

    
Get the lowest value that is equivalent to the given value within the histogram's resolution. Where "equivalent" means that value samples recorded for any two equivalent values are counted in a common total count.

Parameters:
value The given value
Returns:
The lowest value that is equivalent to the given value within the histogram's resolution.
 
     public double lowestEquivalentValue(final double value) {
                 ;
     }

    
Get the highest value that is equivalent to the given value within the histogram's resolution. Where "equivalent" means that value samples recorded for any two equivalent values are counted in a common total count.

Parameters:
value The given value
Returns:
The highest value that is equivalent to the given value within the histogram's resolution.
 
     public double highestEquivalentValue(final double value) {
         double nextNonEquivalentValue = nextNonEquivalentValue(value);
         // Theoretically, nextNonEquivalentValue - ulp(nextNonEquivalentValue) == nextNonEquivalentValue
         // is possible (if the ulp size switches right at nextNonEquivalentValue), so drop by 2 ulps and
         // increment back up to closest within-ulp value.
         double highestEquivalentValue = nextNonEquivalentValue - (2 * Math.ulp(nextNonEquivalentValue));
         while (highestEquivalentValue + Math.ulp(highestEquivalentValue) < nextNonEquivalentValue) {
             highestEquivalentValue += Math.ulp(highestEquivalentValue);
         }
 
         return highestEquivalentValue;
     }

    
Get a value that lies in the middle (rounded up) of the range of values equivalent the given value. Where "equivalent" means that value samples recorded for any two equivalent values are counted in a common total count.

Parameters:
value The given value
Returns:
The value lies in the middle (rounded up) of the range of values equivalent the given value.
 
     public double medianEquivalentValue(final double value) {
                 ;
     }

    
Get the next value that is not equivalent to the given value within the histogram's resolution. Where "equivalent" means that value samples recorded for any two equivalent values are counted in a common total count.

Parameters:
value The given value
Returns:
The next value that is not equivalent to the given value within the histogram's resolution.
 
     public double nextNonEquivalentValue(final double value) {
                 ;     }

    
Determine if two values are equivalent with the histogram's resolution. Where "equivalent" means that value samples recorded for any two equivalent values are counted in a common total count.

Parameters:
value1 first value to compare
value2 second value to compare
Returns:
True if values are equivalent to within the histogram's resolution.
 
     public boolean valuesAreEquivalent(final double value1final double value2) {
         return (lowestEquivalentValue(value1) == lowestEquivalentValue(value2));
     }

    
Provide a (conservatively high) estimate of the Histogram's total footprint in bytes

Returns:
a (conservatively high) estimate of the Histogram's total footprint in bytes
 
     public int getEstimatedFootprintInBytes() {
     }
 
     //
     //
     //
     // Timestamp support:
     //
     //
     //
 
    
get the start time stamp [optionally] stored with this histogram

Returns:
the start time stamp [optionally] stored with this histogram
 
     public long getStartTimeStamp() {
     }

    
Set the start time stamp value associated with this histogram to a given value.

Parameters:
timeStampMsec the value to set the time stamp to, [by convention] in msec since the epoch.
 
     public void setStartTimeStamp(final long timeStampMsec) {
         this.. = timeStampMsec;
     }

    
get the end time stamp [optionally] stored with this histogram

Returns:
the end time stamp [optionally] stored with this histogram
 
     public long getEndTimeStamp() {
         return .;
     }

    
Set the end time stamp value associated with this histogram to a given value.

Parameters:
timeStampMsec the value to set the time stamp to, [by convention] in msec since the epoch.
 
     public void setEndTimeStamp(final long timeStampMsec) {
         this.. = timeStampMsec;
     }
 
     //
     //
     //
     // Histogram Data access support:
     //
     //
     //
 
    
Get the lowest recorded value level in the histogram

Returns:
the Min value recorded in the histogram
 
     public double getMinValue() {
     }

    
Get the highest recorded value level in the histogram

Returns:
the Max value recorded in the histogram
 
     public double getMaxValue() {
     }

    
Get the lowest recorded non-zero value level in the histogram

Returns:
the lowest recorded non-zero value level in the histogram
 
     public double getMinNonZeroValue() {
     }

    
Get the highest recorded value level in the histogram as a double

Returns:
the highest recorded value level in the histogram as a double
 
     @Override
     public double getMaxValueAsDouble() {
         return getMaxValue();
     }

    
Get the computed mean value of all recorded values in the histogram

Returns:
the mean value (in value units) of the histogram data
    public double getMean() {
    }

    
Get the computed standard deviation of all recorded values in the histogram

Returns:
the standard deviation (in value units) of the histogram data
    public double getStdDeviation() {
    }

    
Get the value at a given percentile. When the percentile is > 0.0, the value returned is the value that the given the given percentage of the overall recorded value entries in the histogram are either smaller than or equivalent to. When the percentile is 0.0, the value returned is the value that all value entries in the histogram are either larger than or equivalent to.

Note that two values are "equivalent" in this statement if valuesAreEquivalent(double,double) would return true.

Parameters:
percentile The percentile for which to return the associated value
Returns:
The value that the given percentage of the overall recorded value entries in the histogram are either smaller than or equivalent to. When the percentile is 0.0, returns the value that all value entries in the histogram are either larger than or equivalent to.
    public double getValueAtPercentile(final double percentile) {
    }

    
Get the percentile at a given value. The percentile returned is the percentile of values recorded in the histogram that are smaller than or equivalent to the given value.

Note that two values are "equivalent" in this statement if valuesAreEquivalent(double,double) would return true.

Parameters:
value The value for which to return the associated percentile
Returns:
The percentile of values recorded in the histogram that are smaller than or equivalent to the given value.
    public double getPercentileAtOrBelowValue(final double value) {
    }

    
Get the count of recorded values within a range of value levels (inclusive to within the histogram's resolution).

Parameters:
lowValue The lower value bound on the range for which to provide the recorded count. Will be rounded down with lowestEquivalentValue.
highValue The higher value bound on the range for which to provide the recorded count. Will be rounded up with highestEquivalentValue.
Returns:
the total count of values recorded in the histogram within the value range that is >= lowestEquivalentValue(lowValue) and <= highestEquivalentValue(highValue)
    public double getCountBetweenValues(final double lowValuefinal double highValue)
            throws ArrayIndexOutOfBoundsException {
                (long)(lowValue * ),
                (long)(highValue * )
        );
    }

    
Get the count of recorded values at a specific value (to within the histogram resolution at the value level).

Parameters:
value The value for which to provide the recorded count
Returns:
The total count of values recorded in the histogram within the value range that is >= lowestEquivalentValue(value) and <= highestEquivalentValue(value)
    public long getCountAtValue(final double valuethrows ArrayIndexOutOfBoundsException {
    }

    
Provide a means of iterating through histogram values according to percentile levels. The iteration is performed in steps that start at 0% and reduce their distance to 100% according to the percentileTicksPerHalfDistance parameter, ultimately reaching 100% when all recorded histogram values are exhausted.

Parameters:
percentileTicksPerHalfDistance The number of iteration steps per half-distance to 100%.
Returns:
An java.lang.Iterable<DoubleHistogramIterationValue> through the histogram using a DoublePercentileIterator
    public Percentiles percentiles(final int percentileTicksPerHalfDistance) {
        return new Percentiles(thispercentileTicksPerHalfDistance);
    }

    
Provide a means of iterating through histogram values using linear steps. The iteration is performed in steps of valueUnitsPerBucket in size, terminating when all recorded histogram values are exhausted.

Parameters:
valueUnitsPerBucket The size (in value units) of the linear buckets to use
Returns:
An java.lang.Iterable<DoubleHistogramIterationValue> through the histogram using a DoubleLinearIterator
    public LinearBucketValues linearBucketValues(final double valueUnitsPerBucket) {
        return new LinearBucketValues(thisvalueUnitsPerBucket);
    }

    
Provide a means of iterating through histogram values at logarithmically increasing levels. The iteration is performed in steps that start at valueUnitsInFirstBucket and increase exponentially according to logBase, terminating when all recorded histogram values are exhausted.

Parameters:
valueUnitsInFirstBucket The size (in value units) of the first bucket in the iteration
logBase The multiplier by which bucket sizes will grow in each iteration step
Returns:
An java.lang.Iterable<DoubleHistogramIterationValue> through the histogram using a DoubleLogarithmicIterator
    public LogarithmicBucketValues logarithmicBucketValues(final double valueUnitsInFirstBucket,
                                                           final double logBase) {
        return new LogarithmicBucketValues(thisvalueUnitsInFirstBucketlogBase);
    }

    
Provide a means of iterating through all recorded histogram values using the finest granularity steps supported by the underlying representation. The iteration steps through all non-zero recorded value counts, and terminates when all recorded histogram values are exhausted.

    public RecordedValues recordedValues() {
        return new RecordedValues(this);
    }

    
Provide a means of iterating through all histogram values using the finest granularity steps supported by the underlying representation. The iteration steps through all possible unit value levels, regardless of whether or not there were recorded values for that value level, and terminates when all recorded histogram values are exhausted.

    public AllValues allValues() {
        return new AllValues(this);
    }
    // Percentile iterator support:

    
    public class Percentiles implements Iterable<DoubleHistogramIterationValue> {
        final DoubleHistogram histogram;
        final int percentileTicksPerHalfDistance;
        private Percentiles(final DoubleHistogram histogramfinal int percentileTicksPerHalfDistance) {
            this. = histogram;
            this. = percentileTicksPerHalfDistance;
        }

        
        public Iterator<DoubleHistogramIterationValueiterator() {
        }
    }
    // Linear iterator support:

    
    public class LinearBucketValues implements Iterable<DoubleHistogramIterationValue> {
        final DoubleHistogram histogram;
        final double valueUnitsPerBucket;
        private LinearBucketValues(final DoubleHistogram histogramfinal double valueUnitsPerBucket) {
            this. = histogram;
            this. = valueUnitsPerBucket;
        }

        
        public Iterator<DoubleHistogramIterationValueiterator() {
            return new DoubleLinearIterator();
        }
    }
    // Logarithmic iterator support:

    
        final DoubleHistogram histogram;
        final double valueUnitsInFirstBucket;
        final double logBase;
        private LogarithmicBucketValues(final DoubleHistogram histogram,
                                        final double valueUnitsInFirstBucketfinal double logBase) {
            this. = histogram;
            this. = valueUnitsInFirstBucket;
            this. = logBase;
        }

        
        public Iterator<DoubleHistogramIterationValueiterator() {
            return new DoubleLogarithmicIterator();
        }
    }
    // Recorded value iterator support:

    
    public class RecordedValues implements Iterable<DoubleHistogramIterationValue> {
        final DoubleHistogram histogram;
        private RecordedValues(final DoubleHistogram histogram) {
            this. = histogram;
        }

        
        public Iterator<DoubleHistogramIterationValueiterator() {
            return new DoubleRecordedValuesIterator();
        }
    }
    // AllValues iterator support:

    
    public class AllValues implements Iterable<DoubleHistogramIterationValue> {
        final DoubleHistogram histogram;
        private AllValues(final DoubleHistogram histogram) {
            this. = histogram;
        }

        
        public Iterator<DoubleHistogramIterationValueiterator() {
            return new DoubleAllValuesIterator();
        }
    }



    
Produce textual representation of the value distribution of histogram data by percentile. The distribution is output with exponentially increasing resolution, with each exponentially decreasing half-distance containing five (5) percentile reporting tick points.

Parameters:
printStream Stream into which the distribution will be output

outputValueUnitScalingRatio The scaling factor by which to divide histogram recorded values units in output
    public void outputPercentileDistribution(final PrintStream printStream,
                                             final Double outputValueUnitScalingRatio) {
        outputPercentileDistribution(printStream, 5, outputValueUnitScalingRatio);
    }
    //
    //
    //
    // Textual percentile output support:
    //
    //
    //

    
Produce textual representation of the value distribution of histogram data by percentile. The distribution is output with exponentially increasing resolution, with each exponentially decreasing half-distance containing dumpTicksPerHalf percentile reporting tick points.

Parameters:
printStream Stream into which the distribution will be output

percentileTicksPerHalfDistance The number of reporting points per exponentially decreasing half-distance

outputValueUnitScalingRatio The scaling factor by which to divide histogram recorded values units in output
    public void outputPercentileDistribution(final PrintStream printStream,
                                             final int percentileTicksPerHalfDistance,
                                             final Double outputValueUnitScalingRatio) {
        outputPercentileDistribution(printStreampercentileTicksPerHalfDistanceoutputValueUnitScalingRatiofalse);
    }

    
Produce textual representation of the value distribution of histogram data by percentile. The distribution is output with exponentially increasing resolution, with each exponentially decreasing half-distance containing dumpTicksPerHalf percentile reporting tick points.

Parameters:
printStream Stream into which the distribution will be output

percentileTicksPerHalfDistance The number of reporting points per exponentially decreasing half-distance

outputValueUnitScalingRatio The scaling factor by which to divide histogram recorded values units in output
useCsvFormat Output in CSV format if true. Otherwise use plain text form.
    public void outputPercentileDistribution(final PrintStream printStream,
                                             final int percentileTicksPerHalfDistance,
                                             final Double outputValueUnitScalingRatio,
                                             final boolean useCsvFormat) {
                percentileTicksPerHalfDistance,
                outputValueUnitScalingRatio / ,
                useCsvFormat);
    }
    //
    //
    //
    // Serialization support:
    //
    //
    //
    private static final long serialVersionUID = 42L;
    private void writeObject(final ObjectOutputStream o)
            throws IOException
    {
    }
    private void readObject(final ObjectInputStream o)
            throws IOExceptionClassNotFoundException {
        final long configuredHighestToLowestValueRatio = o.readLong();
        final double lowestValueInAutoRange = o.readDouble();
        AbstractHistogram integerValuesHistogram = (AbstractHistogramo.readObject();
        init(configuredHighestToLowestValueRatiolowestValueInAutoRangeintegerValuesHistogram);
    }
    //
    //
    //
    // Encoding/Decoding support:
    //
    //
    //

    
Get the capacity needed to encode this histogram into a ByteBuffer

Returns:
the capacity needed to encode this histogram into a ByteBuffer
    @Override
    public int getNeededByteBufferCapacity() {
    }
    private int getNeededByteBufferCapacity(final int relevantLength) {
        return .getNeededByteBufferCapacity(relevantLength);
    }
    private void fillCountsArrayFromBuffer(final ByteBuffer bufferfinal int length) {
        .fillCountsArrayFromBuffer(bufferlength);
    }
    private void fillBufferFromCountsArray(final ByteBuffer bufferfinal int length) {
        .fillBufferFromCountsArray(bufferlength);
    }
    private static final int DHIST_encodingCookie = 0x0c72124e;
    private static final int DHIST_compressedEncodingCookie = 0x0c72124f;
    static boolean isDoubleHistogramCookie(int cookie) {
    }
    static boolean isCompressedDoubleHistogramCookie(int cookie) {
        return (cookie == );
    }
    static boolean isNonCompressedDoubleHistogramCookie(int cookie) {
        return (cookie == );
    }

    
Encode this histogram into a ByteBuffer

Parameters:
buffer The buffer to encode into
Returns:
The number of bytes written to the buffer
    synchronized public int encodeIntoByteBuffer(final ByteBuffer buffer) {
        long maxValue = .getMaxValue();
        int relevantLength = .getLengthForNumberOfBuckets(
                .getBucketsNeededToCoverValue(maxValue));
        if (buffer.capacity() < getNeededByteBufferCapacity(relevantLength)) {
            throw new ArrayIndexOutOfBoundsException("buffer does not have capacity for" +
                    getNeededByteBufferCapacity(relevantLength) + " bytes");
        }
        buffer.putInt();
        return .encodeIntoByteBuffer(buffer) + 16;
    }

    
Encode this histogram in compressed form into a byte array

Parameters:
targetBuffer The buffer to encode into
compressionLevel Compression level (for java.util.zip.Deflater).
Returns:
The number of bytes written to the buffer
    @Override
    synchronized public int encodeIntoCompressedByteBuffer(
            final ByteBuffer targetBuffer,
            final int compressionLevel) {
        targetBuffer.putInt();
        targetBuffer.putInt(getNumberOfSignificantValueDigits());
        targetBuffer.putLong();
        return .encodeIntoCompressedByteBuffer(targetBuffercompressionLevel) + 16;
    }

    
Encode this histogram in compressed form into a byte array

Parameters:
targetBuffer The buffer to encode into
Returns:
The number of bytes written to the array
    public int encodeIntoCompressedByteBuffer(final ByteBuffer targetBuffer) {
        return encodeIntoCompressedByteBuffer(targetBuffer.);
    }
            int cookie,
            final ByteBuffer buffer,
            final Class<? extends AbstractHistogramhistogramClass,
            final long minBarForHighestToLowestValueRatiothrows DataFormatException {
        int numberOfSignificantValueDigits = buffer.getInt();
        long configuredHighestToLowestValueRatio = buffer.getLong();
        final AbstractHistogram valuesHistogram;
        if (isNonCompressedDoubleHistogramCookie(cookie)) {
            valuesHistogram =
                    AbstractHistogram.decodeFromByteBuffer(bufferhistogramClassminBarForHighestToLowestValueRatio);
        } else if (isCompressedDoubleHistogramCookie(cookie)) {
            valuesHistogram =
                    AbstractHistogram.decodeFromCompressedByteBuffer(bufferhistogramClassminBarForHighestToLowestValueRatio);
        } else {
            throw new IllegalStateException("The buffer does not contain a DoubleHistogram");
        }
        DoubleHistogram histogram =
                new DoubleHistogram(
                        configuredHighestToLowestValueRatio,
                        numberOfSignificantValueDigits,
                        histogramClass,
                        valuesHistogram
                );
        return histogram;
    }

    
Construct a new DoubleHistogram by decoding it from a ByteBuffer.

Parameters:
buffer The buffer to decode from
minBarForHighestToLowestValueRatio Force highestTrackableValue to be set at least this high
Returns:
The newly constructed DoubleHistogram
    public static DoubleHistogram decodeFromByteBuffer(
            final ByteBuffer buffer,
            final long minBarForHighestToLowestValueRatio) {
        return decodeFromByteBuffer(bufferHistogram.classminBarForHighestToLowestValueRatio);
    }

    
Construct a new DoubleHistogram by decoding it from a ByteBuffer, using a specified AbstractHistogram subclass for tracking internal counts (e.g. Histogram, ConcurrentHistogram, SynchronizedHistogram, IntCountsHistogram, ShortCountsHistogram).

Parameters:
buffer The buffer to decode from
internalCountsHistogramClass The class to use for internal counts tracking
minBarForHighestToLowestValueRatio Force highestTrackableValue to be set at least this high
Returns:
The newly constructed DoubleHistogram
    public static DoubleHistogram decodeFromByteBuffer(
            final ByteBuffer buffer,
            final Class<? extends AbstractHistograminternalCountsHistogramClass,
            long minBarForHighestToLowestValueRatio) {
        try {
            int cookie = buffer.getInt();
            if (!isNonCompressedDoubleHistogramCookie(cookie)) {
                throw new IllegalArgumentException("The buffer does not contain a DoubleHistogram");
            }
            DoubleHistogram histogram = constructHistogramFromBuffer(cookiebufferinternalCountsHistogramClass,
                    minBarForHighestToLowestValueRatio);
            return histogram;
        } catch (DataFormatException ex) {
            throw new RuntimeException(ex);
        }
    }

    
Construct a new DoubleHistogram by decoding it from a compressed form in a ByteBuffer.

Parameters:
buffer The buffer to decode from
minBarForHighestToLowestValueRatio Force highestTrackableValue to be set at least this high
Returns:
The newly constructed DoubleHistogram
Throws:
java.util.zip.DataFormatException on error parsing/decompressing the buffer
            final ByteBuffer buffer,
            final long minBarForHighestToLowestValueRatiothrows DataFormatException {
        return decodeFromCompressedByteBuffer(bufferHistogram.classminBarForHighestToLowestValueRatio);
    }

    
Construct a new DoubleHistogram by decoding it from a compressed form in a ByteBuffer, using a specified AbstractHistogram subclass for tracking internal counts (e.g. Histogram, AtomicHistogram, SynchronizedHistogram, IntCountsHistogram, ShortCountsHistogram).

Parameters:
buffer The buffer to decode from
internalCountsHistogramClass The class to use for internal counts tracking
minBarForHighestToLowestValueRatio Force highestTrackableValue to be set at least this high
Returns:
The newly constructed DoubleHistogram
Throws:
java.util.zip.DataFormatException on error parsing/decompressing the buffer
            final ByteBuffer buffer,
            Class<? extends AbstractHistograminternalCountsHistogramClass,
            long minBarForHighestToLowestValueRatiothrows DataFormatException {
        int cookie = buffer.getInt();
        if (!isCompressedDoubleHistogramCookie(cookie)) {
            throw new IllegalArgumentException("The buffer does not contain a compressed DoubleHistogram");
        }
        DoubleHistogram histogram = constructHistogramFromBuffer(cookiebufferinternalCountsHistogramClass,