hitimes 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/CONTRIBUTING.md +45 -0
  2. data/{HISTORY → HISTORY.rdoc} +14 -1
  3. data/LICENSE +11 -8
  4. data/Manifest.txt +44 -0
  5. data/{README → README.rdoc} +20 -6
  6. data/Rakefile +20 -62
  7. data/ext/hitimes/{extconf.rb → c/extconf.rb} +3 -3
  8. data/ext/hitimes/{hitimes_ext.c → c/hitimes.c} +1 -1
  9. data/ext/hitimes/{hitimes_instant_clock_gettime.c → c/hitimes_instant_clock_gettime.c} +0 -0
  10. data/ext/hitimes/c/hitimes_instant_osx.c +45 -0
  11. data/ext/hitimes/{hitimes_instant_windows.c → c/hitimes_instant_windows.c} +0 -0
  12. data/ext/hitimes/{hitimes_interval.c → c/hitimes_interval.c} +15 -7
  13. data/ext/hitimes/{hitimes_interval.h → c/hitimes_interval.h} +5 -5
  14. data/ext/hitimes/{hitimes_stats.c → c/hitimes_stats.c} +0 -0
  15. data/ext/hitimes/{hitimes_stats.h → c/hitimes_stats.h} +0 -0
  16. data/ext/hitimes/java/src/hitimes/Hitimes.java +54 -0
  17. data/ext/hitimes/java/src/hitimes/HitimesInterval.java +181 -0
  18. data/ext/hitimes/java/src/hitimes/HitimesService.java +16 -0
  19. data/ext/hitimes/java/src/hitimes/HitimesStats.java +112 -0
  20. data/lib/hitimes.rb +15 -5
  21. data/lib/hitimes/version.rb +1 -50
  22. data/spec/hitimes_spec.rb +14 -0
  23. data/spec/interval_spec.rb +24 -21
  24. data/spec/metric_spec.rb +8 -10
  25. data/spec/mutex_stats_spec.rb +8 -6
  26. data/spec/paths_spec.rb +1 -3
  27. data/spec/spec_helper.rb +7 -3
  28. data/spec/stats_spec.rb +26 -28
  29. data/spec/timed_metric_spec.rb +33 -33
  30. data/spec/timed_value_metric_spec.rb +45 -46
  31. data/spec/value_metric_spec.rb +21 -23
  32. data/spec/version_spec.rb +4 -30
  33. data/tasks/default.rake +267 -0
  34. data/tasks/extension.rake +31 -101
  35. data/tasks/this.rb +209 -0
  36. metadata +139 -143
  37. data/ext/hitimes/hitimes_instant_osx.c +0 -16
  38. data/gemspec.rb +0 -64
  39. data/tasks/announce.rake +0 -42
  40. data/tasks/config.rb +0 -109
  41. data/tasks/distribution.rake +0 -93
  42. data/tasks/documentation.rake +0 -32
  43. data/tasks/rspec.rake +0 -33
  44. data/tasks/rubyforge.rake +0 -55
  45. data/tasks/utils.rb +0 -80
