C0 code coverage information
Generated on Wed Jul 19 17:39:34 EDT 2006 with rcov 0.6.0
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # Copyright (c) 2005 Zed A. Shaw
2 # You can redistribute it and/or modify it under the same terms as Ruby.
3 #
4 # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5 # for more information.
6
7 # A very simple little class for doing some basic fast statistics sampling.
8 # You feed it either samples of numeric data you want measured or you call
9 # Sampler.tick to get it to add a time delta between the last time you called it.
10 # When you're done either call sum, sumsq, n, min, max, mean or sd to get
11 # the information. The other option is to just call dump and see everything.
12 #
13 # It does all of this very fast and doesn't take up any memory since the samples
14 # are not stored but instead all the values are calculated on the fly.
15 module RFuzz
16 class Sampler
17 attr_reader :sum, :sumsq, :n, :min, :max
18
19 def initialize(name)
20 @name = name
21 reset
22 end
23
24 # Resets the internal counters so you can start sampling again.
25 def reset
26 @sum = 0.0
27 @sumsq = 0.0
28 @last_time = Time.new
29 @n = 0.0
30 @min = 0.0
31 @max = 0.0
32 end
33
34 # Adds a sampling to the calculations.
35 def sample(s)
36 @sum += s
37 @sumsq += s * s
38 if @n == 0
39 @min = @max = s
40 else
41 @min = s if @min > s
42 @max = s if @max < s
43 end
44 @n+=1
45 end
46
47 # Dump this Sampler object with an optional additional message.
48 def dump(msg = "", out=STDERR)
49 out.puts "#{msg}: #{self.to_s}"
50 end
51
52 # Returns a common display (used by dump)
53 def to_s
54 "[%s]: SUM=%0.6f, SUMSQ=%0.6f, N=%0.6f, MEAN=%0.6f, SD=%0.6f, MIN=%0.6f, MAX=%0.6f" % values
55 end
56
57 # An array of the values minus the name: [sum,sumsq,n,mean,sd,min,max]
58 def values
59 [@name, @sum, @sumsq, @n, mean, sd, @min, @max]
60 end
61
62 # Class method that returns the headers that a CSV file would have for the
63 # values that this stats object is using.
64 def self.keys
65 ["name","sum","sumsq","n","mean","sd","min","max"]
66 end
67
68 def to_hash
69 {"name" => @name, "sum" => @sum, "sumsq" => @sumsq, "mean" => mean,
70 "sd" => sd, "min" => @min, "max" => @max}
71 end
72
73 # Calculates and returns the mean for the data passed so far.
74 def mean
75 @sum / @n
76 end
77
78 # Calculates the standard deviation of the data so far.
79 def sd
80 # (sqrt( ((s).sumsq - ( (s).sum * (s).sum / (s).n)) / ((s).n-1) ))
81 begin
82 return Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) )
83 rescue Errno::EDOM
84 return 0.0
85 end
86 end
87
88 # You can just call tick repeatedly if you need the delta times
89 # between a set of sample periods, but many times you actually want
90 # to sample how long something takes between a start/end period.
91 # Call mark at the beginning and then tick at the end you'll get this
92 # kind of measurement. Don't mix mark/tick and tick sampling together
93 # or the measurement will be meaningless.
94 def mark
95 @last_time = Time.now
96 end
97
98 # Adds a time delta between now and the last time you called this. This
99 # will give you the average time between two activities.
100 #
101 # An example is:
102 #
103 # t = Sampler.new("do_stuff")
104 # 10000.times { do_stuff(); t.tick }
105 # t.dump("time")
106 #
107 def tick
108 now = Time.now
109 sample(now - @last_time)
110 @last_time = now
111 end
112 end
113
114 # When registered as the notifier for a client it tracks
115 # the times for each part of the request. Rather than subclassing
116 # RFuzz::Notifier it uses a method_missing to record the even timings.
117 #
118 # You can dump it with to_s, or you can access the StatsTracker.stats
119 # hash to read the RFuzz::Sampler objects related to each event.
120 class StatsTracker
121 attr_reader :stats
122
123 def initialize
124 @stats = {}
125 @error_count = 0
126 end
127
128 def mark(event)
129 @stats[event] ||= RFuzz::Sampler.new(event)
130 @stats[event].mark
131 end
132
133 def sample(event)
134 @stats[event].tick
135 end
136
137 def reset
138 @stats.each {|e,s| s.reset }
139 end
140
141 def method_missing(event, *args)
142 case args[0]
143 when :begins
144 mark(:request) if event == :connect
145 mark(event)
146 when :ends
147 sample(:request) if event == :close
148 sample(event)
149 when :error
150 sample(:request)
151 @error_count += 1
152 end
153 end
154
155 def to_s
156 "#{@stats.values.join("\n")}\nErrors: #@error_count"
157 end
158 end
159 end
Generated using the rcov code coverage analysis tool for Ruby version 0.6.0.