actsasflinn-ruby-tokyotyrant 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }