actsasflinn-ruby-tokyotyrant 0.1.2 → 0.1.3

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.
@@ -0,0 +1,74 @@
1
+ require 'benchmark'
2
+ require 'rubygems'
3
+ require 'faker'
4
+
5
+ puts "Tokyo Tyrant Bulk Operations Benchmark"
6
+
7
+ data = {}
8
+ data_e = {}
9
+ data_a = []
10
+
11
+ 10_000.times do |i|
12
+ data[i.to_s] = Faker::Name.name
13
+ data_e[i.to_s] = nil
14
+ data_a << i.to_s
15
+ data_a << data[i.to_s]
16
+ end
17
+
18
+ require 'tokyotyrant'
19
+
20
+ rdb = TokyoTyrant::RDB::new
21
+ rdb.open("127.0.0.1", 1978)
22
+ rdb.clear
23
+ nothing = nil
24
+
25
+ 2.times { puts }
26
+ puts 'TokyoTyrant::RDB (Ruby) mget'
27
+
28
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
29
+ b.report('inserting data') do
30
+ rdb.misc('putlist', data_a)
31
+ end
32
+
33
+ b.report('reading data') do
34
+ rdb.mget(data_e)
35
+ end
36
+ end
37
+
38
+ require 'tokyo_tyrant'
39
+ t = TokyoTyrant::DB.new('127.0.0.1', 1978)
40
+ t.clear
41
+ nothing = nil
42
+
43
+ 2.times { puts }
44
+ puts 'TokyoTyrant (c) mput/mget'
45
+
46
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
47
+ b.report('inserting data ') do
48
+ t.mput(data)
49
+ end
50
+
51
+ b.report('reading data') do
52
+ nothing = t.mget(0..9999)
53
+ end
54
+ end
55
+
56
+ require 'memcached'
57
+ m = Memcached.new('127.0.0.1:11211')
58
+ m.flush
59
+ nothing = nil
60
+
61
+ 2.times { puts }
62
+ puts 'Memcached (C) set/get_multi'
63
+
64
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
65
+ b.report('inserting data*') do
66
+ data.each_pair { |k, v| m.set(k, v) }
67
+ end
68
+
69
+ b.report('reading data') do
70
+ nothing = m.get(data.keys)
71
+ end
72
+ end
73
+
74
+ puts "* bulk operation not supported"
@@ -0,0 +1,85 @@
1
+ require 'benchmark'
2
+ require 'rubygems'
3
+ require 'faker'
4
+ require 'date'
5
+
6
+ $year = (1909 .. 2009).to_a
7
+ $month = (1..12).to_a
8
+ $day = (1..28).to_a # not bothering with month diffs
9
+
10
+ def rbdate
11
+ DateTime.new($year[rand($year.size)], $month[rand($month.size)], $day[rand($day.size)])
12
+ end
13
+
14
+ def rdiv
15
+ case rand(3)
16
+ when 0
17
+ 'dev'
18
+ when 1
19
+ 'brd'
20
+ else
21
+ 'brd,dev'
22
+ end
23
+ end
24
+
25
+ def rgen
26
+ (rand(2) == 1 ? 'male' : 'female')
27
+ end
28
+
29
+ data = {}
30
+ 10_000.times do |i|
31
+ data[i] = { :name => Faker::Name.name, :sex => rgen, :birthday => rbdate.to_s, :divisions => rdiv }
32
+ end
33
+
34
+ require 'tokyo_tyrant'
35
+ t = TokyoTyrant::Table.new('127.0.0.1', 1978)
36
+ t.clear
37
+
38
+ 2.times { puts }
39
+ puts 'TokyoTyrant (C)'
40
+
41
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
42
+ b.report('bulk writing data') do
43
+ nothing = t.mput(data)
44
+ end
45
+
46
+ b.report('bulk reading data') do
47
+ nothing = t.mget(0..9999)
48
+ end
49
+ end
50
+
51
+ require 'tokyotyrant'
52
+
53
+ rdb = TokyoTyrant::RDB::new
54
+ rdb.open("127.0.0.1", 1978)
55
+ rdb.clear
56
+
57
+ 2.times { puts }
58
+ puts 'TokyoTyrant::RDB (Ruby)'
59
+
60
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
61
+ b.report('bulk inserting data*') do
62
+ # is this fair to put in the benchmark? yes because it happens within the c-ext
63
+ data_a = []
64
+ data.each_pair{ |i,v|
65
+ data_a << i.to_s
66
+ data_a << v.collect{ |k,v| [k.to_s,v] }.join("\0")
67
+ }
68
+ rdb.misc('putlist', data_a)
69
+ end
70
+
71
+ b.report('bulk reading data ') do
72
+ l = rdb.misc('getlist', data.keys)
73
+ h = Hash[*l]
74
+ h.each_pair do |k,v|
75
+ a = v.split("\0")
76
+ h[k] = Hash[*a]
77
+ end
78
+ end
79
+ end
80
+
81
+ puts "\nNotes:"
82
+ puts "* To supply a hash for bulk operations TokyoTyrant::RDB creates an array and join hash columns."
83
+ puts "* This operation is included in the benchmark because the same code exists within the c-ext."
84
+ puts "Rufus::Tokyo::TyrantTable does not support the misc method, therefor cannot handle a putlist/getlist"
85
+ puts "Memcached does not support bulk writing"
data/benchmarks/db.rb ADDED
@@ -0,0 +1,114 @@
1
+ require 'benchmark'
2
+ require 'rubygems'
3
+ require 'faker'
4
+
5
+ data = []
6
+
7
+ 10_000.times do |i|
8
+ data << Faker::Name.name
9
+ end
10
+
11
+ require 'rufus/tokyo/tyrant'
12
+
13
+ r = Rufus::Tokyo::Tyrant.new('127.0.0.1', 1978)
14
+ r.clear
15
+
16
+ 2.times { puts }
17
+ puts 'Tokyo::Tyrant (Ruby FFI)'
18
+
19
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
20
+ b.report('inserting data') do
21
+ data.each_with_index { |e, i| r[i.to_s] = e }
22
+ end
23
+
24
+ b.report('reading data') do
25
+ data.each_with_index { |e, i| nothing = r[i.to_s] }
26
+ end
27
+ end
28
+
29
+ require 'tokyotyrant'
30
+
31
+ rdb = TokyoTyrant::RDB::new
32
+ rdb.open("127.0.0.1", 1978)
33
+ rdb.clear
34
+
35
+ 2.times { puts }
36
+ puts 'TokyoTyrant::RDB (Ruby)'
37
+
38
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
39
+ b.report('inserting data') do
40
+ data.each_with_index { |e, i| rdb.put(i.to_s, e) }
41
+ end
42
+
43
+ b.report('reading data') do
44
+ data.each_with_index { |e, i| nothing = rdb.get(i.to_s) }
45
+ end
46
+ end
47
+
48
+ require 'tokyo_tyrant'
49
+ t = TokyoTyrant::DB.new('127.0.0.1', 1978)
50
+ t.clear
51
+
52
+ 2.times { puts }
53
+ puts 'TokyoTyrant (C)'
54
+
55
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
56
+ b.report('inserting data') do
57
+ data.each_with_index { |e, i| t[i] = e }
58
+ end
59
+
60
+ b.report('reading data') do
61
+ data.each_with_index { |e, i| nothing = t[i] }
62
+ end
63
+ end
64
+
65
+ require 'memcached'
66
+ m = Memcached.new('127.0.0.1:1978')
67
+ m.flush
68
+
69
+ 2.times { puts }
70
+ puts 'Memcached (C) to Tyrant'
71
+
72
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
73
+ b.report('inserting data') do
74
+ data.each_with_index { |e, i| m.set(i.to_s, e) }
75
+ end
76
+
77
+ b.report('reading data') do
78
+ data.each_with_index { |e, i| nothing = m.get(i.to_s) }
79
+ end
80
+ end
81
+
82
+ require 'memcached'
83
+ m = Memcached.new('127.0.0.1:11211')
84
+ m.flush
85
+
86
+ 2.times { puts }
87
+ puts 'Memcached (C) to Memcached'
88
+
89
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
90
+ b.report('inserting data') do
91
+ data.each_with_index { |e, i| m.set(i.to_s, e) }
92
+ end
93
+
94
+ b.report('reading data') do
95
+ data.each_with_index { |e, i| nothing = m.get(i.to_s) }
96
+ end
97
+ end
98
+
99
+ require 'memcache'
100
+ mc = MemCache.new('127.0.0.1:11211')
101
+ mc.flush_all
102
+
103
+ 2.times { puts }
104
+ puts 'MemCache (Ruby)'
105
+
106
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
107
+ b.report('inserting data') do
108
+ data.each_with_index { |e, i| mc.set(i.to_s, e) }
109
+ end
110
+
111
+ b.report('reading data') do
112
+ data.each_with_index { |e, i| nothing = mc.get(i.to_s) }
113
+ end
114
+ end
@@ -0,0 +1,161 @@
1
+ require 'benchmark'
2
+ require 'rubygems'
3
+ require 'faker'
4
+ require 'date'
5
+
6
+ #
7
+ # the data
8
+ #
9
+
10
+ colnames = %w{ name sex birthday divisions }
11
+
12
+ $year = (1909 .. 2009).to_a
13
+ $month = (1..12).to_a
14
+ $day = (1..28).to_a # not bothering with month diffs
15
+
16
+ def rbdate
17
+ DateTime.new($year[rand($year.size)], $month[rand($month.size)], $day[rand($day.size)])
18
+ end
19
+
20
+ def rdiv
21
+ case rand(3)
22
+ when 0
23
+ 'dev'
24
+ when 1
25
+ 'brd'
26
+ else
27
+ 'brd,dev'
28
+ end
29
+ end
30
+
31
+ def rgen
32
+ (rand(2) == 1 ? 'male' : 'female')
33
+ end
34
+
35
+ data = [
36
+ [ 'Alphonse Armalite', 'male', DateTime.new(1972, 10, 14), 'brd,dev' ],
37
+ [ 'Brutus Beromunster', 'male', DateTime.new(1964, 07, 14), 'dev' ],
38
+ [ 'Crystel Chucknorris', 'female', DateTime.new(1980, 07, 12), 'brd' ],
39
+ [ 'Desree Dylan', 'female', DateTime.new(1954, 07, 13), 'brd,dev' ]
40
+ ]
41
+
42
+ 10_000.times do |i|
43
+ data << [ Faker::Name.name, rgen, rbdate, rdiv]
44
+ end
45
+
46
+ $find_name_list = []
47
+ 100.times { $find_name_list << data[rand(data.size)][0] }
48
+
49
+ data.collect! { |e|
50
+ (0..colnames.length - 1).inject({}) { |h, i| h[colnames[i]] = e[i]; h }
51
+ }
52
+
53
+ data_h = {}
54
+ i = 0
55
+ data1 = data.collect { |e|
56
+ i = i + 1
57
+ h = e.dup
58
+ h['birthday'] = h['birthday'].to_s
59
+ data_h[i.to_s] = h
60
+ h
61
+ }
62
+
63
+ require 'rufus/tokyo/tyrant'
64
+
65
+ r = Rufus::Tokyo::TyrantTable.new('127.0.0.1', 1978)
66
+ r.clear
67
+
68
+ 2.times { puts }
69
+ puts 'Tokyo::TyrantTable (Ruby FFI)'
70
+
71
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
72
+ b.report('inserting data') do
73
+ data1.each_with_index { |e, i| r[i.to_s] = e }
74
+ end
75
+
76
+ b.report('reading data') do
77
+ data1.each_with_index { |e, i| nothing = r[i.to_s] }
78
+ end
79
+ end
80
+
81
+ require 'tokyotyrant'
82
+
83
+ rdb = TokyoTyrant::RDBTBL::new
84
+ rdb.open("127.0.0.1", 1978)
85
+ rdb.clear
86
+
87
+ 2.times { puts }
88
+ puts 'TokyoTyrant::RDB (Ruby)'
89
+
90
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
91
+ b.report('inserting data') do
92
+ data1.each_with_index { |e, i| rdb.put(i.to_s, e) }
93
+ end
94
+
95
+ b.report('reading data') do
96
+ data1.each_with_index { |e, i| nothing = rdb.get(i.to_s) }
97
+ end
98
+ end
99
+
100
+ require 'tokyo_tyrant'
101
+ t = TokyoTyrant::Table.new('127.0.0.1', 1978)
102
+ t.clear
103
+
104
+ 2.times { puts }
105
+ puts 'TokyoTyrant (C)'
106
+
107
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
108
+ b.report('inserting data') do
109
+ data1.each_with_index { |e, i| t[i] = e }
110
+ end
111
+
112
+ b.report('reading data') do
113
+ data1.each_with_index { |e, i| nothing = t[i] }
114
+ end
115
+
116
+ b.report('bulk writing data') do
117
+ nothing = t.mput(data_h)
118
+ end
119
+
120
+ b.report('bulk reading data') do
121
+ nothing = t.mget(0..9999)
122
+ end
123
+ end
124
+
125
+ require 'memcached'
126
+ m = Memcached.new('127.0.0.1:11211')
127
+ m.flush
128
+
129
+ 2.times { puts }
130
+ puts 'Memcached (C)'
131
+
132
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
133
+ b.report('inserting data') do
134
+ data1.each_with_index { |e, i| m.set(i.to_s, e) }
135
+ end
136
+
137
+ b.report('reading data') do
138
+ data1.each_with_index { |e, i| nothing = m.get(i.to_s) }
139
+ end
140
+
141
+ b.report('bulk reading data') do
142
+ nothing = m.get((0..9999).to_a.collect{|i| i.to_s})
143
+ end
144
+ end
145
+
146
+ require 'memcache'
147
+ mc = MemCache.new('127.0.0.1:11211')
148
+ mc.flush_all
149
+
150
+ 2.times { puts }
151
+ puts 'MemCache (Ruby)'
152
+
153
+ Benchmark.benchmark(' ' * 20 + Benchmark::Tms::CAPTION, 20) do |b|
154
+ b.report('inserting data') do
155
+ data1.each_with_index { |e, i| mc.set(i.to_s, e) }
156
+ end
157
+
158
+ b.report('reading data') do
159
+ data1.each_with_index { |e, i| nothing = mc.get(i.to_s) }
160
+ end
161
+ end
@@ -0,0 +1,162 @@
1
+ #include <tokyo_tyrant.h>
2
+
3
+ extern VALUE StringValueEx(VALUE vobj){
4
+ char kbuf[NUMBUFSIZ];
5
+ int ksiz;
6
+ switch(TYPE(vobj)){
7
+ case T_FIXNUM:
8
+ ksiz = sprintf(kbuf, "%d", (int)FIX2INT(vobj));
9
+ return rb_str_new(kbuf, ksiz);
10
+ case T_BIGNUM:
11
+ ksiz = sprintf(kbuf, "%lld", (long long)NUM2LL(vobj));
12
+ return rb_str_new(kbuf, ksiz);
13
+ case T_SYMBOL:
14
+ return rb_str_new2(rb_id2name(SYM2ID(vobj)));
15
+ case T_TRUE:
16
+ ksiz = sprintf(kbuf, "true");
17
+ return rb_str_new(kbuf, ksiz);
18
+ case T_FALSE:
19
+ ksiz = sprintf(kbuf, "false");
20
+ return rb_str_new(kbuf, ksiz);
21
+ // I don't like this, I'd rather an empty string
22
+ // case T_NIL:
23
+ // ksiz = sprintf(kbuf, "nil");
24
+ // return rb_str_new(kbuf, ksiz);
25
+ default:
26
+ if (rb_respond_to(vobj, rb_intern("to_s"))) {
27
+ return rb_convert_type(vobj, T_STRING, "String", "to_s");
28
+ }
29
+ }
30
+ return StringValue(vobj);
31
+ }
32
+
33
+ extern TCLIST *varytolist(VALUE vary){
34
+ VALUE vval;
35
+ TCLIST *list;
36
+ int i, num;
37
+ num = RARRAY_LEN(vary);
38
+ list = tclistnew2(num);
39
+ for(i = 0; i < num; i++){
40
+ vval = rb_ary_entry(vary, i);
41
+ vval = StringValueEx(vval);
42
+ tclistpush(list, RSTRING_PTR(vval), RSTRING_LEN(vval));
43
+ }
44
+ return list;
45
+ }
46
+
47
+ extern VALUE listtovary(TCLIST *list){
48
+ VALUE vary;
49
+ const char *vbuf;
50
+ int i, num, vsiz;
51
+ num = tclistnum(list);
52
+ vary = rb_ary_new2(num);
53
+ for(i = 0; i < num; i++){
54
+ vbuf = tclistval(list, i, &vsiz);
55
+ rb_ary_push(vary, rb_str_new(vbuf, vsiz));
56
+ }
57
+ return vary;
58
+ }
59
+
60
+ extern TCMAP *vhashtomap(VALUE vhash){
61
+ VALUE vkeys, vkey, vval;
62
+ TCMAP *map;
63
+ int i, num;
64
+ map = tcmapnew2(31);
65
+ vkeys = rb_funcall(vhash, rb_intern("keys"), 0);
66
+ num = RARRAY_LEN(vkeys);
67
+ for(i = 0; i < num; i++){
68
+ vkey = rb_ary_entry(vkeys, i);
69
+ vval = rb_hash_aref(vhash, vkey);
70
+ vkey = StringValueEx(vkey);
71
+ vval = StringValueEx(vval);
72
+ tcmapput(map, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vval), RSTRING_LEN(vval));
73
+ }
74
+ return map;
75
+ }
76
+
77
+ extern VALUE maptovhash(TCMAP *map){
78
+ const char *kbuf, *vbuf;
79
+ int ksiz, vsiz;
80
+ VALUE vhash;
81
+ vhash = rb_hash_new();
82
+ tcmapiterinit(map);
83
+ while((kbuf = tcmapiternext(map, &ksiz)) != NULL){
84
+ vbuf = tcmapiterval(kbuf, &vsiz);
85
+ rb_hash_aset(vhash, rb_str_new(kbuf, ksiz), rb_str_new(vbuf, vsiz));
86
+ }
87
+ return vhash;
88
+ }
89
+
90
+ extern VALUE maptovhashsym(TCMAP *map){
91
+ const char *kbuf, *vbuf;
92
+ int ksiz, vsiz;
93
+ VALUE vhash;
94
+ vhash = rb_hash_new();
95
+ tcmapiterinit(map);
96
+ while((kbuf = tcmapiternext(map, &ksiz)) != NULL){
97
+ vbuf = tcmapiterval(kbuf, &vsiz);
98
+ rb_hash_aset(vhash, ID2SYM(rb_intern(kbuf)), rb_str_new(vbuf, vsiz));
99
+ }
100
+ return vhash;
101
+ }
102
+
103
+ extern TCMAP *varytomap(VALUE vary){
104
+ int i;
105
+ TCLIST *keys;
106
+ TCMAP *recs = tcmapnew();
107
+ keys = varytolist(vary);
108
+ for(i = 0; i < tclistnum(keys); i++){
109
+ int ksiz;
110
+ const char *kbuf = tclistval(keys, i, &ksiz);
111
+ tcmapput(recs, kbuf, ksiz, "", 0);
112
+ }
113
+ return recs;
114
+ }
115
+
116
+ extern TCLIST *vhashtolist(VALUE vhash){
117
+ /*
118
+ Seems like something like this might work just as well
119
+ vary = rb_hash_to_a(vhash);
120
+ vary = rb_ary_flatten(vary);
121
+ args = varytolist(vary);
122
+ */
123
+
124
+ VALUE vkeys, vkey, vval;
125
+ TCLIST *list;
126
+ int i, num;
127
+ vkeys = rb_funcall(vhash, rb_intern("keys"), 0);
128
+ num = RARRAY_LEN(vkeys);
129
+ list = tclistnew2(num);
130
+ for(i = 0; i < num; i++){
131
+ vkey = rb_ary_entry(vkeys, i);
132
+ vval = rb_hash_aref(vhash, vkey);
133
+ vkey = StringValueEx(vkey);
134
+ vval = StringValueEx(vval);
135
+ tclistpush(list, RSTRING_PTR(vkey), RSTRING_LEN(vkey));
136
+ tclistpush(list, RSTRING_PTR(vval), RSTRING_LEN(vval));
137
+ }
138
+ return list;
139
+ }
140
+
141
+ VALUE mTokyoTyrant;
142
+ VALUE eTokyoTyrantError;
143
+ VALUE cDB;
144
+ VALUE cTable;
145
+ VALUE cQuery;
146
+
147
+ void Init_tokyo_tyrant(){
148
+ mTokyoTyrant = rb_define_module("TokyoTyrant");
149
+ eTokyoTyrantError = rb_define_class("TokyoTyrantError", rb_eStandardError);
150
+ init_mod();
151
+
152
+ cDB = rb_define_class_under(mTokyoTyrant, "DB", rb_cObject);
153
+ rb_include_module(cDB, mTokyoTyrant);
154
+ init_db();
155
+
156
+ cTable = rb_define_class_under(mTokyoTyrant, "Table", rb_cObject);
157
+ rb_include_module(cTable, mTokyoTyrant);
158
+ init_table();
159
+
160
+ cQuery = rb_define_class_under(mTokyoTyrant, "Query", rb_cObject);
161
+ init_query();
162
+ }