actsasflinn-ruby-tokyotyrant 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -4,7 +4,7 @@ This is a c extension for Ruby to access TokyoTyrant databases. It currently su
4
4
 
5
5
  == Install
6
6
 
7
- # install tokyocabinet and tokyotyrant (requires 1.1.27)
7
+ # install tokyocabinet (1.4.29) and tokyotyrant (requires 1.1.31)
8
8
  # after installing tc and tt on linux I had to /sbin/ldconfig (as root)
9
9
  gem sources -a http://gems.github.com
10
10
  sudo gem install actsasflinn-ruby-tokyotyrant
@@ -111,6 +111,51 @@ This is not in production but the initial benchmarks are very interesting. Resul
111
111
  q.get
112
112
  # => [{:sex=>"male", :name=>"Pat 1", :__id=>"1"}, {:sex=>"male", :name=>"Pat 3", :__id=>"3"}, {:sex=>"male", :name=>"Pat 5", :__id=>"5"}, {:sex=>"male", :name=>"Pat 7", :__id=>"7"}, {:sex=>"male", :name=>"Pat 9", :__id=>"9"}]
113
113
 
114
- == TODO
115
- * implement get_reverse for has_value?
116
- * fix up and test extensions
114
+ === Full Text Search
115
+
116
+ require 'tokyo_tyrant'
117
+ require 'nokogiri'
118
+ require 'open-uri'
119
+
120
+ t = TokyoTyrant::Table.new('127.0.0.1', 1978)
121
+
122
+ (1..13).each do |n|
123
+ doc = Nokogiri::HTML(open("http://www.sacred-texts.com/chr/herm/hermes#{n}.htm"))
124
+ chapter = doc.css('h2').last.inner_text.gsub(/\n/, '').gsub(/ +/, ' ').strip
125
+ doc.css('p').each_with_index do |paragraph, i|
126
+ paragraph = paragraph.inner_text.gsub(/\n/, '').gsub(/ +/, ' ').strip
127
+ key = "chapter:#{n}:paragraph:#{i+1}"
128
+ t[key] = { :chapter => chapter, :paragraph => paragraph }
129
+ end
130
+ end
131
+
132
+ # full-text search with the phrase of
133
+ t.query{ |q| q.condition(:paragraph, :fts, 'rebirth') }
134
+ # => ["chapter:13:paragraph:4", "chapter:13:paragraph:5", "chapter:13:paragraph:7", "chapter:13:paragraph:19", "chapter:13:paragraph:27", "chapter:13:paragraph:44", "chapter:13:paragraph:57", "chapter:13:paragraph:69", "chapter:13:paragraph:125"]
135
+
136
+ # full-text search with all tokens in
137
+ t.query{ |q| q.condition(:paragraph, :ftsand, 'logos word') }
138
+ # => ["chapter:1:paragraph:12", "chapter:1:paragraph:14", "chapter:1:paragraph:17", "chapter:1:paragraph:19", "chapter:1:paragraph:24", "chapter:1:paragraph:27", "chapter:1:paragraph:43", "chapter:1:paragraph:53", "chapter:1:paragraph:62", "chapter:1:paragraph:89", "chapter:1:paragraph:90", "chapter:1:paragraph:94", "chapter:9:paragraph:5", "chapter:9:paragraph:35", "chapter:11:paragraph:3", "chapter:13:paragraph:2", "chapter:13:paragraph:94", "chapter:13:paragraph:121"]
139
+
140
+ # full-text search with at least one token in
141
+ t.query{ |q| q.condition(:paragraph, :ftsor, 'sermon key') }
142
+ # => ["chapter:5:paragraph:1", "chapter:9:paragraph:3", "chapter:10:paragraph:1", "chapter:10:paragraph:4", "chapter:10:paragraph:28", "chapter:11:paragraph:3", "chapter:11:paragraph:66", "chapter:11:paragraph:69", "chapter:13:paragraph:4", "chapter:13:paragraph:5", "chapter:13:paragraph:69"]
143
+
144
+ # negated full-text search with at least one token in
145
+ t.query{ |q| q.condition(:paragraph, '!ftsor', 'the god he and I that said') }
146
+ # => ["chapter:1:paragraph:95", "chapter:1:paragraph:96", "chapter:1:paragraph:97", "chapter:1:paragraph:98", "chapter:1:paragraph:99", "chapter:2:paragraph:3", "chapter:2:paragraph:5", "chapter:2:paragraph:6", "chapter:2:paragraph:7", "chapter:2:paragraph:9", "chapter:2:paragraph:11", "chapter:2:paragraph:13", "chapter:2:paragraph:15", "chapter:2:paragraph:17", "chapter:2:paragraph:19", "chapter:2:paragraph:21", "chapter:2:paragraph:36", "chapter:2:paragraph:43", "chapter:2:paragraph:47", "chapter:2:paragraph:48", "chapter:2:paragraph:49", "chapter:5:paragraph:4", "chapter:10:paragraph:27", "chapter:10:paragraph:62", "chapter:10:paragraph:64", "chapter:13:paragraph:3", "chapter:13:paragraph:9", "chapter:13:paragraph:17", "chapter:13:paragraph:24", "chapter:13:paragraph:29", "chapter:13:paragraph:32", "chapter:13:paragraph:37", "chapter:13:paragraph:45", "chapter:13:paragraph:50", "chapter:13:paragraph:56", "chapter:13:paragraph:59", "chapter:13:paragraph:63", "chapter:13:paragraph:67", "chapter:13:paragraph:70", "chapter:13:paragraph:76", "chapter:13:paragraph:82", "chapter:13:paragraph:87", "chapter:13:paragraph:88", "chapter:13:paragraph:90", "chapter:13:paragraph:98", "chapter:13:paragraph:101", "chapter:13:paragraph:105", "chapter:13:paragraph:110", "chapter:13:paragraph:113", "chapter:13:paragraph:117", "chapter:13:paragraph:123"]
147
+
148
+ === Lua Extension
149
+
150
+ # ttserver -ext spec/ext.lua
151
+ require 'tokyo_tyrant'
152
+ t = TokyoTyrant::Table.new('127.0.0.1', 1978)
153
+
154
+ t.run(:echo, 'hello', 'world')
155
+ # => "hello\tworld"
156
+
157
+ == Contributors
158
+
159
+ * Flinn Mueller (actsasflinn) author/maintainer
160
+ * Justin Reagor (cheapRoc) specs
161
+ * Seth Yates (sethyates) run method (lua ext)
data/Rakefile CHANGED
@@ -20,7 +20,7 @@ CLEAN.include('pkg', 'tmp')
20
20
 