@@ -0,0 +1,54 @@
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.JRubyModule;
8
+
9
+ import org.jruby.Ruby;
10
+ import org.jruby.RubyClass;
11
+ import org.jruby.RubyException;
12
+ import org.jruby.RubyModule;
13
+ import org.jruby.RubyObject;
14
+
15
+ import org.jruby.exceptions.RaiseException;
16
+
17
+
18
+ /**
19
+ * @author <a href="mailto:jeremy@hinegardner.org">Jeremy Hinegardner</a>
20
+ */
21
+ @JRubyModule( name = "Hitimes" )
22
+ public class Hitimes {
23
+
24
+ public static RubyClass hitimesIntervalClass;
25
+ /**
26
+ * Create the Hitimes module and add it to the Ruby runtime.
27
+ */
28
+ public static RubyModule createHitimes( Ruby runtime ) {
29
+ RubyModule mHitimes = runtime.defineModule("Hitimes");
30
+
31
+ RubyClass cStandardError = runtime.getStandardError();
32
+ RubyClass cHitimesError = mHitimes.defineClassUnder("Error", cStandardError, cStandardError.getAllocator());
33
+
34
+ RubyClass cHitimesStats = mHitimes.defineClassUnder("Stats", runtime.getObject(), HitimesStats.ALLOCATOR );
35
+ cHitimesStats.defineAnnotatedMethods( HitimesStats.class );
36
+
37
+ RubyClass cHitimesInterval = mHitimes.defineClassUnder("Interval", runtime.getObject(), HitimesInterval.ALLOCATOR );
38
+ Hitimes.hitimesIntervalClass = cHitimesInterval;
39
+ cHitimesInterval.defineAnnotatedMethods( HitimesInterval.class );
40
+
41
+ return mHitimes;
42
+ }
43
+
44
+ static RaiseException newHitimesError( Ruby runtime, String message ) {
45
+ RubyClass errorClass = runtime.getModule("Hitimes").getClass( "Error" );
46
+ return new RaiseException( RubyException.newException( runtime, errorClass, message ), true );
47
+ }
48
+
49
+
50
+
51
+ @JRubyClass( name = "Hitimes::Error", parent = "StandardError" )
52
+ public static class Error {};
53
+
54
+ }
@@ -0,0 +1,181 @@
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
+ /* this is a double to force all division by the conversion factor
20
+ * to cast to doubles
21
+ */
22
+ private static final double INSTANT_CONVERSION_FACTOR = 1000000000d;
23
+
24
+ private static final long INSTANT_NOT_SET = Long.MIN_VALUE;
25
+ private static final double DURATION_NOT_SET = Double.NaN;
26
+
27
+ public static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
28
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
29
+ return new HitimesInterval( runtime, klass );
30
+ }
31
+ };
32
+
33
+ public HitimesInterval( Ruby runtime, RubyClass klass ) {
34
+ super( runtime, klass );
35
+ }
36
+
37
+ public HitimesInterval( Ruby runtime, RubyClass klass, long start ) {
38
+ super( runtime, klass );
39
+ this.start_instant = start;
40
+ }
41
+
42
+
43
+ private long start_instant = INSTANT_NOT_SET;
44
+ private long stop_instant = INSTANT_NOT_SET;
45
+ private double duration = DURATION_NOT_SET;
46
+
47
+ @JRubyMethod( name = "duration", alias = { "length", "to_f", "to_seconds" } )
48
+ public IRubyObject duration() {
49
+
50
+ /*
51
+ * if start has not yet been called, then raise an exception.
52
+ */
53
+ if ( INSTANT_NOT_SET == this.start_instant ) {
54
+ throw Hitimes.newHitimesError( getRuntime(), "Attempt to report a duration on an interval that has not started");
55
+ }
56
+
57
+ /*
58
+ * if stop has not yet been called, then return the amount of time so far
59
+ */
60
+ if ( INSTANT_NOT_SET == this.stop_instant ) {
61
+ double d = ( System.nanoTime() - this.start_instant ) / INSTANT_CONVERSION_FACTOR;
62
+ return getRuntime().newFloat( d );
63
+ }
64
+
65
+ /*
66
+ * if stop has been called, then calculate the duration and return
67
+ */
68
+ if ( DURATION_NOT_SET == this.duration ) {
69
+ this.duration = (this.stop_instant - this.start_instant) / INSTANT_CONVERSION_FACTOR;
70
+ }
71
+
72
+ return getRuntime().newFloat( this.duration );
73
+
74
+ }
75
+
76
+ @JRubyMethod( name = "duration_so_far" )
77
+ public IRubyObject duration_so_far() {
78
+ IRubyObject rc = getRuntime().getFalse();
79
+
80
+ if ( INSTANT_NOT_SET == this.start_instant ) {
81
+ return rc;
82
+ }
83
+
84
+ if ( INSTANT_NOT_SET == this.stop_instant ) {
85
+ double d = ( System.nanoTime() - this.start_instant ) / INSTANT_CONVERSION_FACTOR;
86
+ return getRuntime().newFloat( d );
87
+ }
88
+
89
+ return rc;
90
+ }
91
+
92
+ @JRubyMethod( name = "started?" )
93
+ public IRubyObject is_started() {
94
+ if ( INSTANT_NOT_SET == this.start_instant ) {
95
+ return getRuntime().getFalse();
96
+ }
97
+ return getRuntime().getTrue();
98
+ }
99
+
100
+ @JRubyMethod( name = "running?" )
101
+ public IRubyObject is_running() {
102
+ if ( ( INSTANT_NOT_SET != this.start_instant ) && ( INSTANT_NOT_SET == this.stop_instant ) ) {
103
+ return getRuntime().getTrue();
104
+ }
105
+ return getRuntime().getFalse();
106
+ }
107
+
108
+ @JRubyMethod( name = "stopped?" )
109
+ public IRubyObject is_stopped() {
110
+ if ( INSTANT_NOT_SET == this.stop_instant ) {
111
+ return getRuntime().getFalse();
112
+ }
113
+ return getRuntime().getTrue();
114
+ }
115
+
116
+ @JRubyMethod( name = "start_instant" )
117
+ public IRubyObject start_instant() {
118
+ return getRuntime().newFixnum( this.start_instant );
119
+ }
120
+
121
+ @JRubyMethod( name = "stop_instant" )
122
+ public IRubyObject stop_instant() {
123
+ return getRuntime().newFixnum( this.stop_instant );
124
+ }
125
+
126
+ @JRubyMethod( name = "start" )
127
+ public IRubyObject start() {
128
+ if ( INSTANT_NOT_SET == this.start_instant ) {
129
+ this.start_instant = System.nanoTime();
130
+ return getRuntime().getTrue();
131
+ }
132
+ return getRuntime().getFalse();
133
+ }
134
+
135
+ @JRubyMethod( name = "stop" )
136
+ public IRubyObject stop() {
137
+ if ( INSTANT_NOT_SET == this.start_instant ) {
138
+ throw Hitimes.newHitimesError( getRuntime(), "Attempt to stop an interval that has not started" );
139
+ }
140
+
141
+ if ( INSTANT_NOT_SET == this.stop_instant ) {
142
+ this.stop_instant = System.nanoTime();
143
+ this.duration = (this.stop_instant - this.start_instant) / INSTANT_CONVERSION_FACTOR;
144
+ return getRuntime().newFloat( this.duration );
145
+ }
146
+
147
+ return getRuntime().getFalse();
148
+ }
149
+
150
+ @JRubyMethod( name = "split" )
151
+ public IRubyObject split() {
152
+ this.stop();
153
+ return new HitimesInterval( getRuntime(), Hitimes.hitimesIntervalClass, this.stop_instant );
154
+ }
155
+
156
+ @JRubyMethod( name = "now", module = true )
157
+ public static IRubyObject now( IRubyObject self ) {
158
+ return new HitimesInterval( self.getRuntime(), Hitimes.hitimesIntervalClass, System.nanoTime() );
159
+ }
160
+
161
+ @JRubyMethod( name = "measure", module = true, frame = true )
162
+ public static IRubyObject measure( IRubyObject self, Block block ) {
163
+
164
+ Ruby runtime = self.getRuntime();
165
+
166
+ if ( block.isGiven() ) {
167
+ IRubyObject nil = runtime.getNil();
168
+ ThreadContext context = runtime.getCurrentContext();
169
+
170
+ HitimesInterval interval = new HitimesInterval( runtime, Hitimes.hitimesIntervalClass );
171
+
172
+ interval.start();
173
+ block.yield( context, nil );
174
+ interval.stop();
175
+
176
+ return interval.duration();
177
+ } else {
178
+ throw Hitimes.newHitimesError( runtime, "No block given to Interval.measure" );
179
+ }
180
+ }
181
+ }
@@ -0,0 +1,16 @@
1
+ package hitimes;
2
+
3
+ import java.io.IOException;
4
+
5
+ import org.jruby.Ruby;
6
+
7
+ import org.jruby.runtime.load.BasicLibraryService;
8
+
9
+ public class HitimesService implements BasicLibraryService {
10
+ public boolean basicLoad( final Ruby runtime ) throws IOException {
11
+ Hitimes.createHitimes( runtime );
12
+ return true;
13
+ }
14
+ }
15
+
16
+
@@ -0,0 +1,112 @@
1
+ package hitimes;
2
+
3
+ import org.jruby.Ruby;
4
+ import org.jruby.RubyClass;
5
+ import org.jruby.RubyObject;
6
+
7
+ import org.jruby.RubyNumeric;
8
+ import org.jruby.runtime.builtin.IRubyObject;
9
+ import org.jruby.runtime.ObjectAllocator;
10
+
11
+ import org.jruby.anno.JRubyMethod;
12
+ import org.jruby.anno.JRubyClass;
13
+
14
+ @JRubyClass( name = "Hitimes::Stats" )
15
+ public class HitimesStats extends RubyObject {
16
+
17
+ private double min = 0.0;
18
+ private double max = 0.0;
19
+ private double sum = 0.0;
20
+ private double sumsq = 0.0;
21
+ private long count = 0;
22
+
23
+ public static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
24
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
25
+ return new HitimesStats( runtime, klass );
26
+ }
27
+ };
28
+
29
+ public HitimesStats( Ruby runtime, RubyClass klass ) {
30
+ super( runtime, klass );
31
+ }
32
+
33
+ @JRubyMethod( name = "update", required = 1, argTypes = RubyNumeric.class )
34
+ public IRubyObject update( IRubyObject val ) {
35
+ double v = RubyNumeric.num2dbl( val );
36
+
37
+ if ( 0 == this.count ) {
38
+ this.min = this.max = v;
39
+ } else {
40
+ this.min = ( v < this.min ) ? v : this.min;
41
+ this.max = ( v > this.max ) ? v : this.max;
42
+ }
43
+
44
+ this.count += 1;
45
+ this.sum += v;
46
+ this.sumsq += (v * v);
47
+
48
+ return val;
49
+ }
50
+
51
+ @JRubyMethod( name = "mean" )
52
+ public IRubyObject mean() {
53
+ double mean = 0.0;
54
+
55
+ if ( this.count > 0 ) {
56
+ mean = this.sum / this.count;
57
+ }
58
+
59
+ return getRuntime().newFloat( mean );
60
+ }
61
+
62
+
63
+ @JRubyMethod( name = "rate" )
64
+ public IRubyObject rate() {
65
+ double rate = 0.0;
66
+
67
+ if ( this.sum > 0.0 ) {
68
+ rate = this.count / this.sum ;
69
+ }
70
+
71
+ return getRuntime().newFloat( rate );
72
+ }
73
+
74
+ @JRubyMethod( name = "stddev" )
75
+ public IRubyObject stddev() {
76
+ double stddev = 0.0;
77
+
78
+ if ( this.count > 1 ) {
79
+ double sq_sum = this.sum * this.sum;
80
+ stddev = Math.sqrt( ( this.sumsq - ( sq_sum / this.count ) ) / ( this.count - 1 ) );
81
+ }
82
+ return getRuntime().newFloat( stddev );
83
+ }
84
+
85
+
86
+ @JRubyMethod( name = "min" )
87
+ public IRubyObject min() {
88
+ return getRuntime().newFloat( this.min );
89
+ }
90
+
91
+ @JRubyMethod( name = "max" )
92
+ public IRubyObject max() {
93
+ return getRuntime().newFloat( this.max );
94
+ }
95
+
96
+ @JRubyMethod( name = "sum" )
97
+ public IRubyObject sum() {
98
+ return getRuntime().newFloat( this.sum );
99
+ }
100
+
101
+ @JRubyMethod( name = "sumsq" )
102
+ public IRubyObject sumsq() {
103
+ return getRuntime().newFloat( this.sumsq );
104
+ }
105
+
106
+ @JRubyMethod( name = "count" )
107
+ public IRubyObject count() {
108
+ return getRuntime().newFixnum( this.count );
109
+ }
110
+ }
111
+
112
+
@@ -15,16 +15,26 @@ module Hitimes
15
15
  # Base class of all errors in Hitimes
