Home | History | Annotate | Download | only in qps
      1 #!/usr/bin/env ruby
      2 
      3 # Copyright 2016 gRPC authors.
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #     http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 
     17 # Histogram class for use in performance testing and measurement
     18 
     19 require 'thread'
     20 
     21 class Histogram
     22   # Determine the bucket index for a given value
     23   # @param {number} value The value to check
     24   # @return {number} The bucket index
     25   def bucket_for(value)
     26     (Math.log(value)/Math.log(@multiplier)).to_i
     27   end
     28   # Initialize an empty histogram
     29   # @param {number} resolution The resolution of the histogram
     30   # @param {number} max_possible The maximum value for the histogram
     31   def initialize(resolution, max_possible)
     32     @lock = Mutex.new
     33     @resolution=resolution
     34     @max_possible=max_possible
     35     @sum=0
     36     @sum_of_squares=0
     37     @multiplier=1+resolution
     38     @count=0
     39     @min_seen=max_possible
     40     @max_seen=0
     41     @buckets=Array.new(bucket_for(max_possible)+1, 0)
     42   end
     43   # Add a value to the histogram. This updates all statistics with the new
     44   # value. Those statistics should not be modified except with this function
     45   # @param {number} value The value to add
     46   def add(value)
     47     @sum += value
     48     @sum_of_squares += value * value
     49     @count += 1
     50     if value < @min_seen
     51       @min_seen = value
     52     end
     53     if value > @max_seen
     54       @max_seen = value
     55     end
     56     @buckets[bucket_for(value)] += 1
     57   end
     58   def minimum
     59     @min_seen
     60   end
     61   def maximum
     62     @max_seen
     63   end
     64   def sum
     65     @sum
     66   end
     67   def sum_of_squares
     68     @sum_of_squares
     69   end
     70   def count
     71     @count
     72   end
     73   def contents
     74     @buckets
     75   end
     76 
     77   def merge(hist)
     78     @lock.synchronize do
     79       @min_seen = hist.min_seen
     80       @max_seen = hist.max_seen
     81       @sum += hist.sum
     82       @sum_of_squares += hist.sum_of_squares
     83       @count += hist.count
     84       received_bucket = hist.bucket.to_a
     85       @buckets = @buckets.map.with_index{ |m,i| m + received_bucket[i].to_i }
     86     end
     87   end
     88 end
     89