21
21
  gemspec = Gem::Specification.new do |s|
22
22
  s.name = 'ruby-tokyotyrant'
23
- s.version = '0.1.8'
23
+ s.version = '0.1.9'
24
24
  s.authors = [ 'Flinn' ]
25
25
  s.email = 'flinn@actsasflinn.com'
26
26
  s.homepage = 'http://github.com/actsasflinn/ruby-tokyotyrant/'
data/ext/tokyo_tyrant.c CHANGED
@@ -103,19 +103,6 @@ extern VALUE maptovhash(TCMAP *map){
103
103
  return vhash;
104
104
  }
105
105
 
106
- extern VALUE maptovhashsym(TCMAP *map){
107
- const char *kbuf;
108
- int ksiz, vsiz;
109
- VALUE vhash;
110
- vhash = rb_hash_new();
111
- tcmapiterinit(map);
112
- while((kbuf = tcmapiternext(map, &ksiz)) != NULL){
113
- const char *vbuf = tcmapiterval(kbuf, &vsiz);
114
- rb_hash_aset(vhash, ID2SYM(rb_intern(kbuf)), StringRaw(vbuf, vsiz));
115
- }
116
- return vhash;
117
- }
118
-
119
106
  extern TCMAP *varytomap(VALUE vary){
120
107
  int i;
121
108
  TCLIST *keys;
data/ext/tokyo_tyrant.h CHANGED
@@ -42,7 +42,6 @@ extern TCLIST *varytolist(VALUE vary);
42
42
  extern VALUE listtovary(TCLIST *list);
43
43
  extern TCMAP *vhashtomap(VALUE vhash);
44
44
  extern VALUE maptovhash(TCMAP *map);
45
- extern VALUE maptovhashsym(TCMAP *map);
46
45
  extern TCMAP *varytomap(VALUE vhash);
47
46
  extern TCLIST *vhashtolist(VALUE vhash);
48
47
 
@@ -1,38 +1,33 @@
1
1
  #include <tokyo_tyrant_db.h>
2
2
 
3
3
  static VALUE cDB_put_method(VALUE vself, VALUE vkey, VALUE vstr, int method){
4
- int ecode;
5
4
  bool res;
6
- TCRDB *db;
7
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
5
+ TCRDB *db = mTokyoTyrant_getdb(vself);
8
6
 
9
7
  vkey = StringValueEx(vkey);
10
8
  vstr = StringValueEx(vstr);
11
9
 
12
10
  switch(method){
13
11
  case TTPUT:
14
- res = tcrdbput2(db, RSTRING_PTR(vkey), RSTRING_PTR(vstr));
12
+ res = tcrdbput(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr));
15
13
  break;
16
14
  case TTPUTKEEP:
17
- res = tcrdbputkeep2(db, RSTRING_PTR(vkey), RSTRING_PTR(vstr));
15
+ res = tcrdbputkeep(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr));
18
16
  break;
19
17
  case TTPUTCAT:
20
- res = tcrdbputcat2(db, RSTRING_PTR(vkey), RSTRING_PTR(vstr));
18
+ res = tcrdbputcat(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr));
21
19
  break;