16
16
  #
17
17
  class Error < ::StandardError; end
18
+
19
+ # Hitimes.measure { } -> Float
20
+ #
21
+ # Times the execution of the block, returning the number of seconds it took
22
+ def self.measure(&block)
23
+ Hitimes::Interval.measure(&block)
24
+ end
18
25
  end
19
26
  require 'hitimes/paths'
20
27
  require 'hitimes/version'
21
28
 
22
- if RUBY_PLATFORM == "java" then
29
+ # Load the binary extension, try loading one for the specific version of ruby
30
+ # and if that fails, then fall back to one in the top of the library.
31
+ # this is the method recommended by rake-compiler
32
+ begin
33
+ # this will be for windows
34
+ require "hitimes/#{RUBY_VERSION.sub(/\.\d$/,'')}/hitimes"
35
+ rescue LoadError
36
+ # everyone else.
23
37
  require 'hitimes/hitimes'
24
- else
25
- # use a version subdirectory for extensions, initially to support windows, but
26
- # why make a special case. It doesn't hurt anyone to have an extra subdir.
27
- require "hitimes/#{RUBY_VERSION.sub(/\.\d$/,'')}/hitimes_ext"
28
38
  end
29
39
 
30
40
  require 'hitimes/stats'
@@ -4,54 +4,5 @@
4
4
  #++
