actsasflinn-ruby-tokyotyrant 0.1.8 → 0.1.9

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.
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
  }