22
20
  case TTPUTNR:
23
- res = tcrdbputnr2(db, RSTRING_PTR(vkey), RSTRING_PTR(vstr));
21
+ res = tcrdbputnr(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr));
24
22
  break;
25
23
  default:
26
24
  res = false;
27
25
  break;
28
26
  }
29
27
 
30
- if(!res){
31
- ecode = tcrdbecode(db);
32
- rb_raise(eTokyoTyrantError, "put error: %s", tcrdberrmsg(ecode));
33
- }
28
+ if(!res) mTokyoTyrant_exception(vself);
34
29
 
35
- return Qtrue;
30
+ return Qtrue;
36
31
  }
37
32
 
38
33
  static VALUE cDB_put(VALUE vself, VALUE vkey, VALUE vstr){
@@ -41,9 +36,8 @@ static VALUE cDB_put(VALUE vself, VALUE vkey, VALUE vstr){
41
36
 
42
37
  static VALUE cDB_mput(VALUE vself, VALUE vhash){
43
38
  VALUE vary;
44
- TCRDB *db;
45
39
  TCLIST *list, *args;
46
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
40
+ TCRDB *db = mTokyoTyrant_getdb(vself);
47
41
 
48
42
  args = vhashtolist(vhash);
49
43
  list = tcrdbmisc(db, "putlist", 0, args);
@@ -66,17 +60,15 @@ static VALUE cDB_putnr(VALUE vself, VALUE vkey, VALUE vstr){
66
60
  }
67
61
 
68
62
  static VALUE cDB_putshl(VALUE vself, VALUE vkey, VALUE vstr, VALUE vwidth){
69
- int ecode;
70
- TCRDB *db;
71
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
63
+ bool res;
64
+ TCRDB *db = mTokyoTyrant_getdb(vself);
72
65
 
73
66
  vkey = StringValueEx(vkey);
74
67
  vstr = StringValueEx(vstr);
75
68
 
76
- if(!tcrdbputshl2(db, RSTRING_PTR(vkey), RSTRING_PTR(vstr), FIXNUM_P(vwidth))){
77
- ecode = tcrdbecode(db);
78
- rb_raise(eTokyoTyrantError, "put error: %s", tcrdberrmsg(ecode));
79
- }
69
+ res = tcrdbputshl(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vstr), RSTRING_LEN(vstr), FIXNUM_P(vwidth));
70
+
71
+ if(!res) mTokyoTyrant_exception(vself);
80
72
 
81
73
  return Qtrue;
82
74
  }
@@ -85,16 +77,13 @@ static VALUE cDB_get(VALUE vself, VALUE vkey){
85
77
  VALUE vval;
86
78
  char *buf;
87
79
  int bsiz, ecode;
88
- TCRDB *db;
89
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
80
+ TCRDB *db = mTokyoTyrant_getdb(vself);
90
81
 
91
82
  // this is ugly
92
83
  vkey = StringValueEx(vkey);
93
84
  if(!(buf = tcrdbget(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), &bsiz))){
94
85
  if ((ecode = tcrdbecode(db))) {
95
- if (ecode != TTENOREC) {
96
- rb_raise(eTokyoTyrantError, "get error: %s", tcrdberrmsg(ecode));
97
- }
86
+ if (ecode != TTENOREC) mTokyoTyrant_exception(vself);
98
87
  }
99
88
  return Qnil;
100
89
  } else {
@@ -107,9 +96,8 @@ static VALUE cDB_get(VALUE vself, VALUE vkey){
107
96
 
108
97
  static VALUE cDB_mget(int argc, VALUE *argv, VALUE vself){
109
98
  VALUE vkeys, vhash, vvalue;
110
- TCRDB *db;
111
99
  TCMAP *recs;
112
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
100
+ TCRDB *db = mTokyoTyrant_getdb(vself);
113
101
  rb_scan_args(argc, argv, "*", &vkeys);
114
102
 
115
103
  // I really hope there is a better way to do this
@@ -122,6 +110,7 @@ static VALUE cDB_mget(int argc, VALUE *argv, VALUE vself){
122
110
  case T_ARRAY:
123
111
  vkeys = vvalue;
124
112
  break;
113
+ case T_STRUCT: // range is not a T_STRUCT instead of a T_OBJECT in ruby1.9?
125
114
  case T_OBJECT:
126
115
  vkeys = rb_convert_type(vvalue, T_ARRAY, "Array", "to_a");
127
116
  break;
@@ -138,21 +127,19 @@ static VALUE cDB_mget(int argc, VALUE *argv, VALUE vself){
138
127
  }
139
128
 
140
129
  static VALUE cDB_vsiz(VALUE vself, VALUE vkey){
141
- TCRDB *db;
142
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
130
+ TCRDB *db = mTokyoTyrant_getdb(vself);
143
131
 
144
132
  vkey = StringValueEx(vkey);
145
- return INT2NUM(tcrdbvsiz2(db, RSTRING_PTR(vkey)));
133
+ return INT2NUM(tcrdbvsiz(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey)));
146
134
  }
147
135
 
148
136
  static VALUE cDB_fetch(int argc, VALUE *argv, VALUE vself){
149
137
  VALUE vkey, vdef, vval;
150
- TCRDB *db;
151
138
  char *vbuf;
152
139
  int vsiz;
153
140
  rb_scan_args(argc, argv, "11", &vkey, &vdef);
141
+ TCRDB *db = mTokyoTyrant_getdb(vself);
154
142
  vkey = StringValueEx(vkey);
155
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
156
143
  if((vbuf = tcrdbget(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), &vsiz)) != NULL){
157
144
  vval = StringRaw(vbuf, vsiz);
158
145
  tcfree(vbuf);
@@ -164,9 +151,8 @@ static VALUE cDB_fetch(int argc, VALUE *argv, VALUE vself){
164
151
 
165
152
  static VALUE cDB_each(VALUE vself){
166
153
  VALUE vrv;
167
- TCRDB *db;
168
154
  if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
169
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
155
+ TCRDB *db = mTokyoTyrant_getdb(vself);
170
156
  vrv = Qnil;
171
157
  tcrdbiterinit(db);
172
158
  int ksiz;
@@ -183,9 +169,8 @@ static VALUE cDB_each(VALUE vself){
183
169
 
184
170
  static VALUE cDB_each_value(VALUE vself){
185
171
  VALUE vrv;
186
- TCRDB *db;
187
172
  if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
188
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
173
+ TCRDB *db = mTokyoTyrant_getdb(vself);
189
174
  vrv = Qnil;
190
175
  tcrdbiterinit(db);
191
176
  int ksiz;
@@ -202,8 +187,7 @@ static VALUE cDB_each_value(VALUE vself){
202
187
 
203
188
  static VALUE cDB_values(VALUE vself){
204
189
  VALUE vary;
205
- TCRDB *db;
206
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
190
+ TCRDB *db = mTokyoTyrant_getdb(vself);
207
191
  vary = rb_ary_new2(tcrdbrnum(db));
208
192
  tcrdbiterinit(db);
209
193
  int ksiz;
@@ -225,7 +209,7 @@ void init_db(){
225
209
  rb_define_alias(cDB, "[]=", "put");
226
210
  rb_define_method(cDB, "putkeep", cDB_putkeep, 2);
227
211
  rb_define_method(cDB, "putcat", cDB_putcat, 2);
228
- rb_define_method(cDB, "putshl", cDB_putshl, 2);
212
+ rb_define_method(cDB, "putshl", cDB_putshl, 3);
229
213
  rb_define_method(cDB, "putnr", cDB_putnr, 2);
230
214
  rb_define_method(cDB, "get", cDB_get, 1);
231
215
  rb_define_alias(cDB, "[]", "get");
@@ -1,17 +1,30 @@
1
1
  #include <tokyo_tyrant_db.h>
2
2
 
3
+ extern TCRDB *mTokyoTyrant_getdb(VALUE vself){
4
+ TCRDB *db;
5
+ Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
6
+ return db;
7
+ }
8
+
9
+ extern void mTokyoTyrant_exception(VALUE vself){
10
+ int ecode;
11
+ TCRDB *db = mTokyoTyrant_getdb(vself);
12
+
13
+ ecode = tcrdbecode(db);
14
+ rb_raise(eTokyoTyrantError, tcrdberrmsg(ecode));
15
+ }
16
+
3
17
  static void mTokyoTyrant_free(TCRDB *db){
4
18
  tcrdbdel(db);
5
19
  }
6
20
 
7
21
  static VALUE mTokyoTyrant_server(VALUE vself){
8
- return rb_iv_get(vself, "@server");;
22
+ return rb_iv_get(vself, "@server");
9
23
  }
10
24
 
11
25
  static VALUE mTokyoTyrant_close(VALUE vself){
12
26
  int ecode;
13
- TCRDB *db;
14
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
27
+ TCRDB *db = mTokyoTyrant_getdb(vself);
15
28
 
16
29
  if(!tcrdbclose(db)){
17
30
  ecode = tcrdbecode(db);
@@ -54,8 +67,7 @@ static VALUE mTokyoTyrant_errmsg(int argc, VALUE *argv, VALUE vself){
54
67
  VALUE vecode;
55
68
  const char *msg;
56
69
  int ecode;
57
- TCRDB *db;
58
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
70
+ TCRDB *db = mTokyoTyrant_getdb(vself);
59
71
  rb_scan_args(argc, argv, "01", &vecode);
60
72
 
61
73
  ecode = (vecode == Qnil) ? tcrdbecode(db) : NUM2INT(vecode);
@@ -64,26 +76,23 @@ static VALUE mTokyoTyrant_errmsg(int argc, VALUE *argv, VALUE vself){
64
76
  }
65
77
 
66
78
  static VALUE mTokyoTyrant_ecode(VALUE vself){
67
- TCRDB *db;
68
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
79
+ TCRDB *db = mTokyoTyrant_getdb(vself);
69
80
 
70
81
  return INT2NUM(tcrdbecode(db));
71
82
  }
72
83
 
73
84
  static VALUE mTokyoTyrant_out(VALUE vself, VALUE vkey){
74
- TCRDB *db;
75
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
85
+ TCRDB *db = mTokyoTyrant_getdb(vself);
76
86
 
77
87
  vkey = StringValueEx(vkey);
78
- return tcrdbout2(db, RSTRING_PTR(vkey)) ? Qtrue : Qfalse;
88
+ return tcrdbout(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey)) ? Qtrue : Qfalse;
79
89
  }
80
90
 
81
91
  // TODO: merge out and mout?
82
92
  static VALUE mTokyoTyrant_outlist(int argc, VALUE *argv, VALUE vself){
83
93
  VALUE vkeys, vary, vvalue;
84
- TCRDB *db;
85
94
  TCLIST *list, *result;
86
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
95
+ TCRDB *db = mTokyoTyrant_getdb(vself);
87
96
  rb_scan_args(argc, argv, "*", &vkeys);
88
97
 
89
98
  // I really hope there is a better way to do this
@@ -112,16 +121,14 @@ static VALUE mTokyoTyrant_outlist(int argc, VALUE *argv, VALUE vself){
112
121
  }
113
122
 
114
123
  static VALUE mTokyoTyrant_check(VALUE vself, VALUE vkey){
115
- TCRDB *db;
116
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
124
+ TCRDB *db = mTokyoTyrant_getdb(vself);
117
125
 
118
126
  vkey = StringValueEx(vkey);
119
- return tcrdbvsiz2(db, RSTRING_PTR(vkey)) >= 0 ? Qtrue : Qfalse;
127
+ return tcrdbvsiz(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey)) >= 0 ? Qtrue : Qfalse;
120
128
  }
121
129
 
122
130
  static VALUE mTokyoTyrant_iterinit(VALUE vself){
123
- TCRDB *db;
124
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
131
+ TCRDB *db = mTokyoTyrant_getdb(vself);
125
132
 
126
133
  return tcrdbiterinit(db) ? Qtrue : Qfalse;
127
134
  }
@@ -129,8 +136,7 @@ static VALUE mTokyoTyrant_iterinit(VALUE vself){
129
136
  static VALUE mTokyoTyrant_iternext(VALUE vself){
130
137
  VALUE vval;
131
138
  char *vbuf;
132
- TCRDB *db;
133
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
139
+ TCRDB *db = mTokyoTyrant_getdb(vself);
134
140
 
135
141
  if(!(vbuf = tcrdbiternext2(db))) return Qnil;
136
142
  vval = rb_str_new2(vbuf);
@@ -143,8 +149,7 @@ static VALUE mTokyoTyrant_fwmkeys(int argc, VALUE *argv, VALUE vself){
143
149
  VALUE vprefix, vmax, vary;
144
150
  TCLIST *keys;
145
151
  int max;
146
- TCRDB *db;
147
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
152
+ TCRDB *db = mTokyoTyrant_getdb(vself);
148
153
  rb_scan_args(argc, argv, "11", &vprefix, &vmax);
149
154
 
150
155
  vprefix = StringValueEx(vprefix);
@@ -159,8 +164,7 @@ static VALUE mTokyoTyrant_delete_keys_with_prefix(int argc, VALUE *argv, VALUE v
159
164
  VALUE vprefix, vmax;
160
165
  TCLIST *keys;
161
166
  int max;
162
- TCRDB *db;
163
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
167
+ TCRDB *db = mTokyoTyrant_getdb(vself);
164
168
  rb_scan_args(argc, argv, "11", &vprefix, &vmax);
165
169
 
166
170
  vprefix = StringValueEx(vprefix);
@@ -174,9 +178,8 @@ static VALUE mTokyoTyrant_delete_keys_with_prefix(int argc, VALUE *argv, VALUE v
174
178
  static VALUE mTokyoTyrant_keys(VALUE vself){
175
179
  /*
176
180
  VALUE vary;
177
- TCRDB *db;
178
181
  char *kxstr;
179
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
182
+ TCRDB *db = mTokyoTyrant_getdb(vself);
180
183
  vary = rb_ary_new2(tcrdbrnum(db));
181
184
  tcrdbiterinit(db);
182
185
  while((kxstr = tcrdbiternext2(db)) != NULL){
@@ -188,9 +191,8 @@ static VALUE mTokyoTyrant_keys(VALUE vself){
188
191
  // Using forward matching keys with an empty string is 100x faster than iternext+get
189
192
  VALUE vary;
190
193
  TCLIST *keys;
191
- TCRDB *db;
192
194
  char *prefix;
193
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
195
+ TCRDB *db = mTokyoTyrant_getdb(vself);
194
196
  prefix = "";
195
197
  keys = tcrdbfwmkeys2(db, prefix, -1);
196
198
  vary = listtovary(keys);
@@ -198,51 +200,77 @@ static VALUE mTokyoTyrant_keys(VALUE vself){
198
200
  return vary;
199
201
  }
200
202
 
201
- static VALUE mTokyoTyrant_add_int(VALUE vself, VALUE vkey, VALUE vnum){
202
- int num;
203
- TCRDB *db;
204
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
203
+ static VALUE mTokyoTyrant_addint(VALUE vself, VALUE vkey, int inum){
204
+ TCRDB *db = mTokyoTyrant_getdb(vself);
205
+ vkey = StringValueEx(vkey);
206
+
207
+ inum = tcrdbaddint(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), inum);
208
+ return inum == INT_MIN ? Qnil : INT2NUM(inum);
209
+ }
210
+
211
+ static VALUE mTokyoTyrant_add_int(int argc, VALUE *argv, VALUE vself){
212
+ VALUE vkey, vnum;
213
+ int inum = 1;
214
+
215
+ rb_scan_args(argc, argv, "11", &vkey, &vnum);
205
216
  vkey = StringValueEx(vkey);
217
+ if(NIL_P(vnum)) vnum = INT2NUM(inum);
206
218
 
207
- num = tcrdbaddint(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), NUM2INT(vnum));
208
- return num == INT_MIN ? Qnil : INT2NUM(num);
219
+ return mTokyoTyrant_addint(vself, vkey, NUM2INT(vnum));
209
220
  }
210
221
 
211
222
  static VALUE mTokyoTyrant_get_int(VALUE vself, VALUE vkey){
212
- return mTokyoTyrant_add_int(vself, vkey, INT2NUM(0));
223
+ return mTokyoTyrant_addint(vself, vkey, 0);
213
224
  }
214
225
 
215
- static VALUE mTokyoTyrant_add_double(VALUE vself, VALUE vkey, VALUE vnum){
216
- double num;
217
- TCRDB *db;
218
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
226
+ static VALUE mTokyoTyrant_adddouble(VALUE vself, VALUE vkey, double dnum){
227
+ TCRDB *db = mTokyoTyrant_getdb(vself);
228
+
229
+ vkey = StringValueEx(vkey);
230
+ dnum = tcrdbadddouble(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), dnum);
231
+ return isnan(dnum) ? Qnil : rb_float_new(dnum);
232
+ }
219
233
 
234
+ static VALUE mTokyoTyrant_add_double(int argc, VALUE *argv, VALUE vself){
235
+ VALUE vkey, vnum;
236
+ double dnum = 1.0;
237
+
238
+ rb_scan_args(argc, argv, "11", &vkey, &vnum);
220
239
  vkey = StringValueEx(vkey);
221
- num = tcrdbadddouble(db, RSTRING_PTR(vkey), RSTRING_LEN(vkey), NUM2DBL(vnum));
222
- return isnan(num) ? Qnil : rb_float_new(num);
240
+ if(NIL_P(vnum)) vnum = rb_float_new(dnum);
241
+
242
+ return mTokyoTyrant_adddouble(vself, vkey, NUM2DBL(vnum));
223
243
  }
224
244
 
225
245
  static VALUE mTokyoTyrant_get_double(VALUE vself, VALUE vkey){
226
- return mTokyoTyrant_add_double(vself, vkey, INT2NUM(0));
246
+ return mTokyoTyrant_adddouble(vself, vkey, 0.0);
227
247
  }
228
248
 
229
249
  static VALUE mTokyoTyrant_sync(VALUE vself){
230
- TCRDB *db;
231
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
250
+ TCRDB *db = mTokyoTyrant_getdb(vself);
232
251
 
233
252
  return tcrdbsync(db) ? Qtrue : Qfalse;
234
253
  }
235
254
 
255
+ static VALUE mTokyoTyrant_optimize(int argc, VALUE *argv, VALUE vself){
256
+ VALUE vparams;
257
+ const char *params = NULL;
258
+ TCRDB *db = mTokyoTyrant_getdb(vself);
259
+ rb_scan_args(argc, argv, "01", &vparams);
260
+ if(NIL_P(vparams)) vparams = Qnil;
261
+ if(vparams != Qnil) params = RSTRING_PTR(vparams);
262
+
263
+ return tcrdboptimize(db, params) ? Qtrue : Qfalse;
264
+ }
265
+
236
266
  static VALUE mTokyoTyrant_vanish(VALUE vself){
237
- TCRDB *db;
238
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
267
+ TCRDB *db = mTokyoTyrant_getdb(vself);
239
268
 
240
269
  return tcrdbvanish(db) ? Qtrue : Qfalse;
241
270
  }
242
271
 
243
272
  static VALUE mTokyoTyrant_copy(VALUE vself, VALUE path){
244
- TCRDB *db;
245
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
273
+ TCRDB *db = mTokyoTyrant_getdb(vself);
246
274
 
247
275
  Check_Type(path, T_STRING);
248
276
  return tcrdbcopy(db, RSTRING_PTR(path)) ? Qtrue : Qfalse;
@@ -251,8 +279,7 @@ static VALUE mTokyoTyrant_copy(VALUE vself, VALUE path){
251
279
  static VALUE mTokyoTyrant_restore(VALUE vself, VALUE vpath, VALUE vts, VALUE vopts){
252
280
  uint64_t ts;
253
281
  int opts;
254
- TCRDB *db;
255
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
282
+ TCRDB *db = mTokyoTyrant_getdb(vself);
256
283
 
257
284
  Check_Type(vpath, T_STRING);
258
285
  ts = (uint64_t) FIX2INT(vts);
@@ -263,8 +290,7 @@ static VALUE mTokyoTyrant_restore(VALUE vself, VALUE vpath, VALUE vts, VALUE vop
263
290
  static VALUE mTokyoTyrant_setmst(VALUE vself, VALUE vhost, VALUE vport, VALUE vts, VALUE vopts){
264
291
  uint64_t ts;
265
292
  int opts;
266
- TCRDB *db;
267
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
293
+ TCRDB *db = mTokyoTyrant_getdb(vself);
268
294
 
269
295
  ts = (uint64_t) FIX2INT(vts);
270
296
  opts = FIX2INT(vopts);
@@ -272,39 +298,33 @@ static VALUE mTokyoTyrant_setmst(VALUE vself, VALUE vhost, VALUE vport, VALUE vt
272
298
  }
273
299
 
274
300
  static VALUE mTokyoTyrant_rnum(VALUE vself){
275
- TCRDB *db;
276
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
301
+ TCRDB *db = mTokyoTyrant_getdb(vself);
277
302
 
278
303
  return LL2NUM(tcrdbrnum(db));
279
304
  }
280
305
 
281
306
  static VALUE mTokyoTyrant_empty(VALUE vself){
282
- TCRDB *db;
283
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
307
+ TCRDB *db = mTokyoTyrant_getdb(vself);
284
308
 
285
309
  return tcrdbrnum(db) < 1 ? Qtrue : Qfalse;
286
310
  }
287
311
 
288
312
  static VALUE mTokyoTyrant_size(VALUE vself){
289
- TCRDB *db;
290
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
313
+ TCRDB *db = mTokyoTyrant_getdb(vself);
291
314
 
292
315
  return LL2NUM(tcrdbsize(db));
293
316
  }
294
317
 
295
318
  static VALUE mTokyoTyrant_stat(VALUE vself){
296
- TCRDB *db;
297
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
319
+ TCRDB *db = mTokyoTyrant_getdb(vself);
298
320
 
299
321
  return rb_str_new2(tcrdbstat(db));
300
322
  }
301
323
 
302
324
  static VALUE mTokyoTyrant_misc(int argc, VALUE *argv, VALUE vself){
303
- VALUE vname, vopts, vargs;
304
- TCRDB *db;
325
+ VALUE vname, vopts, vargs, vary;
305
326
  TCLIST *list, *args;
306
- VALUE vary;
307
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
327
+ TCRDB *db = mTokyoTyrant_getdb(vself);
308
328
  rb_scan_args(argc, argv, "13", &vname, &vopts, &vargs);
309
329
 
310
330
  args = varytolist(vargs);
@@ -316,12 +336,26 @@ static VALUE mTokyoTyrant_misc(int argc, VALUE *argv, VALUE vself){
316
336
  return vary;
317
337
  }
318
338
 
339
+ static VALUE mTokyoTyrant_ext(VALUE vself, VALUE vext, VALUE vkey, VALUE vvalue){
340
+ int vsiz;
341
+ char *vbuf;
342
+ TCRDB *db = mTokyoTyrant_getdb(vself);
343
+ vext = StringValueEx(vext);
344
+ vkey = StringValueEx(vkey);
345
+ vvalue = StringValueEx(vvalue);
346
+
347
+ if(!(vbuf = tcrdbext(db, RSTRING_PTR(vext), 0, RSTRING_PTR(vkey), RSTRING_LEN(vkey), RSTRING_PTR(vvalue), RSTRING_LEN(vvalue), &vsiz))){
348
+ return Qnil;
349
+ } else {
350
+ return rb_str_new(vbuf, vsiz);
351
+ }
352
+ }
353
+
319
354
  static VALUE mTokyoTyrant_each_key(VALUE vself){
320
355
  VALUE vrv;
321
- TCRDB *db;
322
356
  char *kxstr;
323
357
  if(rb_block_given_p() != Qtrue) rb_raise(rb_eArgError, "no block given");
324
- Data_Get_Struct(rb_iv_get(vself, RDBVNDATA), TCRDB, db);
358
+ TCRDB *db = mTokyoTyrant_getdb(vself);
325
359
  vrv = Qnil;
326
360
  tcrdbiterinit(db);
327
361
  while((kxstr = tcrdbiternext2(db)) != NULL){
@@ -367,11 +401,15 @@ void init_mod(){
367
401
  rb_define_method(mTokyoTyrant, "delete_keys_with_prefix", mTokyoTyrant_delete_keys_with_prefix, -1);// Rufus Compat
368
402
  rb_define_alias(mTokyoTyrant, "dfwmkeys", "delete_keys_with_prefix");
369
403
  rb_define_method(mTokyoTyrant, "keys", mTokyoTyrant_keys, 0);
370
- rb_define_method(mTokyoTyrant, "add_int", mTokyoTyrant_add_int, 2);
404
+ rb_define_method(mTokyoTyrant, "add_int", mTokyoTyrant_add_int, -1);
405
+ rb_define_alias(mTokyoTyrant, "addint", "add_int");
406
+ rb_define_alias(mTokyoTyrant, "increment", "add_int");
371
407
  rb_define_method(mTokyoTyrant, "get_int", mTokyoTyrant_get_int, 1);
372
- rb_define_method(mTokyoTyrant, "add_double", mTokyoTyrant_add_double, 2);
408
+ rb_define_method(mTokyoTyrant, "add_double", mTokyoTyrant_add_double, -1);
409
+ rb_define_alias(mTokyoTyrant, "adddouble", "add_double");
373
410
  rb_define_method(mTokyoTyrant, "get_double", mTokyoTyrant_get_double, 1);
374
411
  rb_define_method(mTokyoTyrant, "sync", mTokyoTyrant_sync, 0);
412
+ rb_define_method(mTokyoTyrant, "optimize", mTokyoTyrant_optimize, -1);
375
413
  rb_define_method(mTokyoTyrant, "vanish", mTokyoTyrant_vanish, 0);
376
414
  rb_define_alias(mTokyoTyrant, "clear", "vanish");
377
415
  rb_define_method(mTokyoTyrant, "copy", mTokyoTyrant_copy, 1);
@@ -385,5 +423,7 @@ void init_mod(){
385
423
  rb_define_alias(mTokyoTyrant, "length", "size");
386
424
  rb_define_method(mTokyoTyrant, "stat", mTokyoTyrant_stat, 0);
387
425
  rb_define_method(mTokyoTyrant, "misc", mTokyoTyrant_misc, -1);
426
+ rb_define_method(mTokyoTyrant, "ext", mTokyoTyrant_ext, 3);
427
+ rb_define_alias(mTokyoTyrant, "run", "ext");
388
428
  rb_define_method(mTokyoTyrant, "each_key", mTokyoTyrant_each_key, 0);
389
429
  }