void repack()

in Extremem/src/main/java/com/amazon/corretto/benchmark/extremem/RelativeTimeMetrics.java [1370:1592]


  void repack(long[] histo_columns, long lb, long histo_span) {

    for (int i = 0; i < HistoColumnCount; i++)
      histo_columns[i] = 0;
    int index = fbi;
    for (int i = 0; i < biu; i++) {

      // Every data "bucket" has a hit_rate which is the total number
      // of samples divided by the number of 256-microsecond intervals
      // spanned by this bucket.

      // Since data buckets may not align exactly with report buckets,
      // we need a way to map between them.

      // Model each data bucket's distribution by assuming linear
      // progression of hit_rate throughout the interval of time
      // spanned by the bucket, with the hit_rate at the beginning of
      // the interval matching the preceding bucket's hit_rate and the
      // hit_rate at the end of the interval matching the hit_rate of
      // the interval that follows.

      // Use floating point y-intercept and slope to model each
      // data bucket's distribution.  y-intercept is relative to the
      // a time value of zero.  Thus, the y-intercept value may be
      // negative.

      // To compute how much of a particular data bucket pertains to a
      // particular reporting quantum, take the calculate the y-value
      // at the midpoint of the reporting quantum, rounding fractional
      // results to the nearest integer.

      // For complete "integrity", correct round-off errors by summing
      // the contributions over all reported quanta and adding or
      // subtracting to report totals, working from the center time of
      // the data bucket's time span outward.

      float right_rate, left_rate;
      if (buckets[index] > 0) {
        int segment_quanta;

        int bucket_tally = buckets[index];
        float my_slope;
        float my_intercept;
        long segment_start;
        if (i == 0) {             // use sis instead of region span
          long start_of_span = sis;
          int end_index = incrIndex(index);
          long end_of_span = bucket_bounds[end_index];
          segment_start = truncate256(start_of_span);

          // end_of_interval and segment_start are both multiples of 256
          segment_quanta = (int) ((end_of_span - segment_start) / 256);
          float this_rate = ((float) buckets[index]) / segment_quanta;
       
          left_rate = 0.0F;
          if (biu > 1) {
            int next_index = incrIndex(index);
            float right_tally = (float) buckets[next_index];
            right_rate = right_tally / (spanAt(next_index) / 256);
          } else
            right_rate = this_rate * 2;
          
          // Log the sis value within the first bucket now.
          // Spread the remaining tally values as appropriate.
          addToReportTally(histo_columns, lb, histo_span,
                           sis, 1);
          bucket_tally--;
        } else if (i + 1 == biu) {
          segment_start = bucket_bounds[index];
          long end_of_span = truncate256(lis);
          // In the case that lis equals segment_start, we need to expand this segment_quanta calculation
          if (end_of_span <= lis)
            end_of_span += 256;
          segment_quanta = (int) ((end_of_span - segment_start) / 256);

          float this_rate = ((float) buckets[index] / segment_quanta);
          
          if (biu > 1) {
            int prev_index = decrIndex(index);
            float left_tally = (float) buckets[prev_index];
            left_rate = left_tally / (spanAt(prev_index) / 256);
          } else
            left_rate = this_rate * 2;
          right_rate = 0.0F;
          
          if (lis > segment_start) {
            // Log the lis value within the last bucket now.
            // Spread the remaining tally values as appropriate.
            addToReportTally(histo_columns, lb, histo_span, lis, 1);
            bucket_tally--;
          }
          // expect my slope to be negative
        } else {
          // since this is not first and not last, we know it has neighbors
          segment_start = bucket_bounds[index];
          int next_index = incrIndex(index);
          int prev_index = decrIndex(index);

          long end_of_span = bucket_bounds[next_index];
          segment_quanta = (int) ((end_of_span - segment_start) / 256);

          float this_rate = ((float) buckets[index] / segment_quanta);
          
          float left_tally = (float) buckets[prev_index];
          left_rate = left_tally / (spanAt(prev_index) / 256);
          
          float right_tally = (float) buckets[next_index];
          right_rate = right_tally / (spanAt(next_index) / 256);
          
          if ((lis >= segment_start) && (lis < end_of_span))  {
            // Log the lis value within the last bucket now.
            // Spread the remaining tally values as appropriate.
            addToReportTally(histo_columns, lb, histo_span, lis, 1);
            bucket_tally--;
          }
        }
        
        my_slope = (right_rate - left_rate) / (segment_quanta * 256);
        float midpoint_time = segment_start + segment_quanta * 128;
        my_intercept =
        ((float) bucket_tally) / segment_quanta - my_slope * midpoint_time;

        if (bucket_tally < segment_quanta) {
          // There are fewer tallied values than there are 256-microsecond segments

          int pad;
          long midpoint;
          if (my_slope > 0.0) {      // fill in from high end
            pad = segment_quanta - bucket_tally;
            midpoint = segment_start - 128 + pad * 256;
          } else if (my_slope < 0.0) { // fill in from low end
            pad = 0;
            midpoint = segment_start + 128;
          } else {              // fill form middle
            pad = (segment_quanta - bucket_tally) / 2;
            midpoint = segment_start + 128 + pad * 256;
          }
          while (bucket_tally-- > 0) {
            addToReportTally(histo_columns, lb, histo_span, midpoint, 1);
            midpoint += 256;
          }
        } else {
          // There are more tallied values than there are 256-microsecond segments
          if (my_intercept + (segment_start + 128) * my_slope < 0) {
            // Rather than allowing the rate to go negative, form a triangle that
            // slopes downward to the left, the enclosing rectangle holding twice
            // the tally.
            left_rate = 0.0F;
            right_rate = (2 * (float) bucket_tally) / segment_quanta;
            my_slope = (right_rate - left_rate) / (segment_quanta * 256);

            // Since y = mx + b, calculate b = y_0 - m * x_0
            // Rectangle holds bucket_tally * 2.
            // Width of rectangle is segment_quanta.
            // Height of rectangle is tally * 2 / segment_quanta.
            // height at midpoint is (tally * 2 / segment_quanta) / 2, aka (tally / segment_quanta)
            //    y_0 is 0
            //    x_0 is segment_start
            my_intercept = 0.0F - my_slope * segment_start;
          } else if ((segment_start - 128 + 256 * segment_quanta) * my_slope
                     + my_intercept < 0) {
            // form a triangle that slopes downward to the right, the
            // enclosing rectangle holding twice my tally.
            left_rate = (2 * (float) bucket_tally) / segment_quanta;
            right_rate = 0.0F;
            my_slope = (right_rate - left_rate) / (segment_quanta * 256);
            // Since y = mx + b, calculate b = y_0 - m * x_0
            //    y_0 is 0
            //    x_0 is segment_start + segment_quanta * 256

            my_intercept = 0.0F - my_slope * (segment_start + segment_quanta * 256);
          }
          if (my_slope > 0) {
            // fill from low to high
            for (int j = 0; j < segment_quanta; j++) {
              long quanta_midpoint = segment_start + 128 + 256 * j;

              int quanta_contribution = java.lang.Math.round(my_intercept + quanta_midpoint * my_slope);
              if (quanta_contribution > bucket_tally) {
                quanta_contribution = bucket_tally;
              }
              addToReportTally(histo_columns, lb, histo_span, quanta_midpoint, quanta_contribution);
              bucket_tally -= quanta_contribution;
            }
            while (bucket_tally > 0) {
              long midpoint = segment_start + 128;
              for (int j = 0; j < segment_quanta; j++) {
                addToReportTally(histo_columns, lb, histo_span, midpoint, 1);
                midpoint += 256;
                if (bucket_tally-- == 1)
                  break;
              }
            }
          } else {
            // fill from high to low
            for (int j = segment_quanta - 1; j >= 0; j--) {
              long quanta_midpoint = segment_start + 128 + 256 * j;
              int quanta_contribution =
                java.lang.Math.round(my_intercept + quanta_midpoint * my_slope);
              if (quanta_contribution > bucket_tally) {
                quanta_contribution = bucket_tally;
              }
              addToReportTally(histo_columns, lb, histo_span,
                               quanta_midpoint, quanta_contribution);
              bucket_tally -= quanta_contribution;
            }
            // We distributed the tallies, but not all of them.  Spread the remaining
            // tallies "evenly".
            while (bucket_tally > 0) {
              long midpoint = segment_start - 128 + 256 * segment_quanta;
              for (int j = 0; j < segment_quanta; j++) {
                addToReportTally(histo_columns, lb, histo_span, midpoint, 1);
                midpoint -= 256;
                if (bucket_tally-- == 1)
                  break;
              }
            }
          }
        }
      }
      index = incrIndex(index);
    }
  }