stella 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/{README.txt → README.textile} +63 -40
  2. data/Rakefile +7 -5
  3. data/bin/stella +1 -1
  4. data/bin/stella.bat +12 -0
  5. data/lib/pcaplet.rb +180 -0
  6. data/lib/stella/adapter/ab.rb +57 -33
  7. data/lib/stella/adapter/base.rb +11 -1
  8. data/lib/stella/adapter/httperf.rb +13 -10
  9. data/lib/stella/adapter/pcap_watcher.rb +221 -0
  10. data/lib/stella/adapter/proxy_watcher.rb +76 -0
  11. data/lib/stella/adapter/siege.rb +28 -11
  12. data/lib/stella/cli/agents.rb +2 -2
  13. data/lib/stella/cli/base.rb +37 -1
  14. data/lib/stella/cli/localtest.rb +1 -2
  15. data/lib/stella/cli/sysinfo.rb +17 -0
  16. data/lib/stella/cli/watch.rb +278 -0
  17. data/lib/stella/cli.rb +23 -11
  18. data/lib/stella/command/base.rb +1 -10
  19. data/lib/stella/command/localtest.rb +43 -23
  20. data/lib/stella/data/domain.rb +75 -0
  21. data/lib/stella/data/http.rb +124 -0
  22. data/lib/stella/logger.rb +16 -5
  23. data/lib/stella/storable.rb +4 -2
  24. data/lib/stella/support.rb +71 -0
  25. data/lib/stella/sysinfo.rb +247 -0
  26. data/lib/stella/test/base.rb +5 -1
  27. data/lib/stella/test/definition.rb +1 -1
  28. data/lib/stella/test/run/summary.rb +14 -4
  29. data/lib/stella/text/resource.rb +0 -1
  30. data/lib/stella.rb +28 -10
  31. data/lib/utils/domainutil.rb +47 -0
  32. data/lib/utils/fileutil.rb +22 -3
  33. data/lib/utils/httputil.rb +184 -128
  34. data/lib/utils/mathutil.rb +20 -7
  35. data/lib/win32/Console/ANSI.rb +305 -0
  36. data/lib/win32/Console.rb +970 -0
  37. data/spec/show-agents_spec.rb +0 -0
  38. data/support/kvm.h +91 -0
  39. data/support/ruby-pcap-takuma-notes.txt +19 -0
  40. data/support/ruby-pcap-takuma-patch.txt +30 -0
  41. data/support/text/en.yaml +26 -3
  42. data/vendor/frylock/README.textile +72 -0
  43. data/vendor/frylock/bin/example +170 -0
  44. data/vendor/frylock/frylock.gemspec +18 -0
  45. data/vendor/frylock/lib/frylock/exceptions.rb +24 -0
  46. data/vendor/frylock/lib/frylock.rb +232 -0
  47. data/vendor/frylock/test/command_test.rb +33 -0
  48. data/vendor/hitimes-0.4.0/HISTORY +28 -0
  49. data/vendor/hitimes-0.4.0/LICENSE.txt +19 -0
  50. data/vendor/hitimes-0.4.0/README +80 -0
  51. data/vendor/hitimes-0.4.0/Rakefile +63 -0
  52. data/vendor/hitimes-0.4.0/examples/benchmarks.rb +86 -0
  53. data/vendor/hitimes-0.4.0/examples/stats.rb +29 -0
  54. data/vendor/hitimes-0.4.0/ext/extconf.rb +15 -0
  55. data/vendor/hitimes-0.4.0/ext/hitimes_ext.c +21 -0
  56. data/vendor/hitimes-0.4.0/ext/hitimes_instant_clock_gettime.c +20 -0
  57. data/vendor/hitimes-0.4.0/ext/hitimes_instant_osx.c +16 -0
  58. data/vendor/hitimes-0.4.0/ext/hitimes_instant_windows.c +27 -0
  59. data/vendor/hitimes-0.4.0/ext/hitimes_interval.c +340 -0
  60. data/vendor/hitimes-0.4.0/ext/hitimes_interval.h +73 -0
  61. data/vendor/hitimes-0.4.0/ext/hitimes_stats.c +242 -0
  62. data/vendor/hitimes-0.4.0/ext/hitimes_stats.h +30 -0
  63. data/vendor/hitimes-0.4.0/ext/rbconfig-mingw.rb +178 -0
  64. data/vendor/hitimes-0.4.0/ext/rbconfig.rb +178 -0
  65. data/vendor/hitimes-0.4.0/gemspec.rb +54 -0
  66. data/vendor/hitimes-0.4.0/lib/hitimes/mutexed_stats.rb +23 -0
  67. data/vendor/hitimes-0.4.0/lib/hitimes/paths.rb +54 -0
  68. data/vendor/hitimes-0.4.0/lib/hitimes/stats.rb +29 -0
  69. data/vendor/hitimes-0.4.0/lib/hitimes/timer.rb +223 -0
  70. data/vendor/hitimes-0.4.0/lib/hitimes/version.rb +42 -0
  71. data/vendor/hitimes-0.4.0/lib/hitimes.rb +24 -0
  72. data/vendor/hitimes-0.4.0/spec/interval_spec.rb +115 -0
  73. data/vendor/hitimes-0.4.0/spec/mutex_stats_spec.rb +34 -0
  74. data/vendor/hitimes-0.4.0/spec/paths_spec.rb +14 -0
  75. data/vendor/hitimes-0.4.0/spec/spec_helper.rb +6 -0
  76. data/vendor/hitimes-0.4.0/spec/stats_spec.rb +72 -0
  77. data/vendor/hitimes-0.4.0/spec/timer_spec.rb +105 -0
  78. data/vendor/hitimes-0.4.0/spec/version_spec.rb +27 -0
  79. data/vendor/hitimes-0.4.0/tasks/announce.rake +39 -0
  80. data/vendor/hitimes-0.4.0/tasks/config.rb +107 -0
  81. data/vendor/hitimes-0.4.0/tasks/distribution.rake +53 -0
  82. data/vendor/hitimes-0.4.0/tasks/documentation.rake +33 -0
  83. data/vendor/hitimes-0.4.0/tasks/extension.rake +64 -0
  84. data/vendor/hitimes-0.4.0/tasks/rspec.rake +31 -0
  85. data/vendor/hitimes-0.4.0/tasks/rubyforge.rake +52 -0
  86. data/vendor/hitimes-0.4.0/tasks/utils.rb +80 -0
  87. data/vendor/useragent/lib/user_agent.rb +1 -1
  88. metadata +87 -8
