hitimes 1.3.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +57 -0
  3. data/HISTORY.md +124 -0
  4. data/LICENSE +16 -0
  5. data/Manifest.txt +44 -0
  6. data/README.md +200 -0
  7. data/Rakefile +28 -0
  8. data/examples/benchmarks.rb +113 -0
  9. data/examples/stats.rb +31 -0
  10. data/ext/hitimes/c/extconf.rb +24 -0
  11. data/ext/hitimes/c/hitimes.c +37 -0
  12. data/ext/hitimes/c/hitimes_instant_clock_gettime.c +28 -0
  13. data/ext/hitimes/c/hitimes_instant_osx.c +45 -0
  14. data/ext/hitimes/c/hitimes_instant_windows.c +27 -0
  15. data/ext/hitimes/c/hitimes_interval.c +370 -0
  16. data/ext/hitimes/c/hitimes_interval.h +73 -0
  17. data/ext/hitimes/c/hitimes_stats.c +269 -0
  18. data/ext/hitimes/c/hitimes_stats.h +30 -0
  19. data/ext/hitimes/java/src/hitimes/Hitimes.java +66 -0
  20. data/ext/hitimes/java/src/hitimes/HitimesInterval.java +176 -0
  21. data/ext/hitimes/java/src/hitimes/HitimesService.java +16 -0
  22. data/ext/hitimes/java/src/hitimes/HitimesStats.java +112 -0
  23. data/lib/hitimes.rb +66 -0
  24. data/lib/hitimes/2.0/hitimes.so +0 -0
  25. data/lib/hitimes/2.1/hitimes.so +0 -0
  26. data/lib/hitimes/2.2/hitimes.so +0 -0
  27. data/lib/hitimes/2.3/hitimes.so +0 -0
  28. data/lib/hitimes/2.4/hitimes.so +0 -0
  29. data/lib/hitimes/2.5/hitimes.so +0 -0
  30. data/lib/hitimes/metric.rb +118 -0
  31. data/lib/hitimes/mutexed_stats.rb +32 -0
  32. data/lib/hitimes/paths.rb +53 -0
  33. data/lib/hitimes/stats.rb +58 -0
  34. data/lib/hitimes/timed_metric.rb +176 -0
  35. data/lib/hitimes/timed_value_metric.rb +233 -0
  36. data/lib/hitimes/value_metric.rb +71 -0
  37. data/lib/hitimes/version.rb +8 -0
  38. data/spec/hitimes_spec.rb +24 -0
  39. data/spec/interval_spec.rb +136 -0
  40. data/spec/metric_spec.rb +28 -0
  41. data/spec/mutex_stats_spec.rb +36 -0
  42. data/spec/paths_spec.rb +11 -0
  43. data/spec/spec_helper.rb +11 -0
  44. data/spec/stats_spec.rb +98 -0
  45. data/spec/timed_metric_spec.rb +155 -0
  46. data/spec/timed_value_metric_spec.rb +171 -0
  47. data/spec/value_metric_spec.rb +108 -0
  48. data/spec/version_spec.rb +7 -0
  49. data/tasks/default.rake +242 -0
  50. data/tasks/extension.rake +38 -0
  51. data/tasks/this.rb +208 -0
  52. metadata +216 -0
@@ -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 1e9l
14
+
15
+ #ifdef USE_INSTANT_CLOCK_GETTIME
16
+ # define HITIMES_U64INT unsigned long long int
17
+ # define HITIMES_INSTANT_CONVERSION_FACTOR 1e9l
18
+ #elif USE_INSTANT_OSX
19
+ # define HITIMES_U64INT uint64_t
20
+ # define HITIMES_INSTANT_CONVERSION_FACTOR hitimes_instant_conversion_factor()
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
+ long double duration;
38
+ } hitimes_interval_t;
39
+
40
+ /* all the backends must define these methods */
41
+ hitimes_instant_t hitimes_get_current_instant( );
42
+ long 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( );
62
+ VALUE hitimes_interval_measure( );
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,269 @@
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 ) -> val
43
+ *
44
+ * Update the running stats with the new value.
45
+ * Return the input value.
46
+ */
47
+ VALUE hitimes_stats_update( VALUE self, VALUE v )
48
+ {
49
+ long double new_v;
50
+ hitimes_stats_t *stats;
51
+
52
+ Data_Get_Struct( self, hitimes_stats_t, stats );
53
+ new_v = NUM2DBL( v );
54
+
55
+ if ( 0 == stats->count ) {
56
+ stats->min = new_v;
57
+ stats->max = new_v;
58
+ } else {
59
+ stats->min = ( new_v < stats->min) ? ( new_v ) : ( stats->min );
60
+ stats->max = ( new_v > stats->max) ? ( new_v ) : ( stats->max );
61
+ }
62
+
63
+ stats->count += 1;
64
+ stats->sum += new_v;
65
+ stats->sumsq += ( new_v * new_v );
66
+
67
+ return v;
68
+ }
69
+
70
+ /**
71
+ * call-seq:
72
+ * stat.mean -> Float
73
+ *
74
+ * Return the arithmetic mean of the values put into the Stats object. If no
75
+ * values have passed through the stats object then 0.0 is returned;
76
+ */
77
+ VALUE hitimes_stats_mean( VALUE self )
78
+ {
79
+ hitimes_stats_t *stats;
80
+ long double mean = 0.0;
81
+
82
+ Data_Get_Struct( self, hitimes_stats_t, stats );
83
+
84
+ if ( stats->count > 0 ) {
85
+ mean = stats->sum / stats->count ;
86
+ }
87
+
88
+ return rb_float_new( mean );
89
+ }
90
+
91
+
92
+ /**
93
+ * call-seq:
94
+ * stat.rate -> Float
95
+ *
96
+ * Return the +count+ divided by +sum+.
97
+ *
98
+ * In many cases when Stats#update( _value_ ) is called, the _value_ is a unit
99
+ * of time, typically seconds or microseconds. #rate is a convenience for those
100
+ * times. In this case, where _value_ is a unit if time, then count divided by
101
+ * sum is a useful value, i.e. +something per unit of time+.
102
+ *
103
+ * In the case where _value_ is a non-time related value, then the value
104
+ * returned by _rate_ is not really useful.
105
+ *
106
+ */
107
+ VALUE hitimes_stats_rate( VALUE self )
108
+ {
109
+ hitimes_stats_t *stats;
110
+ long double rate = 0.0;
111
+
112
+ Data_Get_Struct( self, hitimes_stats_t, stats );
113
+
114
+ if ( stats->sum > 0.0 ) {
115
+ rate = stats->count / stats->sum;
116
+ }
117
+
118
+ return rb_float_new( rate );
119
+ }
120
+
121
+
122
+ /**
123
+ * call-seq:
124
+ * stat.max -> Float
125
+ *
126
+ * Return the maximum value that has passed through the Stats object
127
+ */
128
+ VALUE hitimes_stats_max( VALUE self )
129
+ {
130
+ hitimes_stats_t *stats;
131
+
132
+ Data_Get_Struct( self, hitimes_stats_t, stats );
133
+
134
+ return rb_float_new( stats->max );
135
+ }
136
+
137
+
138
+
139
+ /**
140
+ * call-seq:
141
+ * stat.min -> Float
142
+ *
143
+ * Return the minimum value that has passed through the Stats object
144
+ */
145
+ VALUE hitimes_stats_min( VALUE self )
146
+ {
147
+ hitimes_stats_t *stats;
148
+
149
+ Data_Get_Struct( self, hitimes_stats_t, stats );
150
+
151
+ return rb_float_new( stats->min );
152
+ }
153
+
154
+
155
+ /**
156
+ * call-seq:
157
+ * stat.count -> Integer
158
+ *
159
+ * Return the number of values that have passed through the Stats object.
160
+ */
161
+ VALUE hitimes_stats_count( VALUE self )
162
+ {
163
+ hitimes_stats_t *stats;
164
+
165
+ Data_Get_Struct( self, hitimes_stats_t, stats );
166
+
167
+ return LONG2NUM( stats->count );
168
+ }
169
+
170
+
171
+ /**
172
+ * call-seq:
173
+ * stat.sum -> Float
174
+ *
175
+ * Return the sum of all the values that have passed through the Stats object.
176
+ */
177
+ VALUE hitimes_stats_sum( VALUE self )
178
+ {
179
+ hitimes_stats_t *stats;
180
+
181
+ Data_Get_Struct( self, hitimes_stats_t, stats );
182
+
183
+ return rb_float_new( stats->sum );
184
+ }
185
+
186
+ /**
187
+ * call-seq:
188
+ * stat.sumsq -> Float
189
+ *
190
+ * Return the sum of the squars of all the values that passed through the Stats
191
+ * object.
192
+ */
193
+ VALUE hitimes_stats_sumsq( VALUE self )
194
+ {
195
+ hitimes_stats_t *stats;
196
+
197
+ Data_Get_Struct( self, hitimes_stats_t, stats );
198
+
199
+ return rb_float_new( stats->sumsq );
200
+ }
201
+
202
+
203
+ /**
204
+ * call-seq:
205
+ * stat.stddev -> Float
206
+ *
207
+ * Return the standard deviation of all the values that have passed through the
208
+ * Stats object. The standard deviation has no meaning unless the count is > 1,
209
+ * therefore if the current _stat.count_ is < 1 then 0.0 will be returned;
210
+ */
211
+ VALUE hitimes_stats_stddev ( VALUE self )
212
+ {
213
+ hitimes_stats_t *stats;
214
+ long double stddev = 0.0;
215
+
216
+ Data_Get_Struct( self, hitimes_stats_t, stats );
217
+ if ( stats->count > 1 ) {
218
+ stddev = sqrt( ( stats->sumsq - ( stats->sum * stats->sum / stats->count ) ) / ( stats->count - 1 ) );
219
+ }
220
+
221
+ return rb_float_new( stddev );
222
+ }
223
+
224
+
225
+ /**
226
+ * Document-class: Hitimes::Stats
227
+ *
228
+ * The Stats class encapulsates capturing and reporting statistics. It is
229
+ * modeled after the RFuzz::Sampler class, but implemented in C. For general use
230
+ * you allocate a new Stats object, and then update it with new values. The
231
+ * Stats object will keep track of the _min_, _max_, _count_, _sum_ and _sumsq_
232
+ * and when you want you may also retrieve the _mean_, _stddev_ and _rate_.
233
+ *
234
+ * this contrived example shows getting a list of all the files in a directory
235
+ * and running stats on file sizes.
236
+ *
237
+ * s = Hitimes::Stats.new
238
+ * dir = ARGV.shift || Dir.pwd
239
+ * Dir.entries( dir ).each do |entry|
240
+ * fs = File.stat( entry )
241
+ * if fs.file? then
242
+ * s.update( fs.size )
243
+ * end
244
+ * end
245
+ *
246
+ * %w[ count min max mean sum stddev rate ].each do |m|
247
+ * puts "#{m.rjust(6)} : #{s.send( m ) }"
248
+ * end
249
+ */
250
+ void Init_hitimes_stats()
251
+ {
252
+
253
+ mH = rb_define_module("Hitimes");
254
+
255
+ cH_Stats = rb_define_class_under( mH, "Stats", rb_cObject ); /* in hitimes_stats.c */
256
+ rb_define_alloc_func( cH_Stats, hitimes_stats_alloc );
257
+
258
+ rb_define_method( cH_Stats, "update", hitimes_stats_update, 1 ); /* in hitimes_stats.c */
259
+
260
+ rb_define_method( cH_Stats, "count", hitimes_stats_count, 0 ); /* in hitimes_stats.c */
261
+ rb_define_method( cH_Stats, "max", hitimes_stats_max, 0 ); /* in hitimes_stats.c */
262
+ rb_define_method( cH_Stats, "mean", hitimes_stats_mean, 0 ); /* in hitimes_stats.c */
263
+ rb_define_method( cH_Stats, "min", hitimes_stats_min, 0 ); /* in hitimes_stats.c */
264
+ rb_define_method( cH_Stats, "rate", hitimes_stats_rate, 0 ); /* in hitimes_stats.c */
265
+ rb_define_method( cH_Stats, "sum", hitimes_stats_sum, 0 ); /* in hitimes_stats.c */
266
+ rb_define_method( cH_Stats, "sumsq", hitimes_stats_sumsq, 0 ); /* in hitimes_stats.c */
267
+ rb_define_method( cH_Stats, "stddev", hitimes_stats_stddev, 0 ); /* in hitimes_stats.c */
268
+ }
269
+
@@ -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
+ long double min;
22
+ long double max;
23
+ long double sum;
24
+ long double sumsq;
25
+ long long count;
26
+ } hitimes_stats_t;
27
+
28
+ #endif
29
+
30
+
@@ -0,0 +1,66 @@
1
+ package hitimes;
2
+
3
+ import java.lang.Math;
4
+ import java.lang.System;
5
+
6
+ import org.jruby.anno.JRubyClass;
7
+ import org.jruby.anno.JRubyMethod;
8
+ import org.jruby.anno.JRubyModule;
9
+ import org.jruby.anno.JRubyConstant;
10
+ import org.jruby.runtime.Visibility;
11
+
12
+ import org.jruby.Ruby;
13
+ import org.jruby.RubyClass;
14
+ import org.jruby.RubyException;
15
+ import org.jruby.RubyModule;
16
+ import org.jruby.RubyObject;
17
+
18
+ import org.jruby.exceptions.RaiseException;
19
+
20
+ import org.jruby.runtime.builtin.IRubyObject;
21
+
22
+
23
+ /**
24
+ * @author <a href="mailto:jeremy@hinegardner.org">Jeremy Hinegardner</a>
25
+ */
26
+ @JRubyModule( name = "Hitimes" )
27
+ public class Hitimes {
28
+
29
+ public static final double INSTANT_CONVERSION_FACTOR = 1000000000d;
30
+
31
+ private static final Ruby __ruby__ = Ruby.getGlobalRuntime();
32
+
33
+ public static RubyClass hitimesIntervalClass;
34
+ /**
35
+ * Create the Hitimes module and add it to the Ruby runtime.
36
+ */
37
+ public static RubyModule createHitimesModule( Ruby runtime ) {
38
+ RubyModule mHitimes = runtime.defineModule("Hitimes");
39
+ mHitimes.defineConstant("INSTANT_CONVERSION_FACTOR", __ruby__.newFloat(INSTANT_CONVERSION_FACTOR));
40
+ mHitimes.defineAnnotatedMethods( Hitimes.class );
41
+
42
+ RubyClass cStandardError = runtime.getStandardError();
43
+ RubyClass cHitimesError = mHitimes.defineClassUnder("Error", cStandardError, cStandardError.getAllocator());
44
+
45
+ RubyClass cHitimesStats = mHitimes.defineClassUnder("Stats", runtime.getObject(), HitimesStats.ALLOCATOR );
46
+ cHitimesStats.defineAnnotatedMethods( HitimesStats.class );
47
+
48
+ RubyClass cHitimesInterval = mHitimes.defineClassUnder("Interval", runtime.getObject(), HitimesInterval.ALLOCATOR );
49
+ Hitimes.hitimesIntervalClass = cHitimesInterval;
50
+ cHitimesInterval.defineAnnotatedMethods( HitimesInterval.class );
51
+
52
+ return mHitimes;
53
+ }
54
+
55
+ static RaiseException newHitimesError( Ruby runtime, String message ) {
56
+ RubyClass errorClass = runtime.getModule("Hitimes").getClass( "Error" );
57
+ return new RaiseException( RubyException.newException( runtime, errorClass, message ), true );
58
+ }
59
+
60
+
61
+ @JRubyMethod( name = "raw_instant", module = true )
62
+ public static IRubyObject rawInstant(IRubyObject self) {
63
+ return __ruby__.newFixnum( System.nanoTime() );
64
+ }
65
+
66
+ }
@@ -0,0 +1,176 @@
1
+ package hitimes;
2
+
3
+ import org.jruby.runtime.builtin.IRubyObject;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.RubyClass;
7
+ import org.jruby.RubyObject;
8
+
9
+ import org.jruby.runtime.Block;
10
+ import org.jruby.runtime.ObjectAllocator;
11
+ import org.jruby.runtime.ThreadContext;
12
+
13
+ import org.jruby.anno.JRubyClass;
14
+ import org.jruby.anno.JRubyMethod;
15
+
16
+ @JRubyClass( name = "Hitimes::Interval" )
17
+ public class HitimesInterval extends RubyObject {
18
+
19
+ private static final long INSTANT_NOT_SET = Long.MIN_VALUE;
20
+ private static final double DURATION_NOT_SET = Double.NaN;
21
+
22
+ public static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
23
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
24
+ return new HitimesInterval( runtime, klass );
25
+ }
26
+ };
27
+
28
+ public HitimesInterval( Ruby runtime, RubyClass klass ) {
29
+ super( runtime, klass );
30
+ }
31
+
32
+ public HitimesInterval( Ruby runtime, RubyClass klass, long start ) {
33
+ super( runtime, klass );
34
+ this.start_instant = start;
35
+ }
36
+
37
+
38
+ private long start_instant = INSTANT_NOT_SET;
39
+ private long stop_instant = INSTANT_NOT_SET;
40
+ private double duration = DURATION_NOT_SET;
41
+
42
+ @JRubyMethod( name = "duration", alias = { "length", "to_f", "to_seconds" } )
43
+ public IRubyObject duration() {
44
+
45
+ /*
46
+ * if start has not yet been called, then raise an exception.
47
+ */
48
+ if ( INSTANT_NOT_SET == this.start_instant ) {
49
+ throw Hitimes.newHitimesError( getRuntime(), "Attempt to report a duration on an interval that has not started");
50
+ }
51
+
52
+ /*
53
+ * if stop has not yet been called, then return the amount of time so far
54
+ */
55
+ if ( INSTANT_NOT_SET == this.stop_instant ) {
56
+ double d = ( System.nanoTime() - this.start_instant ) / Hitimes.INSTANT_CONVERSION_FACTOR;
57
+ return getRuntime().newFloat( d );
58
+ }
59
+
60
+ /*
61
+ * if stop has been called, then calculate the duration and return
62
+ */
63
+ if ( DURATION_NOT_SET == this.duration ) {
64
+ this.duration = (this.stop_instant - this.start_instant) / Hitimes.INSTANT_CONVERSION_FACTOR;
65
+ }
66
+
67
+ return getRuntime().newFloat( this.duration );
68
+
69
+ }
70
+
71
+ @JRubyMethod( name = "duration_so_far" )
72
+ public IRubyObject duration_so_far() {
73
+ IRubyObject rc = getRuntime().getFalse();
74
+
75
+ if ( INSTANT_NOT_SET == this.start_instant ) {
76
+ return rc;
77
+ }
78
+
79
+ if ( INSTANT_NOT_SET == this.stop_instant ) {
80
+ double d = ( System.nanoTime() - this.start_instant ) / Hitimes.INSTANT_CONVERSION_FACTOR;
81
+ return getRuntime().newFloat( d );
82
+ }
83
+
84
+ return rc;
85
+ }
86
+
87
+ @JRubyMethod( name = "started?" )
88
+ public IRubyObject is_started() {
89
+ if ( INSTANT_NOT_SET == this.start_instant ) {
90
+ return getRuntime().getFalse();
91
+ }
92
+ return getRuntime().getTrue();
93
+ }
94
+
95
+ @JRubyMethod( name = "running?" )
96
+ public IRubyObject is_running() {
97
+ if ( ( INSTANT_NOT_SET != this.start_instant ) && ( INSTANT_NOT_SET == this.stop_instant ) ) {
98
+ return getRuntime().getTrue();
99
+ }
100
+ return getRuntime().getFalse();
101
+ }
102
+
103
+ @JRubyMethod( name = "stopped?" )
104
+ public IRubyObject is_stopped() {
105
+ if ( INSTANT_NOT_SET == this.stop_instant ) {
106
+ return getRuntime().getFalse();
107
+ }
108
+ return getRuntime().getTrue();
109
+ }
110
+
111
+ @JRubyMethod( name = "start_instant" )
112
+ public IRubyObject start_instant() {
113
+ return getRuntime().newFixnum( this.start_instant );
114
+ }
115
+
116
+ @JRubyMethod( name = "stop_instant" )
117
+ public IRubyObject stop_instant() {
118
+ return getRuntime().newFixnum( this.stop_instant );
119
+ }
120
+
121
+ @JRubyMethod( name = "start" )
122
+ public IRubyObject start() {
123
+ if ( INSTANT_NOT_SET == this.start_instant ) {
124
+ this.start_instant = System.nanoTime();
125
+ return getRuntime().getTrue();
126
+ }
127
+ return getRuntime().getFalse();
128
+ }
129
+
130
+ @JRubyMethod( name = "stop" )
131
+ public IRubyObject stop() {
132
+ if ( INSTANT_NOT_SET == this.start_instant ) {
133
+ throw Hitimes.newHitimesError( getRuntime(), "Attempt to stop an interval that has not started" );
134
+ }
135
+
136
+ if ( INSTANT_NOT_SET == this.stop_instant ) {
137
+ this.stop_instant = System.nanoTime();
138
+ this.duration = (this.stop_instant - this.start_instant) / Hitimes.INSTANT_CONVERSION_FACTOR;
139
+ return getRuntime().newFloat( this.duration );
140
+ }
141
+
142
+ return getRuntime().getFalse();
143
+ }
144
+
145
+ @JRubyMethod( name = "split" )
146
+ public IRubyObject split() {
147
+ this.stop();
148
+ return new HitimesInterval( getRuntime(), Hitimes.hitimesIntervalClass, this.stop_instant );
149
+ }
150
+
151
+ @JRubyMethod( name = "now", module = true )
152
+ public static IRubyObject now( IRubyObject self ) {
153
+ return new HitimesInterval( self.getRuntime(), Hitimes.hitimesIntervalClass, System.nanoTime() );
154
+ }
155
+
156
+ @JRubyMethod( name = "measure", module = true, frame = true )
157
+ public static IRubyObject measure( IRubyObject self, Block block ) {
158
+
159
+ Ruby runtime = self.getRuntime();
160
+
161
+ if ( block.isGiven() ) {
162
+ IRubyObject nil = runtime.getNil();
163
+ ThreadContext context = runtime.getCurrentContext();
164
+
165
+ HitimesInterval interval = new HitimesInterval( runtime, Hitimes.hitimesIntervalClass );
166
+
167
+ interval.start();
168
+ block.yield( context, nil );
169
+ interval.stop();
170
+
171
+ return interval.duration();
172
+ } else {
173
+ throw Hitimes.newHitimesError( runtime, "No block given to Interval.measure" );
174
+ }
175
+ }
176
+ }