stream_stats 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +11 -0
- data/Gemfile.lock +24 -0
- data/README.rdoc +8 -5
- data/Rakefile +53 -0
- data/ext/stream_stats/counter.c +103 -0
- data/ext/stream_stats/counter.h +77 -0
- data/ext/stream_stats/stream_stats.c +17 -17
- data/ext/stream_stats/stream_stats_counter.c +87 -0
- data/lib/stream_stats/counter.rb +11 -0
- data/lib/stream_stats/version.rb +2 -3
- data/lib/stream_stats.rb +2 -1
- data/test/stream_stats/counter_test.rb +24 -0
- data/test/stream_stats/stream_test.rb +29 -0
- data/test/test_helper.rb +9 -0
- metadata +34 -8
- data/stream_stats.gemspec +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84b135a85d843c06875ca540fd2a492d932f1a7c
|
4
|
+
data.tar.gz: 2c3747c578d13fa06f344cfa2a2079faa03bdc4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ca93d154216b3e4eebe987a214517d8cf9516c14513fed62102a7d0a91104336ae7dc2d20c96a01e606a8aded8be1314d044252f03f378f615e2b0c6d931c6d
|
7
|
+
data.tar.gz: 39870beb67f6d297a944b4c6215f211f8f00a6f2f5a62edfbf794e49ad0555d8dd978f949325a5bace3218519fa51d3a1159c9fbd3c2a39d36993d9e52469082
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
stream_stats (0.0.4)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
multi_json (1.7.6)
|
10
|
+
rake (10.0.4)
|
11
|
+
rdoc (4.0.0)
|
12
|
+
simplecov (0.7.1)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
simplecov-html (~> 0.7.1)
|
15
|
+
simplecov-html (0.7.1)
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
ruby
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
rake
|
22
|
+
rdoc
|
23
|
+
simplecov
|
24
|
+
stream_stats!
|
data/README.rdoc
CHANGED
@@ -16,14 +16,16 @@ Create stream and add values
|
|
16
16
|
stream = StreamStats::Stream.new(0.001, [0.50, 0.90])
|
17
17
|
|
18
18
|
Parameters:
|
19
|
-
precision level
|
20
|
-
array of quantiles for guaranteed precision
|
19
|
+
1) precision level
|
20
|
+
2) array of quantiles for guaranteed precision
|
21
21
|
|
22
|
-
The above example guarantees that the 50% and 90% percentile results are
|
22
|
+
The above example guarantees that the 50% and 90% percentile results are accurate to +/- 0.001.
|
23
23
|
|
24
24
|
Populate stream with samples:
|
25
25
|
|
26
|
-
(0..20).each do |i|
|
26
|
+
(0..20).each do |i|
|
27
|
+
stream << i
|
28
|
+
end
|
27
29
|
|
28
30
|
Get stream result whenever desired:
|
29
31
|
|
@@ -39,5 +41,6 @@ Get stream result whenever desired:
|
|
39
41
|
|
40
42
|
=== Credit
|
41
43
|
|
42
|
-
Complete credit goes to Armon Dadgar.
|
44
|
+
Complete credit goes to Armon Dadgar.
|
45
|
+
Algorithm code copied directly out of [statsite](http://github.com/armon/statsite)
|
43
46
|
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/clean'
|
5
|
+
require 'rdoc/task'
|
6
|
+
|
7
|
+
task default: :test
|
8
|
+
|
9
|
+
NAME = 'stream_stats'
|
10
|
+
|
11
|
+
# rule to build the extension: this says
|
12
|
+
# that the extension should be rebuilt
|
13
|
+
# after any change to the files in ext
|
14
|
+
file "lib/#{NAME}/#{NAME}.#{RbConfig::CONFIG['DLEXT']}" =>
|
15
|
+
Dir.glob("ext/#{NAME}/*{.rb,.c}") do
|
16
|
+
Dir.chdir("ext/#{NAME}") do
|
17
|
+
# this does essentially the same thing
|
18
|
+
# as what RubyGems does
|
19
|
+
ruby "extconf.rb"
|
20
|
+
sh "make"
|
21
|
+
end
|
22
|
+
cp "ext/#{NAME}/#{NAME}.#{RbConfig::CONFIG['DLEXT']}", "lib/#{NAME}"
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# make the :test task depend on the shared
|
27
|
+
# object, so it will be built automatically
|
28
|
+
# before running the tests
|
29
|
+
task :test => "lib/#{NAME}/#{NAME}.#{RbConfig::CONFIG['DLEXT']}"
|
30
|
+
|
31
|
+
# use 'rake clean' and 'rake clobber' to
|
32
|
+
# easily delete generated files
|
33
|
+
CLEAN.include("ext/**/*{.o,.log,.#{RbConfig::CONFIG['DLEXT']}}")
|
34
|
+
CLEAN.include('ext/**/Makefile')
|
35
|
+
CLEAN.include("lib/#{NAME}/#{NAME}.#{RbConfig::CONFIG['DLEXT']}")
|
36
|
+
CLOBBER.include("lib/**/*.#{RbConfig::CONFIG['DLEXT']}")
|
37
|
+
|
38
|
+
|
39
|
+
Rake::TestTask.new(:test) do |t|
|
40
|
+
t.libs << 'lib'
|
41
|
+
t.libs << 'test'
|
42
|
+
t.pattern = 'test/**/*_test.rb'
|
43
|
+
t.verbose = true
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'Generate documentation.'
|
47
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
48
|
+
rdoc.rdoc_dir = 'rdoc'
|
49
|
+
rdoc.title = 'StreamStats'
|
50
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
51
|
+
rdoc.rdoc_files.include('README.rdoc')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#include <math.h>
|
2
|
+
#include "counter.h"
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Initializes the counter struct
|
6
|
+
* @arg counter The counter struct to initialize
|
7
|
+
* @return 0 on success.
|
8
|
+
*/
|
9
|
+
int init_counter(counter *counter) {
|
10
|
+
counter->count = 0;
|
11
|
+
counter->sum = 0;
|
12
|
+
counter->squared_sum = 0;
|
13
|
+
counter->min = 0;
|
14
|
+
counter->max = 0;
|
15
|
+
return 0;
|
16
|
+
}
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Adds a new sample to the struct
|
20
|
+
* @arg counter The counter to add to
|
21
|
+
* @arg sample The new sample value
|
22
|
+
* @return 0 on success.
|
23
|
+
*/
|
24
|
+
int counter_add_sample(counter *counter, double sample) {
|
25
|
+
if (counter->count == 0) {
|
26
|
+
counter->min = counter->max = sample;
|
27
|
+
} else {
|
28
|
+
if (counter->min > sample)
|
29
|
+
counter->min = sample;
|
30
|
+
else if (counter->max < sample)
|
31
|
+
counter->max = sample;
|
32
|
+
}
|
33
|
+
counter->count++;
|
34
|
+
counter->sum += sample;
|
35
|
+
counter->squared_sum += pow(sample, 2);
|
36
|
+
return 0;
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Returns the number of samples in the counter
|
41
|
+
* @arg counter The counter to query
|
42
|
+
* @return The number of samples
|
43
|
+
*/
|
44
|
+
uint64_t counter_count(counter *counter) {
|
45
|
+
return counter->count;
|
46
|
+
}
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Returns the mean counter value
|
50
|
+
* @arg counter The counter to query
|
51
|
+
* @return The mean value
|
52
|
+
*/
|
53
|
+
double counter_mean(counter *counter) {
|
54
|
+
return (counter->count) ? counter->sum / counter->count : 0;
|
55
|
+
}
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Returns the sample standard deviation counter value
|
59
|
+
* @arg counter The counter to query
|
60
|
+
* @return The sample standard deviation
|
61
|
+
*/
|
62
|
+
double counter_stddev(counter *counter) {
|
63
|
+
double num = (counter->count * counter->squared_sum) - pow(counter->sum, 2);
|
64
|
+
double div = counter->count * (counter->count - 1);
|
65
|
+
if (div == 0) return 0;
|
66
|
+
return sqrt(num / div);
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Returns the sum of the counter
|
71
|
+
* @arg counter The counter to query
|
72
|
+
* @return The sum of values
|
73
|
+
*/
|
74
|
+
double counter_sum(counter *counter) {
|
75
|
+
return counter->sum;
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* Returns the sum squared of the counter
|
80
|
+
* @arg counter The counter to query
|
81
|
+
* @return The sum squared of values
|
82
|
+
*/
|
83
|
+
double counter_squared_sum(counter *counter) {
|
84
|
+
return counter->squared_sum;
|
85
|
+
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Returns the minimum value of the counter
|
89
|
+
* @arg counter The counter to query
|
90
|
+
* @return The minimum value.
|
91
|
+
*/
|
92
|
+
double counter_min(counter *counter) {
|
93
|
+
return counter->min;
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Returns the maximum value of the counter
|
98
|
+
* @arg counter The counter to query
|
99
|
+
* @return The maximum value.
|
100
|
+
*/
|
101
|
+
double counter_max(counter *counter) {
|
102
|
+
return counter->max;
|
103
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#ifndef COUNTER_H
|
2
|
+
#define COUNTER_H
|
3
|
+
#include <stdint.h>
|
4
|
+
|
5
|
+
typedef struct {
|
6
|
+
uint64_t count; // Count of items
|
7
|
+
double sum; // Sum of the values
|
8
|
+
double squared_sum; // Sum of the squared values
|
9
|
+
double min; // Minimum value
|
10
|
+
double max; // Maximum value
|
11
|
+
} counter;
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Initializes the counter struct
|
15
|
+
* @arg counter The counter struct to initialize
|
16
|
+
* @return 0 on success.
|
17
|
+
*/
|
18
|
+
int init_counter(counter *counter);
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Adds a new sample to the struct
|
22
|
+
* @arg counter The counter to add to
|
23
|
+
* @arg sample The new sample value
|
24
|
+
* @return 0 on success.
|
25
|
+
*/
|
26
|
+
int counter_add_sample(counter *counter, double sample);
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Returns the number of samples in the counter
|
30
|
+
* @arg counter The counter to query
|
31
|
+
* @return The number of samples
|
32
|
+
*/
|
33
|
+
uint64_t counter_count(counter *counter);
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Returns the mean counter value
|
37
|
+
* @arg counter The counter to query
|
38
|
+
* @return The mean value
|
39
|
+
*/
|
40
|
+
double counter_mean(counter *counter);
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Returns the sample standard deviation counter value
|
44
|
+
* @arg counter The counter to query
|
45
|
+
* @return The sample standard deviation
|
46
|
+
*/
|
47
|
+
double counter_stddev(counter *counter);
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Returns the sum of the counter
|
51
|
+
* @arg counter The counter to query
|
52
|
+
* @return The sum of values
|
53
|
+
*/
|
54
|
+
double counter_sum(counter *counter);
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Returns the sum squared of the counter
|
58
|
+
* @arg counter The counter to query
|
59
|
+
* @return The sum squared of values
|
60
|
+
*/
|
61
|
+
double counter_squared_sum(counter *counter);
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Returns the minimum value of the counter
|
65
|
+
* @arg counter The counter to query
|
66
|
+
* @return The minimum value.
|
67
|
+
*/
|
68
|
+
double counter_min(counter *counter);
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Returns the maximum value of the counter
|
72
|
+
* @arg counter The counter to query
|
73
|
+
* @return The maximum value.
|
74
|
+
*/
|
75
|
+
double counter_max(counter *counter);
|
76
|
+
|
77
|
+
#endif
|
@@ -7,6 +7,7 @@ VALUE timer_class;
|
|
7
7
|
|
8
8
|
static void strstat_timer_free(void *ptr) {
|
9
9
|
destroy_timer(ptr);
|
10
|
+
free(ptr);
|
10
11
|
}
|
11
12
|
|
12
13
|
static VALUE strstat_timer_init(VALUE self, VALUE rb_eps, VALUE rb_quantiles) {
|
@@ -37,19 +38,24 @@ static VALUE strstat_timer_init(VALUE self, VALUE rb_eps, VALUE rb_quantiles) {
|
|
37
38
|
init_timer(eps, quantiles, num_quantiles, i_timer);
|
38
39
|
|
39
40
|
VALUE data = Data_Wrap_Struct(timer_class, NULL, strstat_timer_free, i_timer);
|
40
|
-
rb_ivar_set(self, rb_intern("
|
41
|
+
rb_ivar_set(self, rb_intern("internal_struct"), data);
|
41
42
|
|
42
43
|
return Qnil;
|
43
44
|
}
|
44
45
|
|
46
|
+
static void *strstat_get_struct(VALUE self) {
|
47
|
+
void *ptr;
|
48
|
+
|
49
|
+
VALUE data = rb_ivar_get(self, rb_intern("internal_struct"));
|
50
|
+
Data_Get_Struct(data, timer, ptr);
|
51
|
+
return ptr;
|
52
|
+
}
|
53
|
+
|
45
54
|
static VALUE strstat_timer_add_sample(VALUE self, VALUE rb_sample) {
|
46
55
|
|
47
56
|
double sample = NUM2DBL(rb_sample);
|
48
57
|
|
49
|
-
timer *i_timer;
|
50
|
-
|
51
|
-
VALUE data = rb_ivar_get(self, rb_intern("timer"));
|
52
|
-
Data_Get_Struct(data, timer, i_timer);
|
58
|
+
timer *i_timer = (timer*) strstat_get_struct(self);
|
53
59
|
|
54
60
|
int returned = timer_add_sample(i_timer, sample);
|
55
61
|
if (returned != 0) {
|
@@ -60,10 +66,7 @@ static VALUE strstat_timer_add_sample(VALUE self, VALUE rb_sample) {
|
|
60
66
|
}
|
61
67
|
|
62
68
|
static VALUE strstat_timer_count(VALUE self) {
|
63
|
-
timer *i_timer;
|
64
|
-
|
65
|
-
VALUE data = rb_ivar_get(self, rb_intern("timer"));
|
66
|
-
Data_Get_Struct(data, timer, i_timer);
|
69
|
+
timer *i_timer = (timer*) strstat_get_struct(self);
|
67
70
|
|
68
71
|
return LONG2NUM(timer_count(i_timer));
|
69
72
|
}
|
@@ -73,10 +76,7 @@ static VALUE strstat_timer_query(VALUE self, VALUE rb_query) {
|
|
73
76
|
if (query < 0 || query > 1)
|
74
77
|
rb_raise(rb_eRuntimeError, "invalid quantile");
|
75
78
|
|
76
|
-
timer *i_timer;
|
77
|
-
|
78
|
-
VALUE data = rb_ivar_get(self, rb_intern("timer"));
|
79
|
-
Data_Get_Struct(data, timer, i_timer);
|
79
|
+
timer *i_timer = (timer*) strstat_get_struct(self);
|
80
80
|
return DBL2NUM(timer_query(i_timer, query));
|
81
81
|
}
|
82
82
|
|
@@ -89,10 +89,7 @@ static VALUE strstat_timer_percentile(VALUE self, VALUE rb_percentile) {
|
|
89
89
|
}
|
90
90
|
|
91
91
|
static VALUE strstat_timer_commoncall(VALUE self, double(*func)(timer*)) {
|
92
|
-
timer *i_timer;
|
93
|
-
|
94
|
-
VALUE data = rb_ivar_get(self, rb_intern("timer"));
|
95
|
-
Data_Get_Struct(data, timer, i_timer);
|
92
|
+
timer *i_timer = (timer*) strstat_get_struct(self);
|
96
93
|
return DBL2NUM((*func)(i_timer));
|
97
94
|
}
|
98
95
|
|
@@ -115,6 +112,8 @@ static VALUE strstat_timer_squared_sum(VALUE self) {
|
|
115
112
|
return strstat_timer_commoncall(self, timer_squared_sum);
|
116
113
|
}
|
117
114
|
|
115
|
+
extern void Init_stream_stats_counter(void);
|
116
|
+
|
118
117
|
void Init_stream_stats(void) {
|
119
118
|
VALUE module = rb_define_module("StreamStats");
|
120
119
|
|
@@ -132,4 +131,5 @@ void Init_stream_stats(void) {
|
|
132
131
|
rb_define_method(timer_class, "sum", strstat_timer_sum, 0);
|
133
132
|
rb_define_method(timer_class, "squared_sum", strstat_timer_squared_sum, 0);
|
134
133
|
|
134
|
+
Init_stream_stats_counter();
|
135
135
|
}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <stdio.h>
|
3
|
+
|
4
|
+
#include "counter.h"
|
5
|
+
|
6
|
+
VALUE counter_class;
|
7
|
+
|
8
|
+
static VALUE strstat_counter_init(VALUE self) {
|
9
|
+
|
10
|
+
counter *i_counter = (counter *) malloc(sizeof(counter));
|
11
|
+
|
12
|
+
init_counter(i_counter);
|
13
|
+
|
14
|
+
VALUE data = Data_Wrap_Struct(counter_class, NULL, free, i_counter);
|
15
|
+
rb_ivar_set(self, rb_intern("internal_struct"), data);
|
16
|
+
|
17
|
+
return Qnil;
|
18
|
+
}
|
19
|
+
|
20
|
+
static void *strstat_get_struct(VALUE self) {
|
21
|
+
void *ptr;
|
22
|
+
|
23
|
+
VALUE data = rb_ivar_get(self, rb_intern("internal_struct"));
|
24
|
+
Data_Get_Struct(data, counter, ptr);
|
25
|
+
return ptr;
|
26
|
+
}
|
27
|
+
|
28
|
+
static VALUE strstat_counter_add_sample(VALUE self, VALUE rb_sample) {
|
29
|
+
|
30
|
+
double sample = NUM2DBL(rb_sample);
|
31
|
+
|
32
|
+
counter *i_counter = (counter*) strstat_get_struct(self);
|
33
|
+
|
34
|
+
int returned = counter_add_sample(i_counter, sample);
|
35
|
+
if (returned != 0) {
|
36
|
+
rb_raise(rb_eRuntimeError, "add sample returned %d", returned);
|
37
|
+
}
|
38
|
+
|
39
|
+
return Qnil;
|
40
|
+
}
|
41
|
+
|
42
|
+
static VALUE strstat_counter_count(VALUE self) {
|
43
|
+
counter *i_counter = (counter*) strstat_get_struct(self);
|
44
|
+
|
45
|
+
return LONG2NUM(counter_count(i_counter));
|
46
|
+
}
|
47
|
+
|
48
|
+
static VALUE strstat_counter_commoncall(VALUE self, double(*func)(counter*)) {
|
49
|
+
counter *i_counter = (counter*) strstat_get_struct(self);
|
50
|
+
return DBL2NUM((*func)(i_counter));
|
51
|
+
}
|
52
|
+
|
53
|
+
static VALUE strstat_counter_min(VALUE self) {
|
54
|
+
return strstat_counter_commoncall(self, counter_min);
|
55
|
+
}
|
56
|
+
static VALUE strstat_counter_max(VALUE self) {
|
57
|
+
return strstat_counter_commoncall(self, counter_max);
|
58
|
+
}
|
59
|
+
static VALUE strstat_counter_mean(VALUE self) {
|
60
|
+
return strstat_counter_commoncall(self, counter_mean);
|
61
|
+
}
|
62
|
+
static VALUE strstat_counter_stddev(VALUE self) {
|
63
|
+
return strstat_counter_commoncall(self, counter_stddev);
|
64
|
+
}
|
65
|
+
static VALUE strstat_counter_sum(VALUE self) {
|
66
|
+
return strstat_counter_commoncall(self, counter_sum);
|
67
|
+
}
|
68
|
+
static VALUE strstat_counter_squared_sum(VALUE self) {
|
69
|
+
return strstat_counter_commoncall(self, counter_squared_sum);
|
70
|
+
}
|
71
|
+
|
72
|
+
void Init_stream_stats_counter(void) {
|
73
|
+
VALUE module = rb_define_module("StreamStats");
|
74
|
+
|
75
|
+
counter_class = rb_define_class_under(module, "Counter", rb_cObject);
|
76
|
+
|
77
|
+
rb_define_method(counter_class, "initialize", strstat_counter_init, 0);
|
78
|
+
rb_define_method(counter_class, "<<", strstat_counter_add_sample, 1);
|
79
|
+
rb_define_method(counter_class, "count", strstat_counter_count, 0);
|
80
|
+
rb_define_method(counter_class, "min", strstat_counter_min, 0);
|
81
|
+
rb_define_method(counter_class, "max", strstat_counter_max, 0);
|
82
|
+
rb_define_method(counter_class, "mean", strstat_counter_mean, 0);
|
83
|
+
rb_define_method(counter_class, "stddev", strstat_counter_stddev, 0);
|
84
|
+
rb_define_method(counter_class, "sum", strstat_counter_sum, 0);
|
85
|
+
rb_define_method(counter_class, "squared_sum", strstat_counter_squared_sum, 0);
|
86
|
+
|
87
|
+
}
|
data/lib/stream_stats/version.rb
CHANGED
data/lib/stream_stats.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module StreamStats
|
4
|
+
class CounterTest < MiniTest::Spec
|
5
|
+
|
6
|
+
def test_basic
|
7
|
+
counter = StreamStats::Counter.new
|
8
|
+
|
9
|
+
(0..20).each do |i|
|
10
|
+
counter << i
|
11
|
+
end
|
12
|
+
|
13
|
+
assert_equal 21, counter.count
|
14
|
+
assert_equal 210.0, counter.sum
|
15
|
+
assert_equal 0.0, counter.min
|
16
|
+
assert_equal 20.0, counter.max
|
17
|
+
assert_equal 10.0, counter.mean
|
18
|
+
assert_in_delta 6.2048368229, counter.stddev, 0.0000000001
|
19
|
+
|
20
|
+
assert counter.inspect =~ /#<StreamStats::Counter:0x.*> {count: 21, sum: 210.0, min: 0.0, max: 20.0, mean: 10.0, stddev: 6.2048368229954285}/
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module StreamStats
|
4
|
+
class StreamTest < MiniTest::Spec
|
5
|
+
|
6
|
+
def test_basic
|
7
|
+
stream = StreamStats::Stream.new(0.001, [0.50, 0.90])
|
8
|
+
|
9
|
+
(0..20).each do |i|
|
10
|
+
stream << i
|
11
|
+
end
|
12
|
+
|
13
|
+
assert_equal 21, stream.count
|
14
|
+
assert_equal 210.0, stream.sum
|
15
|
+
assert_equal 0.0, stream.min
|
16
|
+
assert_equal 20.0, stream.max
|
17
|
+
assert_equal 10.0, stream.mean
|
18
|
+
assert_in_delta 6.2048368229, stream.stddev, 0.0000000001
|
19
|
+
assert_equal 10.0, stream.quantile(0.50)
|
20
|
+
assert_equal 10.0, stream.percentile(50)
|
21
|
+
assert_equal 18.0, stream.quantile(0.90)
|
22
|
+
assert_equal 18.0, stream.percentile(90)
|
23
|
+
assert_equal Hash[0.50 => 10.0, 0.9 => 18.0], stream.get_quantiles
|
24
|
+
|
25
|
+
assert stream.inspect =~ /#<StreamStats::Stream:0x.*> {count: 21, sum: 210.0, min: 0.0, max: 20.0, mean: 10.0, stddev: 6.2048368229954285, quantiles: {0.5=>10.0, 0.9=>18.0}}/
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stream_stats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Neville Kadwa
|
@@ -9,7 +9,21 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2013-06-13 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rdoc
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: Compute statistics on stream data
|
14
28
|
email:
|
15
29
|
- neville@kadwa.com
|
@@ -18,19 +32,28 @@ extensions:
|
|
18
32
|
- ext/stream_stats/extconf.rb
|
19
33
|
extra_rdoc_files: []
|
20
34
|
files:
|
21
|
-
-
|
35
|
+
- lib/stream_stats.rb
|
36
|
+
- lib/stream_stats/counter.rb
|
37
|
+
- lib/stream_stats/stream.rb
|
38
|
+
- lib/stream_stats/version.rb
|
22
39
|
- ext/stream_stats/cm_quantile.c
|
23
40
|
- ext/stream_stats/cm_quantile.h
|
41
|
+
- ext/stream_stats/counter.c
|
42
|
+
- ext/stream_stats/counter.h
|
24
43
|
- ext/stream_stats/extconf.rb
|
25
44
|
- ext/stream_stats/heap.c
|
26
45
|
- ext/stream_stats/heap.h
|
27
46
|
- ext/stream_stats/stream_stats.c
|
47
|
+
- ext/stream_stats/stream_stats_counter.c
|
28
48
|
- ext/stream_stats/timer.c
|
29
49
|
- ext/stream_stats/timer.h
|
30
|
-
-
|
31
|
-
-
|
32
|
-
-
|
33
|
-
-
|
50
|
+
- Gemfile
|
51
|
+
- Gemfile.lock
|
52
|
+
- README.rdoc
|
53
|
+
- Rakefile
|
54
|
+
- test/stream_stats/counter_test.rb
|
55
|
+
- test/stream_stats/stream_test.rb
|
56
|
+
- test/test_helper.rb
|
34
57
|
homepage: http://github.com/kadwanev/stream_stats
|
35
58
|
licenses: []
|
36
59
|
metadata: {}
|
@@ -54,4 +77,7 @@ rubygems_version: 2.0.3
|
|
54
77
|
signing_key:
|
55
78
|
specification_version: 4
|
56
79
|
summary: Stream Statistics
|
57
|
-
test_files:
|
80
|
+
test_files:
|
81
|
+
- test/stream_stats/counter_test.rb
|
82
|
+
- test/stream_stats/stream_test.rb
|
83
|
+
- test/test_helper.rb
|
data/stream_stats.gemspec
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path('../lib/stream_stats/version', __FILE__)
|
3
|
-
|
4
|
-
Gem::Specification.new do |s|
|
5
|
-
s.name = 'stream_stats'
|
6
|
-
s.version = '0.0.1'
|
7
|
-
s.summary = "Stream Statistics"
|
8
|
-
s.description = "Compute statistics on stream data"
|
9
|
-
s.version = StreamStats::VERSION
|
10
|
-
s.authors = ["Neville Kadwa"]
|
11
|
-
s.email = ["neville@kadwa.com"]
|
12
|
-
s.files = `git ls-files`.split($\)
|
13
|
-
s.homepage = 'http://github.com/kadwanev/stream_stats'
|
14
|
-
s.extensions = ['ext/stream_stats/extconf.rb']
|
15
|
-
end
|