5
5
 
6
6
  module Hitimes
7
- #
8
- # module containing all the version information about Hitimes
9
- #
10
- module Version
11
-
12
- # Major version number
13
- MAJOR = 1
14
-
15
- # Minor version number
16
- MINOR = 1
17
-
18
- # Build number
19
- BUILD = 1
20
-
21
- #
22
- # :call-seq:
23
- # Version.to_a -> [ MAJOR, MINOR, BUILD ]
24
- #
25
- # Return the version as an array of Integers
26
- #
27
- def self.to_a
28
- [MAJOR, MINOR, BUILD]
29
- end
30
-
31
- #
32
- # :call-seq:
33
- # Version.to_s -> "MAJOR.MINOR.BUILD"
34
- #
35
- # Return the version as a String with dotted notation
36
- #
37
- def self.to_s
38
- to_a.join(".")
39
- end
40
-
41
- #
42
- # :call-seq:
43
- # Version.to_hash -> { :major => ..., :minor => ..., :build => ... }
44
- #
45
- # Return the version as a Hash
46
- #
47
- def self.to_hash
48
- { :major => MAJOR, :minor => MINOR, :build => BUILD }
49
- end
50
-
51
- # The Version in MAJOR.MINOR.BUILD dotted notation
52
- STRING = Version.to_s
53
- end
54
-
55
- # The Version in MAJOR.MINOR.BUILD dotted notation
56
- VERSION = Version.to_s
7
+ VERSION = "1.2.0"
57
8
  end