histogram.rb 2.3 KB

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