stella 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/{README.txt → README.textile} +63 -40
- data/Rakefile +7 -5
- data/bin/stella +1 -1
- data/bin/stella.bat +12 -0
- data/lib/pcaplet.rb +180 -0
- data/lib/stella/adapter/ab.rb +57 -33
- data/lib/stella/adapter/base.rb +11 -1
- data/lib/stella/adapter/httperf.rb +13 -10
- data/lib/stella/adapter/pcap_watcher.rb +221 -0
- data/lib/stella/adapter/proxy_watcher.rb +76 -0
- data/lib/stella/adapter/siege.rb +28 -11
- data/lib/stella/cli/agents.rb +2 -2
- data/lib/stella/cli/base.rb +37 -1
- data/lib/stella/cli/localtest.rb +1 -2
- data/lib/stella/cli/sysinfo.rb +17 -0
- data/lib/stella/cli/watch.rb +278 -0
- data/lib/stella/cli.rb +23 -11
- data/lib/stella/command/base.rb +1 -10
- data/lib/stella/command/localtest.rb +43 -23
- data/lib/stella/data/domain.rb +75 -0
- data/lib/stella/data/http.rb +124 -0
- data/lib/stella/logger.rb +16 -5
- data/lib/stella/storable.rb +4 -2
- data/lib/stella/support.rb +71 -0
- data/lib/stella/sysinfo.rb +247 -0
- data/lib/stella/test/base.rb +5 -1
- data/lib/stella/test/definition.rb +1 -1
- data/lib/stella/test/run/summary.rb +14 -4
- data/lib/stella/text/resource.rb +0 -1
- data/lib/stella.rb +28 -10
- data/lib/utils/domainutil.rb +47 -0
- data/lib/utils/fileutil.rb +22 -3
- data/lib/utils/httputil.rb +184 -128
- data/lib/utils/mathutil.rb +20 -7
- data/lib/win32/Console/ANSI.rb +305 -0
- data/lib/win32/Console.rb +970 -0
- data/spec/show-agents_spec.rb +0 -0
- data/support/kvm.h +91 -0
- data/support/ruby-pcap-takuma-notes.txt +19 -0
- data/support/ruby-pcap-takuma-patch.txt +30 -0
- data/support/text/en.yaml +26 -3
- data/vendor/frylock/README.textile +72 -0
- data/vendor/frylock/bin/example +170 -0
- data/vendor/frylock/frylock.gemspec +18 -0
- data/vendor/frylock/lib/frylock/exceptions.rb +24 -0
- data/vendor/frylock/lib/frylock.rb +232 -0
- data/vendor/frylock/test/command_test.rb +33 -0
- data/vendor/hitimes-0.4.0/HISTORY +28 -0
- data/vendor/hitimes-0.4.0/LICENSE.txt +19 -0
- data/vendor/hitimes-0.4.0/README +80 -0
- data/vendor/hitimes-0.4.0/Rakefile +63 -0
- data/vendor/hitimes-0.4.0/examples/benchmarks.rb +86 -0
- data/vendor/hitimes-0.4.0/examples/stats.rb +29 -0
- data/vendor/hitimes-0.4.0/ext/extconf.rb +15 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_ext.c +21 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_clock_gettime.c +20 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_osx.c +16 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_instant_windows.c +27 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_interval.c +340 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_interval.h +73 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_stats.c +242 -0
- data/vendor/hitimes-0.4.0/ext/hitimes_stats.h +30 -0
- data/vendor/hitimes-0.4.0/ext/rbconfig-mingw.rb +178 -0
- data/vendor/hitimes-0.4.0/ext/rbconfig.rb +178 -0
- data/vendor/hitimes-0.4.0/gemspec.rb +54 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/mutexed_stats.rb +23 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/paths.rb +54 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/stats.rb +29 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/timer.rb +223 -0
- data/vendor/hitimes-0.4.0/lib/hitimes/version.rb +42 -0
- data/vendor/hitimes-0.4.0/lib/hitimes.rb +24 -0
- data/vendor/hitimes-0.4.0/spec/interval_spec.rb +115 -0
- data/vendor/hitimes-0.4.0/spec/mutex_stats_spec.rb +34 -0
- data/vendor/hitimes-0.4.0/spec/paths_spec.rb +14 -0
- data/vendor/hitimes-0.4.0/spec/spec_helper.rb +6 -0
- data/vendor/hitimes-0.4.0/spec/stats_spec.rb +72 -0
- data/vendor/hitimes-0.4.0/spec/timer_spec.rb +105 -0
- data/vendor/hitimes-0.4.0/spec/version_spec.rb +27 -0
- data/vendor/hitimes-0.4.0/tasks/announce.rake +39 -0
- data/vendor/hitimes-0.4.0/tasks/config.rb +107 -0
- data/vendor/hitimes-0.4.0/tasks/distribution.rake +53 -0
- data/vendor/hitimes-0.4.0/tasks/documentation.rake +33 -0
- data/vendor/hitimes-0.4.0/tasks/extension.rake +64 -0
- data/vendor/hitimes-0.4.0/tasks/rspec.rake +31 -0
- data/vendor/hitimes-0.4.0/tasks/rubyforge.rake +52 -0
- data/vendor/hitimes-0.4.0/tasks/utils.rb +80 -0
- data/vendor/useragent/lib/user_agent.rb +1 -1
- 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
|
+
|