@@ -0,0 +1,340 @@
1
+ /**
2
+ * Copyright (c) 2008 Jeremy Hinegardner
3
+ * All rights reserved. See LICENSE and/or COPYING for details.
4
+ *
5
+ * vim: shiftwidth=4
6
+ */
7
+
8
+ #include "hitimes_interval.h"
9
+
10
+ /* Modules and Classes -- defined here */
11
+ VALUE cH_Interval; /* class Hitimes::Interval */
12
+
13
+ /**
14
+ * Allocator and Deallocator for Interval classes
15
+ */
16
+
17
+ VALUE hitimes_interval_free(hitimes_interval_t* i)
18
+ {
19
+ if ( Qnil != i->duration ) {
20
+ rb_gc_unregister_address( &(i->duration) );
21
+ i->duration = Qnil;
22
+ }
23
+ xfree( i );
24
+ return Qnil;
25
+ }
26
+
27
+ VALUE hitimes_interval_alloc(VALUE klass)
28
+ {
29
+ VALUE obj;
30
+ hitimes_interval_t* i = xmalloc( sizeof( hitimes_interval_t ) );
31
+
32
+ i->start_instant = 0L;
33
+ i->stop_instant = 0L;
34
+ i->duration = Qnil;
35
+
36
+ obj = Data_Wrap_Struct(klass, NULL, hitimes_interval_free, i);
37
+ return obj;
38
+ }
39
+
40
+ /**
41
+ * call-seq:
42
+ * Interval.now -> Interval
43
+ *
44
+ * Create an interval that has already started
45
+ */
46
+ VALUE hitimes_interval_now( VALUE self )
47
+ {
48
+ VALUE obj;
49
+ hitimes_interval_t *i = xmalloc( sizeof( hitimes_interval_t ) );
50
+
51
+ i->start_instant = hitimes_get_current_instant( );
52
+ i->stop_instant = 0L;
53
+ i->duration = Qnil;
54
+
55
+ obj = Data_Wrap_Struct(cH_Interval, NULL, hitimes_interval_free, i);
56
+
57
+ return obj;
58
+ }
59
+
60
+ /**
61
+ * call-seq:
62
+ * Interval.measure { } -> Float
63
+ *
64
+ * Times the execution of the block returning the number of seconds it took
65
+ */
66
+ VALUE hitimes_interval_measure( VALUE self )
67
+ {
68
+ hitimes_instant_t before;
69
+ hitimes_instant_t after;
70
+ double duration;
71
+
72
+ if ( !rb_block_given_p() ) {
73
+ rb_raise(eH_Error, "No block given to Interval.measure" );
74
+ }
75
+
76
+ before = hitimes_get_current_instant( );
77
+ rb_yield( Qnil );
78
+ after = hitimes_get_current_instant( );
79
+
80
+ duration = ( after - before ) / HITIMES_INSTANT_CONVERSION_FACTOR;
81
+ return rb_float_new( duration );
82
+ }
83
+
84
+ /**
85
+ * call-seq:
86
+ * interval.split -> Interval
87
+ *
88
+ * Immediately stop the current interval and start a new interval that has a
89
+ * start_instant equivalent to the stop_interval of self.
90
+ */
91
+ VALUE hitimes_interval_split( VALUE self )
92
+ {
93
+ hitimes_interval_t *first;
94
+ hitimes_interval_t *second = xmalloc( sizeof( hitimes_interval_t ) );
95
+ VALUE obj;
96
+
97
+ Data_Get_Struct( self, hitimes_interval_t, first );
98
+ first->stop_instant = hitimes_get_current_instant( );
99
+
100
+ second->start_instant = first->stop_instant;
101
+ second->stop_instant = 0L;
102
+ second->duration = Qnil;
103
+
104
+ obj = Data_Wrap_Struct(cH_Interval, NULL, hitimes_interval_free, second);
105
+
106
+ return obj;
107
+ }
108
+
109
+
110
+ /**
111
+ * call-seq:
112
+ * interval.start -> boolean
113
+ *
114
+ * mark the start of the interval. Calling start on an already started
115
+ * interval has no effect. An interval can only be started once. If the
116
+ * interval is truely started +true+ is returned otherwise +false+.
117
+ */
118
+ VALUE hitimes_interval_start( VALUE self )
119
+ {
120
+ hitimes_interval_t *i;
121
+ VALUE rc = Qfalse;
122
+
123
+ Data_Get_Struct( self, hitimes_interval_t, i );
124
+ if ( 0L == i->start_instant ) {
125
+ i->start_instant = hitimes_get_current_instant( );
126
+ i->stop_instant = 0L;
127
+ i->duration = Qnil;
128
+
129
+ rc = Qtrue;
130
+ }
131
+
132
+ return rc;
133
+ }
134
+
135
+
136
+ /**
137
+ * call-seq:
138
+ * interval.stop -> bool or Float
139
+ *
140
+ * mark the stop of the interval. Calling stop on an already stopped interval
141
+ * has no effect. An interval can only be stopped once. If the interval is
142
+ * truely stopped then the duration is returned, otherwise +false+.
143
+ */
144
+ VALUE hitimes_interval_stop( VALUE self )
145
+ {
146
+ hitimes_interval_t *i;
147
+ VALUE rc = Qfalse;
148
+
149
+ Data_Get_Struct( self, hitimes_interval_t, i );
150
+ if ( 0L == i->start_instant ) {
151
+ rb_raise(eH_Error, "Attempt to stop an interval that has not started.\n" );
152
+ }
153
+
154
+ if ( 0L == i->stop_instant ) {
155
+ double d;
156
+
157
+ i->stop_instant = hitimes_get_current_instant( );
158
+ d = ( i->stop_instant - i->start_instant ) / HITIMES_INSTANT_CONVERSION_FACTOR;
159
+ i->duration = rb_float_new( d );
160
+ rb_gc_register_address( &(i->duration) );
161
+ rc = i->duration;
162
+ }
163
+
164
+ return rc;
165
+ }
166
+
167
+ /**
168
+ * call-seq:
169
+ * interval.started? -> boolean
170
+ *
171
+ * returns whether or not the interval has been started
172
+ */
173
+ VALUE hitimes_interval_started( VALUE self )
174
+ {
175
+ hitimes_interval_t *i;
176
+
177
+ Data_Get_Struct( self, hitimes_interval_t, i );
178
+
179
+ return ( 0L == i->start_instant ) ? Qfalse : Qtrue;
180
+ }
181
+
182
+
183
+ /**
184
+ * call-seq:
185
+ * interval.stopped? -> boolean
186
+ *
187
+ * returns whether or not the interval has been stopped
188
+ */
189
+ VALUE hitimes_interval_stopped( VALUE self )
190
+ {
191
+ hitimes_interval_t *i;
192
+
193
+ Data_Get_Struct( self, hitimes_interval_t, i );
194
+
195
+ return ( 0L == i->stop_instant ) ? Qfalse : Qtrue;
196
+ }
197
+
198
+ /**
199
+ * call-seq:
200
+ * interval.running? -> boolean
201
+ *
202
+ * returns whether or not the interval is running or not. This means that it
203
+ * has started, but not stopped.
204
+ */
205
+ VALUE hitimes_interval_running( VALUE self )
206
+ {
207
+ hitimes_interval_t *i;
208
+ VALUE rc = Qfalse;
209
+
210
+ Data_Get_Struct( self, hitimes_interval_t, i );
211
+ if ( ( 0L != i->start_instant ) && ( 0L == i->stop_instant ) ) {
212
+ rc = Qtrue;
213
+ }
214
+
215
+ return rc;
216
+ }
217
+
218
+
219
+ /**
220
+ * call-seq:
221
+ * interval.start_instant -> Integer
222
+ *
223
+ * The integer representing the start instant of the Interval. This value
224
+ * is not useful on its own. It is a platform dependent value.
225
+ */
226
+ VALUE hitimes_interval_start_instant( VALUE self )
227
+ {
228
+ hitimes_interval_t *i;
229
+
230
+ Data_Get_Struct( self, hitimes_interval_t, i );
231
+
232
+ return ULL2NUM( i->start_instant );
233
+ }
234
+
235
+
236
+ /**
237
+ * call-seq:
238
+ * interval.stop_instant -> Integer
239
+ *
240
+ * The integer representing the stop instant of the Interval. This value
241
+ * is not useful on its own. It is a platform dependent value.
242
+ */
243
+ VALUE hitimes_interval_stop_instant( VALUE self )
244
+ {
245
+ hitimes_interval_t *i;
246
+
247
+ Data_Get_Struct( self, hitimes_interval_t, i );
248
+
249
+ return ULL2NUM( i->stop_instant );
250
+ }
251
+
252
+
253
+
254
+ /**
255
+ * call-seq:
256
+ * interval.duration -> Float
257
+ *
258
+ * Returns the Float value of the interval, the value is in seconds. If the
259
+ * interval has not had stop called yet, it will report the number of seconds
260
+ * in the interval up to the current point in time.
261
+ */
262
+ VALUE hitimes_interval_duration ( VALUE self )
263
+ {
264
+ hitimes_interval_t *i;
265
+ double d;
266
+
267
+ Data_Get_Struct( self, hitimes_interval_t, i );
268
+
269
+ /**
270
+ * if stop has not yet been called, then return the amount of time so far
271
+ */
272
+ if ( 0L == i->stop_instant ) {
273
+ hitimes_instant_t now = hitimes_get_current_instant( );
274
+ d = ( now - i->start_instant ) / HITIMES_INSTANT_CONVERSION_FACTOR;
275
+ return rb_float_new( d );
276
+ }
277
+
278
+
279
+ /*
280
+ * stop has been called, calculate the duration and save the result
281
+ */
282
+ if ( Qnil == i->duration ) {
283
+ d = ( i->stop_instant - i->start_instant ) / HITIMES_INSTANT_CONVERSION_FACTOR;
284
+ i->duration = rb_float_new( d );
285
+ rb_gc_register_address( &(i->duration) );
286
+ }
287
+
288
+ return i->duration;
289
+ }
290
+
291
+
292
+ /**
293
+ * Document-class: Hitimes::Interval
294
+ *
295
+ * This is the lowest level timing mechanism available. It allows for easy
296
+ * measuring based upon a block:
297
+ *
298
+ * duration = Interval.measure { ... }
299
+ *
300
+ * Or measuring something specifically
301
+ *
302
+ * interval = Interval.new
303
+ * interval.start
304
+ * duration = interval.stop
305
+ *
306
+ * Allocating and starting an interval can be done in one method call with
307
+ *
308
+ * interval = Interval.now
309
+ *
310
+ * Interval is useful when you only need to track a single interval of time, or
311
+ * if you do not want to track statistics about an operation.
312
+ *
313
+ */
314
+ void Init_hitimes_interval()
315
+ {
316
+ mH = rb_define_module("Hitimes");
317
+
318
+ cH_Interval = rb_define_class_under( mH, "Interval", rb_cObject );
319
+ rb_define_alloc_func( cH_Interval, hitimes_interval_alloc );
320
+
321
+ rb_define_module_function( cH_Interval, "now", hitimes_interval_now, 0 ); /* in hitimes_interval.c */
322
+ rb_define_module_function( cH_Interval, "measure", hitimes_interval_measure, 0 ); /* in hitimes_interval.c */
323
+
324
+ rb_define_method( cH_Interval, "to_f", hitimes_interval_duration, 0 ); /* in hitimes_interval.c */
325
+ rb_define_method( cH_Interval, "to_seconds", hitimes_interval_duration, 0 ); /* in hitimes_interval.c */
326
+ rb_define_method( cH_Interval, "duration", hitimes_interval_duration, 0 ); /* in hitimes_interval.c */
327
+ rb_define_method( cH_Interval, "length", hitimes_interval_duration, 0 ); /* in hitimes_interval.c */
328
+
329
+ rb_define_method( cH_Interval, "started?", hitimes_interval_started, 0 ); /* in hitimes_interval.c */
330
+ rb_define_method( cH_Interval, "running?", hitimes_interval_running, 0 ); /* in hitimes_interval.c */
331
+ rb_define_method( cH_Interval, "stopped?", hitimes_interval_stopped, 0 ); /* in hitimes_interval.c */
332
+
333
+ rb_define_method( cH_Interval, "start_instant", hitimes_interval_start_instant, 0 ); /* in hitimes_interval.c */
334
+ rb_define_method( cH_Interval, "stop_instant", hitimes_interval_stop_instant, 0 ); /* in hitimes_interval.c */
335
+
336
+ rb_define_method( cH_Interval, "start", hitimes_interval_start, 0); /* in hitimes_interval.c */
337
+ rb_define_method( cH_Interval, "stop", hitimes_interval_stop, 0); /* in hitimes_interval.c */
338
+ rb_define_method( cH_Interval, "split", hitimes_interval_split, 0); /* in hitimes_interval.c */
339
+
340
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Copyright (c) 2008 Jeremy Hinegardner
3
+ * All rights reserved. See LICENSE and/or COPYING for details.
4
+ *
5
+ * vim: shiftwidth=4
6
+ */
7
+
8
+ #ifndef __HITIMES_INTERVAL_H__
9
+ #define __HITIMES_INTERVAL_H__
10
+
11
+ #include <ruby.h>
12
+
13
+ #define NANOSECONDS_PER_SECOND 1e9
14
+
15
+ #ifdef USE_INSTANT_CLOCK_GETTIME
16
+ # define HITIMES_U64INT unsigned long long int
17
+ # define HITIMES_INSTANT_CONVERSION_FACTOR 1e9
18
+ #elif USE_INSTANT_OSX
19
+ # define HITIMES_U64INT unsigned long long int
20
+ # define HITIMES_INSTANT_CONVERSION_FACTOR 1e9
21
+ #elif USE_INSTANT_WINDOWS
22
+ # define HITIMES_U64INT unsigned __int64
23
+ # define HITIMES_INSTANT_CONVERSION_FACTOR hitimes_instant_conversion_factor()
24
+ #else
25
+ # error "Unable to build hitimes, no Instance backend available"
26
+ #endif
27
+
28
+
29
+ /* an alias for a 64bit unsigned integer. The various sytem dependenent
30
+ * files must define hitimes_u64int_t
31
+ */
32
+ typedef HITIMES_U64INT hitimes_instant_t;
33
+
34
+ typedef struct hitimes_interval {
35
+ hitimes_instant_t start_instant;
36
+ hitimes_instant_t stop_instant;
37
+ VALUE duration;
38
+ } hitimes_interval_t;
39
+
40
+ /* all the backends must define this method */
41
+ hitimes_instant_t hitimes_get_current_instant( );
42
+ double hitimes_instant_conversion_factor( );
43
+
44
+ /* init methods */
45
+ void Init_hitimes_stats();
46
+ void Init_hitimes_interval();
47
+
48
+
49
+ /* Module and Classes -- defined at the top level */
50
+ extern VALUE mH; /* module Hitimes */
51
+ extern VALUE eH_Error; /* class Hitimes::Error */
52
+ extern VALUE cH_Interval; /* class Hitimes::Interval */
53
+
54
+
55
+ /**
56
+ * Methods for Interval
57
+ */
58
+
59
+ VALUE hitimes_interval_free(hitimes_interval_t* i) ;
60
+ VALUE hitimes_interval_alloc(VALUE klass);
61
+ VALUE hitimes_interval_now( VALUE self );
62
+ VALUE hitimes_interval_measure( VALUE self );
63
+ VALUE hitimes_interval_split( VALUE self );
64
+ VALUE hitimes_interval_start( VALUE self );
65
+ VALUE hitimes_interval_stop( VALUE self );
66
+ VALUE hitimes_interval_started( VALUE self );
67
+ VALUE hitimes_interval_stopped( VALUE self );
68
+ VALUE hitimes_interval_running( VALUE self );
69
+ VALUE hitimes_interval_start_instant( VALUE self );
70
+ VALUE hitimes_interval_stop_instant( VALUE self );
71
+ VALUE hitimes_interval_duration ( VALUE self );
72
+
73
+ #endif
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Copyright (c) 2008 Jeremy Hinegardner
3
+ * All rights reserved. See LICENSE and/or COPYING for details.
4
+ *
5
+ * vim: shiftwidth=4
6
+ */
7
+
8
+ #include "hitimes_stats.h"
9
+
10
+ /* classes defined here */
11
+ VALUE cH_Stats; /* Hitimes::Stats */
12
+
13
+ /**
14
+ * Allocator and Deallocator for Stats classes
15
+ */
16
+
17
+ VALUE hitimes_stats_free(hitimes_stats_t* s)
18
+ {
19
+ xfree( s );
20
+ return Qnil;
21
+ }
22
+
23
+ VALUE hitimes_stats_alloc(VALUE klass)
24
+ {
25
+ VALUE obj;
26
+ hitimes_stats_t* s = xmalloc( sizeof( hitimes_stats_t ) );
27
+
28
+ s->min = 0.0;
29
+ s->max = 0.0;
30
+ s->count = 0;
31
+ s->sum = 0.0;
32
+ s->sumsq = 0.0;
33
+
34
+ obj = Data_Wrap_Struct(klass, NULL, hitimes_stats_free, s);
35
+
36
+ return obj;
37
+ }
38
+
39
+
40
+ /**
41
+ * call-seq:
42
+ * stat.update( val ) -> nil
43
+ *
44
+ * Update the running stats with the new value.
45
+ */
46
+ VALUE hitimes_stats_update( VALUE self, VALUE v )
47
+ {
48
+ double new_v = NUM2DBL( v );
49
+ hitimes_stats_t *stats;
50
+
51
+ Data_Get_Struct( self, hitimes_stats_t, stats );
52
+
53
+ if ( 0 == stats->count ) {
54
+ stats->min = new_v;
55
+ stats->max = new_v;
56
+ } else {
57
+ stats->min = ( new_v < stats->min) ? ( new_v ) : ( stats->min );
58
+ stats->max = ( new_v > stats->max) ? ( new_v ) : ( stats->max );
59
+ }
60
+
61
+ stats->count += 1;
62
+ stats->sum += new_v;
63
+ stats->sumsq += ( new_v * new_v );
64
+
65
+ return Qnil;
66
+ }
67
+
68
+ /**
69
+ * call-seq:
70
+ * stat.mean -> Float
71
+ *
72
+ * Return the arithmetic mean of the values put into the Stats object. If no
73
+ * values have passed through the stats object then 0.0 is returned;
74
+ */
75
+ VALUE hitimes_stats_mean( VALUE self )
76
+ {
77
+ hitimes_stats_t *stats;
78
+ double mean = 0.0;
79
+
80
+ Data_Get_Struct( self, hitimes_stats_t, stats );
81
+
82
+ if ( stats->count > 0 ) {
83
+ mean = stats->sum / stats->count ;
84
+ }
85
+
86
+ return rb_float_new( mean );
87
+ }
88
+
89
+
90
+ /**
91
+ * call-seq:
92
+ * stat.rate -> Float
93
+ *
94
+ * Return the count per seconds ( rate ) rate stat. If no values have passed
95
+ * through the stats object then 0.0 is returned.
96
+ */
97
+ VALUE hitimes_stats_rate( VALUE self )
98
+ {
99
+ hitimes_stats_t *stats;
100
+ double rate = 0.0;
101
+
102
+ Data_Get_Struct( self, hitimes_stats_t, stats );
103
+
104
+ if ( stats->sum > 0.0 ) {
105
+ rate = stats->count / stats->sum;
106
+ }
107
+
108
+ return rb_float_new( rate );
109
+ }
110
+
111
+
112
+ /**
113
+ * call-seq:
114
+ * stat.max -> Float
115
+ *
116
+ * Return the maximum value that has passed through the Stats object
117
+ */
118
+ VALUE hitimes_stats_max( VALUE self )
119
+ {
120
+ hitimes_stats_t *stats;
121
+
122
+ Data_Get_Struct( self, hitimes_stats_t, stats );
123
+
124
+ return rb_float_new( stats->max );
125
+ }
126
+
127
+
128
+
129
+ /**
130
+ * call-seq:
131
+ * stat.min -> Float
132
+ *
133
+ * Return the minimum value that has passed through the Stats object
134
+ */
135
+ VALUE hitimes_stats_min( VALUE self )
136
+ {
137
+ hitimes_stats_t *stats;
138
+
139
+ Data_Get_Struct( self, hitimes_stats_t, stats );
140
+
141
+ return rb_float_new( stats->min );
142
+ }
143
+
144
+
145
+ /**
146
+ * call-seq:
147
+ * stat.count -> Integer
148
+ *
149
+ * Return the number of values that have passed through the Stats object.
150
+ */
151
+ VALUE hitimes_stats_count( VALUE self )
152
+ {
153
+ hitimes_stats_t *stats;
154
+
155
+ Data_Get_Struct( self, hitimes_stats_t, stats );
156
+
157
+ return LONG2NUM( stats->count );
158
+ }
159
+
160
+
161
+ /**
162
+ * call-seq:
163
+ * stat.sum -> Float
164
+ *
165
+ * Return the sum of all the values that have passed through the Stats object.
166
+ */
167
+ VALUE hitimes_stats_sum( VALUE self )
168
+ {
169
+ hitimes_stats_t *stats;
170
+
171
+ Data_Get_Struct( self, hitimes_stats_t, stats );
172
+
173
+ return rb_float_new( stats->sum );
174
+ }
175
+
176
+
177
+ /**
178
+ * call-seq:
179
+ * stat.stddev -> Float
180
+ *
181
+ * Return the standard deviation of all the values that have passed through the
182
+ * Stats object. The standard deviation has no meaning unless the count is > 1,
183
+ * therefore if the current _stat.count_ is < 1 then 0.0 will be returned;
184
+ */
185
+ VALUE hitimes_stats_stddev ( VALUE self )
186
+ {
187
+ hitimes_stats_t *stats;
188
+ double stddev = 0.0;
189
+
190
+ Data_Get_Struct( self, hitimes_stats_t, stats );
191
+ if ( stats->count > 1 ) {
192
+ stddev = sqrt( ( stats->sumsq - ( stats->sum * stats->sum / stats->count ) ) / ( stats->count - 1 ) );
193
+ }
194
+
195
+ return rb_float_new( stddev );
196
+ }
197
+
198
+
199
+ /**
200
+ * Document-class: Hitimes::Stats
201
+ *
202
+ * The Stats class encapulsates capturing and reporting statistics. It is
203
+ * modeled after the RFuzz::Sampler class, but implemented in C. For general use
204
+ * you allocate a new Stats object, and then update it with new values. The
205
+ * Stats object will keep track of the _min_, _max_, _count_ and _sum_ and when
206
+ * you want you may also retrieve the _mean_ and _stddev_.
207
+ *
208
+ * this contrived example shows getting a list of all the files in a directory
209
+ * and running stats on file sizes.
210
+ *
211
+ * s = Hitimes::Stats.new
212
+ * dir = ARGV.shift || Dir.pwd
213
+ * Dir.entries( dir ).each do |entry|
214
+ * fs = File.stat( entry )
215
+ * if fs.file? then
216
+ * s.update( fs.size )
217
+ * end
218
+ * end
219
+ *
220
+ * %w[ count min max mean sum stddev rate ].each do |m|
221
+ * puts "#{m.rjust(6)} : #{s.send( m ) }"
222
+ * end
223
+ */
224
+ void Init_hitimes_stats()
225
+ {
226
+
227
+ mH = rb_define_module("Hitimes");
228
+
229
+ cH_Stats = rb_define_class_under( mH, "Stats", rb_cObject ); /* in hitimes_stats.c */
230
+ rb_define_alloc_func( cH_Stats, hitimes_stats_alloc );
231
+
232
+ rb_define_method( cH_Stats, "update", hitimes_stats_update, 1 ); /* in hitimes_stats.c */
233
+
234
+ rb_define_method( cH_Stats, "count", hitimes_stats_count, 0 ); /* in hitimes_stats.c */
235
+ rb_define_method( cH_Stats, "max", hitimes_stats_max, 0 ); /* in hitimes_stats.c */
236
+ rb_define_method( cH_Stats, "mean", hitimes_stats_mean, 0 ); /* in hitimes_stats.c */
237
+ rb_define_method( cH_Stats, "min", hitimes_stats_min, 0 ); /* in hitimes_stats.c */
238
+ rb_define_method( cH_Stats, "rate", hitimes_stats_rate, 0 ); /* in hitimes_stats.c */
239
+ rb_define_method( cH_Stats, "sum", hitimes_stats_sum, 0 ); /* in hitimes_stats.c */
240
+ rb_define_method( cH_Stats, "stddev", hitimes_stats_stddev, 0 ); /* in hitimes_stats.c */
241
+ }
242
+
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Copyright (c) 2008 Jeremy Hinegardner
3
+ * All rights reserved. See LICENSE and/or COPYING for details.
4
+ *
5
+ * vim: shiftwidth=4
6
+ */
7
+
8
+ #ifndef __HITIMES_STATS_H__
9
+ #define __HITIMES_STATS_H__
10
+
11
+ #include <ruby.h>
12
+ #include <math.h>
13
+
14
+ /* classes and modules defined elswhere */
15
+ extern VALUE mH; /* Hitimes */
16
+ extern VALUE eH_Error; /* Hitimes::Error */
17
+ extern VALUE cH_Stats; /* Hitimes::Stats */
18
+
19
+
20
+ typedef struct hitimes_stats {
21
+ double min;
22
+ double max;
23
+ double sum;
24
+ double sumsq;
25
+ long count;
26
+ } hitimes_stats_t;
27
+
28
+ #endif
29
+
30
+