rufus-tokyo 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +11 -0
- data/CREDITS.txt +5 -3
- data/README.txt +1 -0
- data/lib/rufus/tokyo.rb +7 -5
- data/lib/rufus/tokyo/cabinet/abstract.rb +144 -22
- data/lib/rufus/tokyo/cabinet/lib.rb +8 -0
- data/lib/rufus/tokyo/cabinet/table.rb +178 -65
- data/lib/rufus/tokyo/cabinet/util.rb +12 -1
- data/lib/rufus/tokyo/tyrant/lib.rb +4 -0
- metadata +2 -2
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
= rufus-tokyo CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-tokyo - 0.1.7 released 2009/02/19
|
6
|
+
|
7
|
+
- todo : Rufus::Tokyo::Cabinet.new('filename', :type => :hash) now OK (Zev)
|
8
|
+
- todo : more documentation for Rufus::Tokyo::Cabinet#new
|
9
|
+
- added : Rufus::Tokyo::Cabinet has a open method that takes a block like
|
10
|
+
File.open (Zev)
|
11
|
+
- todo : aligned Rufus::Tokyo::Table#new on ::Cabinet#new
|
12
|
+
- todo : added opts (:prefix, :limit, :native) to Rufus::Tokyo::Cabinet#keys,
|
13
|
+
Rufus::Tokyo::Table#keys and the corresponding Tyrant classes
|
14
|
+
|
15
|
+
|
5
16
|
== rufus-tokyo - 0.1.6 released 2009/02/16
|
6
17
|
|
7
18
|
- todo : Tyrant and TyrantTable now complain when used in lieu of each other
|
data/CREDITS.txt
CHANGED
@@ -4,13 +4,15 @@
|
|
4
4
|
|
5
5
|
== authors
|
6
6
|
|
7
|
-
John Mettraux
|
8
|
-
Justin Reagor
|
7
|
+
John Mettraux http://jmettraux.wordpress.com
|
8
|
+
Justin Reagor http://blog.kineticweb.com/
|
9
|
+
Zev Blut http://www.iknow.co.jp/users/zev
|
9
10
|
|
10
11
|
|
11
12
|
== finally
|
12
13
|
|
13
|
-
many thanks to the author of Tokyo Cabinet (Mikio Hirabayashi) and
|
14
|
+
many thanks to the author of Tokyo Cabinet (Mikio Hirabayashi) and
|
15
|
+
the authors of ruby-ffi
|
14
16
|
|
15
17
|
http://tokyocabinet.sourceforge.net
|
16
18
|
http://kenai.com/projects/ruby-ffi
|
data/README.txt
CHANGED
@@ -240,6 +240,7 @@ many thanks to the author of Tokyo Cabinet, Mikio Hirabayashi, and to the author
|
|
240
240
|
|
241
241
|
John Mettraux, jmettraux@gmail.com, http://jmettraux.wordpress.com
|
242
242
|
Justin Reagor, http://blog.kineticweb.com/
|
243
|
+
Zev Blut, http://www.iknow.co.jp/users/zev
|
243
244
|
|
244
245
|
|
245
246
|
== the rest of Rufus
|
data/lib/rufus/tokyo.rb
CHANGED
@@ -22,13 +22,19 @@
|
|
22
22
|
#++
|
23
23
|
#
|
24
24
|
|
25
|
+
#
|
26
|
+
# "made in Japan"
|
27
|
+
#
|
28
|
+
# jmettraux@gmail.com
|
29
|
+
#
|
30
|
+
|
25
31
|
require 'ffi' # sudo gem install ffi
|
26
32
|
|
27
33
|
|
28
34
|
module Rufus
|
29
35
|
module Tokyo
|
30
36
|
|
31
|
-
VERSION = '0.1.
|
37
|
+
VERSION = '0.1.7'
|
32
38
|
|
33
39
|
#
|
34
40
|
# A common error class
|
@@ -40,7 +46,3 @@ end
|
|
40
46
|
|
41
47
|
require 'rufus/tokyo/cabinet'
|
42
48
|
|
43
|
-
# TODO : do not include me
|
44
|
-
#require 'rufus/tokyo/tyrant'
|
45
|
-
#require 'rufus/tokyo/dystopia'
|
46
|
-
|
@@ -74,48 +74,140 @@ module Rufus
|
|
74
74
|
# 'casket.tch' with a bucket number of 100000 and the 'large' and
|
75
75
|
# 'deflate' options (opts) turned on.
|
76
76
|
#
|
77
|
-
#
|
77
|
+
# Note that there is an #open method similar to File#open for openening
|
78
|
+
# a db and closing it when it's no longer needed :
|
78
79
|
#
|
79
|
-
#
|
80
|
-
#
|
80
|
+
# Rufus::Tokyo::Cabinet.new('data.tch') do |db|
|
81
|
+
# db['key'] = value
|
82
|
+
# end
|
81
83
|
#
|
82
|
-
# ==
|
84
|
+
# == database name
|
83
85
|
#
|
84
|
-
#
|
85
|
-
# options, thus
|
86
|
+
# From http://tokyocabinet.sourceforge.net/spex-en.html#tcadbapi :
|
86
87
|
#
|
87
|
-
#
|
88
|
+
# 'If it is "*", the database will be an on-memory hash database. If it is
|
89
|
+
# "+", the database will be an on-memory tree database. If its suffix is
|
90
|
+
# ".tch", the database will be a hash database. If its suffix is ".tcb",
|
91
|
+
# the database will be a B+ tree database. If its suffix is ".tcf", the
|
92
|
+
# database will be a fixed-length database. If its suffix is ".tct", the
|
93
|
+
# database will be a table database.'
|
94
|
+
#
|
95
|
+
# You're supposed to give a path to the database file you want to use and
|
96
|
+
# Cabinet expects you to give the proper prefix.
|
97
|
+
#
|
98
|
+
# db = Rufus::Tokyo::Cabinet.new('data.tch') # hash database
|
99
|
+
# db = Rufus::Tokyo::Cabinet.new('data.tcb') # B+ tree db
|
100
|
+
# db = Rufus::Tokyo::Cabinet.new('data.tcf') # fixed-length db
|
101
|
+
#
|
102
|
+
# will result with the same file names :
|
103
|
+
#
|
104
|
+
# db = Rufus::Tokyo::Cabinet.new('data', :type => :hash) # hash database
|
105
|
+
# db = Rufus::Tokyo::Cabinet.new('data', :type => :btree) # B+ tree db
|
106
|
+
# db = Rufus::Tokyo::Cabinet.new('data', :type => :fixed) # fixed-length db
|
107
|
+
#
|
108
|
+
# You can open an in-memory hash and an in-memory B+ tree with :
|
109
|
+
#
|
110
|
+
# h = Rufus::Tokyo::Cabinet.new(:mem_hash) # or
|
111
|
+
# h = Rufus::Tokyo::Cabinet.new('*')
|
112
|
+
#
|
113
|
+
# t = Rufus::Tokyo::Cabinet.new(:mem_tree) # or
|
114
|
+
# t = Rufus::Tokyo::Cabinet.new('+')
|
115
|
+
#
|
116
|
+
# == parameters
|
88
117
|
#
|
89
|
-
#
|
118
|
+
# There are two ways to pass parameters at the opening of a db :
|
119
|
+
#
|
120
|
+
# db = Rufus::Tokyo::Cabinet.new('data.tch#opts=ld#mode=w') # or
|
121
|
+
# db = Rufus::Tokyo::Cabinet.new('data.tch', :opts => 'ld', :mode => 'w')
|
122
|
+
#
|
123
|
+
# most verbose :
|
90
124
|
#
|
91
125
|
# db = Rufus::Tokyo::Cabinet.new(
|
92
|
-
# '
|
126
|
+
# 'data', :type => :hash, :opts => 'ld', :mode => 'w')
|
127
|
+
#
|
128
|
+
# === mode
|
129
|
+
#
|
130
|
+
# * :mode a set of chars ('r'ead, 'w'rite, 'c'reate, 't'runcate,
|
131
|
+
# 'e' non locking, 'f' non blocking lock), default is 'wc'
|
132
|
+
#
|
133
|
+
# === other parameters
|
134
|
+
#
|
135
|
+
# 'On-memory hash database supports "bnum", "capnum", and "capsiz".
|
136
|
+
# On-memory tree database supports "capnum" and "capsiz".
|
137
|
+
# Hash database supports "mode", "bnum", "apow", "fpow", "opts",
|
138
|
+
# "rcnum", and "xmsiz".
|
139
|
+
# B+ tree database supports "mode", "lmemb", "nmemb", "bnum", "apow",
|
140
|
+
# "fpow", "opts", "lcnum", "ncnum", and "xmsiz".
|
141
|
+
# Fixed-length database supports "mode", "width", and "limsiz"'
|
142
|
+
#
|
143
|
+
# * :opts a set of chars ('l'arge, 'd'eflate, 'b'zip2, 't'cbs)
|
144
|
+
# (usually empty or something like 'ld' or 'lb')
|
145
|
+
#
|
146
|
+
# * :bnum number of elements of the bucket array
|
147
|
+
# * :apow size of record alignment by power of 2 (defaults to 4)
|
148
|
+
# * :fpow maximum number of elements of the free block pool by
|
149
|
+
# power of 2 (defaults to 10)
|
150
|
+
# * :mutex when set to true, makes sure only 1 thread at a time
|
151
|
+
# accesses the table (well, Ruby, global thread lock, ...)
|
93
152
|
#
|
94
|
-
#
|
153
|
+
# * :rcnum specifies the maximum number of records to be cached.
|
154
|
+
# If it is not more than 0, the record cache is disabled.
|
155
|
+
# It is disabled by default.
|
156
|
+
# * :lcnum specifies the maximum number of leaf nodes to be cached.
|
157
|
+
# If it is not more than 0, the default value is specified.
|
158
|
+
# The default value is 2048.
|
159
|
+
# * :ncnum specifies the maximum number of non-leaf nodes to be
|
160
|
+
# cached. If it is not more than 0, the default value is
|
161
|
+
# specified. The default value is 512.
|
95
162
|
#
|
96
|
-
#
|
163
|
+
# * :xmsiz specifies the size of the extra mapped memory. If it is
|
164
|
+
# not more than 0, the extra mapped memory is disabled.
|
165
|
+
# The default size is 67108864.
|
97
166
|
#
|
98
|
-
#
|
167
|
+
# * :capnum specifies the capacity number of records.
|
168
|
+
# * :capsiz specifies the capacity size of using memory.
|
99
169
|
#
|
100
|
-
#
|
101
|
-
#
|
170
|
+
#
|
171
|
+
# = NOTE :
|
172
|
+
#
|
173
|
+
# On reopening a file, Cabinet will tend to stick to the parameters as
|
174
|
+
# set when the file was opened. To change that, have a look at the
|
175
|
+
# man pages of the various command line tools coming with Tokyo Cabinet.
|
102
176
|
#
|
103
177
|
def initialize (name, params={})
|
104
178
|
|
105
179
|
@db = lib.tcadbnew
|
106
180
|
|
107
|
-
name = '*' if name == :
|
108
|
-
name = '+' if name == :
|
181
|
+
name = '*' if name == :mem_hash # in memory hash database
|
182
|
+
name = '+' if name == :mem_tree # in memory B+ tree database
|
183
|
+
|
184
|
+
if type = params.delete(:type)
|
185
|
+
name += { :hash => '.tch', :btree => '.tcb', :fixed => '.tcf' }[type]
|
186
|
+
end
|
109
187
|
|
110
188
|
name = name + params.collect { |k, v| "##{k}=#{v}" }.join('')
|
111
189
|
|
112
190
|
(lib.tcadbopen(@db, name) == 1) ||
|
113
|
-
raise("failed to open/create db '#{name}'")
|
191
|
+
raise("failed to open/create db '#{name}' #{params.inspect}")
|
114
192
|
|
115
193
|
self.default = params[:default]
|
116
194
|
@default_proc ||= params[:default_proc]
|
117
195
|
end
|
118
196
|
|
197
|
+
# Same args as initialize, but can take a block form that will
|
198
|
+
# close the db when done. Similar to File.open
|
199
|
+
def self.open (name, params={})
|
200
|
+
db = self.new(name, params)
|
201
|
+
if block_given?
|
202
|
+
yield db
|
203
|
+
nil
|
204
|
+
else
|
205
|
+
db
|
206
|
+
end
|
207
|
+
ensure
|
208
|
+
db.close if block_given? && db
|
209
|
+
end
|
210
|
+
|
119
211
|
#
|
120
212
|
# Returns a new in-memory hash. Accepts the same optional params hash
|
121
213
|
# as new().
|
@@ -229,11 +321,41 @@ module Rufus
|
|
229
321
|
#
|
230
322
|
# Returns an array with all the keys in the databse
|
231
323
|
#
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
324
|
+
# With no options given, this method will return all the keys (strings)
|
325
|
+
# in a Ruby array.
|
326
|
+
#
|
327
|
+
# :prefix --> returns only the keys who match a given string prefix
|
328
|
+
#
|
329
|
+
# :limit --> returns a limited number of keys
|
330
|
+
#
|
331
|
+
# :native --> returns an instance of Rufus::Tokyo::List instead of
|
332
|
+
# a Ruby Hash, you have to call #free on that List when done with it !
|
333
|
+
# Else you're exposing yourself to a memory leak.
|
334
|
+
#
|
335
|
+
def keys (options={})
|
336
|
+
|
337
|
+
if pref = options[:prefix]
|
338
|
+
|
339
|
+
l = lib.abs_fwmkeys2(@db, pref, options[:limit] || -1)
|
340
|
+
l = Rufus::Tokyo::List.new(l)
|
341
|
+
options[:native] ? l : l.release
|
342
|
+
|
343
|
+
else
|
344
|
+
|
345
|
+
limit = options[:limit] || -1
|
346
|
+
limit = nil if limit < 1
|
347
|
+
|
348
|
+
l = options[:native] ? Rufus::Tokyo::List.new : []
|
349
|
+
|
350
|
+
lib.abs_iterinit(@db)
|
351
|
+
|
352
|
+
while (k = (lib.abs_iternext2(@db) rescue nil))
|
353
|
+
break if limit and l.size >= limit
|
354
|
+
l << k
|
355
|
+
end
|
356
|
+
|
357
|
+
l
|
358
|
+
end
|
237
359
|
end
|
238
360
|
end
|
239
361
|
|
@@ -97,12 +97,18 @@ module Rufus
|
|
97
97
|
attfunc :abs_sync, :tcadbsync, [ :pointer ], :int
|
98
98
|
attfunc :abs_copy, :tcadbcopy, [ :pointer, :string ], :int
|
99
99
|
|
100
|
+
attfunc :abs_fwmkeys2, :tcadbfwmkeys2, [ :pointer, :string, :int ], :pointer
|
101
|
+
|
100
102
|
#
|
101
103
|
# tctdb functions
|
102
104
|
#
|
103
105
|
# http://tokyocabinet.sourceforge.net/spex-en.html#tctdbapi
|
104
106
|
|
105
107
|
attfunc :tctdbnew, [], :pointer
|
108
|
+
attfunc :tctdbsetmutex, [ :pointer ], :int
|
109
|
+
attfunc :tctdbtune, [ :pointer, :uint64, :uint8, :uint8, :uint8 ], :int
|
110
|
+
attfunc :tctdbsetcache, [ :pointer, :uint32, :uint32, :uint32 ], :int
|
111
|
+
attfunc :tctdbsetxmsiz, [ :pointer, :uint64 ], :int
|
106
112
|
|
107
113
|
attfunc :tctdbopen, [ :pointer, :string, :int ], :int
|
108
114
|
|
@@ -137,6 +143,8 @@ module Rufus
|
|
137
143
|
attfunc :tctdbtrancommit, [ :pointer ], :int
|
138
144
|
attfunc :tctdbtranabort, [ :pointer ], :int
|
139
145
|
|
146
|
+
attfunc :tab_fwmkeys2, :tctdbfwmkeys2, [ :pointer, :string, :int ], :pointer
|
147
|
+
|
140
148
|
#
|
141
149
|
# tctdbqry functions
|
142
150
|
#
|
@@ -31,61 +31,94 @@
|
|
31
31
|
module Rufus
|
32
32
|
module Tokyo
|
33
33
|
|
34
|
-
|
34
|
+
#
|
35
|
+
# Methods for setting up / tuning a Cabinet.
|
36
|
+
#
|
37
|
+
# Gets included into Table.
|
38
|
+
#
|
39
|
+
module CabinetConfig
|
40
|
+
|
41
|
+
protected
|
35
42
|
|
36
43
|
#
|
37
|
-
#
|
44
|
+
# Given a path, a hash of parameters and a suffix,
|
45
|
+
#
|
46
|
+
# a) makes sure that the path has the given suffix or raises an exception
|
47
|
+
# b) gathers params found in the path (#) or in params
|
48
|
+
# c) determines the config as set by the parameters
|
49
|
+
#
|
50
|
+
def determine_conf (path, params, suffix)
|
38
51
|
|
39
|
-
|
40
|
-
OWRITER = 1 << 1 # open as a writer
|
41
|
-
OCREAT = 1 << 2 # writer creating
|
42
|
-
OTRUNC = 1 << 3 # writer truncating
|
43
|
-
ONOLCK = 1 << 4 # open without locking
|
44
|
-
OLCKNB = 1 << 5 # lock without blocking
|
52
|
+
if path.index('#')
|
45
53
|
|
46
|
-
|
54
|
+
ss = path.split('#')
|
55
|
+
path = ss.shift
|
47
56
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
57
|
+
ss.each { |p| pp = p.split('='); params[pp[0]] = pp[1] }
|
58
|
+
end
|
59
|
+
|
60
|
+
raise "path '#{path}' must be suffixed with #{suffix}" \
|
61
|
+
unless path[-suffix.length..-1] == suffix
|
62
|
+
|
63
|
+
params = params.inject({}) { |h, (k, v)| h[k.to_sym] = v; h }
|
53
64
|
|
54
|
-
|
55
|
-
params
|
56
|
-
|
65
|
+
conf = {
|
66
|
+
:params => params,
|
67
|
+
:path => path,
|
68
|
+
:mode => determine_open_mode(params),
|
69
|
+
:mutex => (params[:mutex].to_s == 'true'),
|
70
|
+
#:indexes => params[:idx] || params[:indexes],
|
71
|
+
:xmsiz => (params[:xmsiz] || 67108864).to_i
|
72
|
+
}
|
73
|
+
conf.merge!(determine_tuning_values(params))
|
74
|
+
conf.merge(determine_cache_values(params))
|
57
75
|
end
|
58
76
|
|
59
|
-
#
|
60
|
-
# Given params (array or hash), computes the open mode (an int)
|
61
|
-
# for the Tokyo Cabinet object.
|
62
|
-
#
|
63
|
-
def compute_open_mode (params)
|
77
|
+
def determine_open_mode (params) #:nodoc#
|
64
78
|
|
65
|
-
|
79
|
+
mode = params[:mode].to_s
|
80
|
+
mode = 'wc' if mode.size < 1
|
66
81
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
:lock_no_block => OLCKNB,
|
76
|
-
:sync_every => OTSYNC
|
82
|
+
{
|
83
|
+
'r' => (1 << 0), # open as a reader
|
84
|
+
'w' => (1 << 1), # open as a writer
|
85
|
+
'c' => (1 << 2), # writer creating
|
86
|
+
't' => (1 << 3), # writer truncating
|
87
|
+
'e' => (1 << 4), # open without locking
|
88
|
+
'f' => (1 << 5), # lock without blocking
|
89
|
+
's' => (1 << 6), # synchronize every transaction (tctdb.h)
|
77
90
|
|
78
|
-
}.inject(0) { |r, (
|
91
|
+
}.inject(0) { |r, (c, v)|
|
79
92
|
|
80
|
-
r = r | v if
|
93
|
+
r = r | v if mode.index(c); r
|
81
94
|
}
|
95
|
+
end
|
82
96
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
97
|
+
def determine_tuning_values (params) #:nodoc#
|
98
|
+
|
99
|
+
bnum = (params[:bnum] || 131071).to_i
|
100
|
+
apow = (params[:apow] || 4).to_i
|
101
|
+
fpow = (params[:fpow] || 10).to_i
|
87
102
|
|
88
|
-
|
103
|
+
o = params[:opts] || ''
|
104
|
+
o = {
|
105
|
+
'l' => 1 << 0, # large
|
106
|
+
'd' => 1 << 1, # deflate
|
107
|
+
'b' => 1 << 2, # bzip2
|
108
|
+
't' => 1 << 3, # tcbs
|
109
|
+
'x' => 1 << 4
|
110
|
+
}.inject(0) { |i, (k, v)| i = i | v if o.index(k); i }
|
111
|
+
|
112
|
+
{ :bnum => bnum, :apow => apow, :fpow => fpow, :opts => o }
|
113
|
+
end
|
114
|
+
|
115
|
+
def determine_cache_values (params) #:nodoc#
|
116
|
+
|
117
|
+
{
|
118
|
+
:rcnum => params[:rcnum].to_i,
|
119
|
+
:lcnum => (params[:lcnum] || 2048).to_i,
|
120
|
+
:ncnum => (params[:ncnum] || 512).to_i
|
121
|
+
}
|
89
122
|
end
|
90
123
|
end
|
91
124
|
|
@@ -122,31 +155,82 @@ module Rufus
|
|
122
155
|
class Table
|
123
156
|
|
124
157
|
include HashMethods
|
125
|
-
include
|
158
|
+
include CabinetConfig
|
126
159
|
|
127
160
|
#
|
128
161
|
# Creates a Table instance (creates or opens it depending on the args)
|
129
162
|
#
|
130
163
|
# For example,
|
131
164
|
#
|
132
|
-
# t = Rufus::Tokyo::Table.new('table.tdb'
|
165
|
+
# t = Rufus::Tokyo::Table.new('table.tdb')
|
133
166
|
# # '.tdb' suffix is a must
|
134
167
|
#
|
135
168
|
# will create the table.tdb (or simply open it if already present)
|
136
169
|
# and make sure we have write access to it.
|
137
|
-
# Note that the suffix (.tdc) is relevant to Tokyo Cabinet, using another
|
138
|
-
# will result in a Tokyo Cabinet error.
|
139
170
|
#
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
171
|
+
# == parameters
|
172
|
+
#
|
173
|
+
# Parameters can be set in the path or via the optional params hash (like
|
174
|
+
# in Rufus::Tokyo::Cabinet)
|
175
|
+
#
|
176
|
+
# * :mode a set of chars ('r'ead, 'w'rite, 'c'reate, 't'runcate,
|
177
|
+
# 'e' non locking, 'f' non blocking lock), default is 'wc'
|
178
|
+
# * :opts a set of chars ('l'arge, 'd'eflate, 'b'zip2, 't'cbs)
|
179
|
+
# (usually empty or something like 'ld' or 'lb')
|
180
|
+
#
|
181
|
+
# * :bnum number of elements of the bucket array
|
182
|
+
# * :apow size of record alignment by power of 2 (defaults to 4)
|
183
|
+
# * :fpow maximum number of elements of the free block pool by
|
184
|
+
# power of 2 (defaults to 10)
|
185
|
+
# * :mutex when set to true, makes sure only 1 thread at a time
|
186
|
+
# accesses the table (well, Ruby, global thread lock, ...)
|
187
|
+
#
|
188
|
+
# * :rcnum specifies the maximum number of records to be cached.
|
189
|
+
# If it is not more than 0, the record cache is disabled.
|
190
|
+
# It is disabled by default.
|
191
|
+
# * :lcnum specifies the maximum number of leaf nodes to be cached.
|
192
|
+
# If it is not more than 0, the default value is specified.
|
193
|
+
# The default value is 2048.
|
194
|
+
# * :ncnum specifies the maximum number of non-leaf nodes to be
|
195
|
+
# cached. If it is not more than 0, the default value is
|
196
|
+
# specified. The default value is 512.
|
197
|
+
#
|
198
|
+
# * :xmsiz specifies the size of the extra mapped memory. If it is
|
199
|
+
# not more than 0, the extra mapped memory is disabled.
|
200
|
+
# The default size is 67108864.
|
201
|
+
#
|
202
|
+
# Some examples :
|
203
|
+
#
|
204
|
+
# t = Rufus::Tokyo::Table.new('table.tdb')
|
205
|
+
# t = Rufus::Tokyo::Table.new('table.tdb#mode=r')
|
206
|
+
# t = Rufus::Tokyo::Table.new('table.tdb', :mode => 'r')
|
207
|
+
# t = Rufus::Tokyo::Table.new('table.tdb#opts=ld#mode=r')
|
208
|
+
# t = Rufus::Tokyo::Table.new('table.tdb', :opts => 'ld', :mode => 'r')
|
209
|
+
#
|
210
|
+
def initialize (path, params={})
|
144
211
|
|
145
|
-
|
212
|
+
conf = determine_conf(path, params, '.tdb')
|
146
213
|
|
147
214
|
@db = lib.tctdbnew
|
148
215
|
|
149
|
-
|
216
|
+
#
|
217
|
+
# tune table
|
218
|
+
|
219
|
+
libcall(:tctdbsetmutex) if conf[:mutex]
|
220
|
+
|
221
|
+
libcall(:tctdbtune, conf[:bnum], conf[:apow], conf[:fpow], conf[:opts])
|
222
|
+
|
223
|
+
# TODO : set indexes here... well, there is already #set_index
|
224
|
+
#conf[:indexes]...
|
225
|
+
|
226
|
+
libcall(:tctdbsetcache, conf[:rcnum], conf[:lcnum], conf[:ncnum])
|
227
|
+
|
228
|
+
libcall(:tctdbsetxmsiz, conf[:xmsiz])
|
229
|
+
|
230
|
+
#
|
231
|
+
# open table
|
232
|
+
|
233
|
+
libcall(:tctdbopen, conf[:path], conf[:mode])
|
150
234
|
end
|
151
235
|
|
152
236
|
#
|
@@ -245,25 +329,43 @@ module Rufus
|
|
245
329
|
end
|
246
330
|
|
247
331
|
#
|
248
|
-
# Returns
|
332
|
+
# Returns an array of all the primary keys in the table
|
249
333
|
#
|
250
|
-
#
|
334
|
+
# With no options given, this method will return all the keys (strings)
|
335
|
+
# in a Ruby array.
|
251
336
|
#
|
252
|
-
|
253
|
-
m = lib.tab_get(@db, k, CabinetLib.strlen(k))
|
254
|
-
return nil if m.address == 0 # :( too bad, but it works
|
255
|
-
Map.to_h(m) # which frees the map
|
256
|
-
end
|
257
|
-
protected :get
|
258
|
-
|
337
|
+
# :prefix --> returns only the keys who match a given string prefix
|
259
338
|
#
|
260
|
-
#
|
339
|
+
# :limit --> returns a limited number of keys
|
261
340
|
#
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
341
|
+
# :native --> returns an instance of Rufus::Tokyo::List instead of
|
342
|
+
# a Ruby Hash, you have to call #free on that List when done with it !
|
343
|
+
# Else you're exposing yourself to a memory leak.
|
344
|
+
#
|
345
|
+
def keys (options={})
|
346
|
+
|
347
|
+
if pref = options[:prefix]
|
348
|
+
|
349
|
+
l = lib.tab_fwmkeys2(@db, pref, options[:limit] || -1)
|
350
|
+
l = Rufus::Tokyo::List.new(l)
|
351
|
+
options[:native] ? l : l.release
|
352
|
+
|
353
|
+
else
|
354
|
+
|
355
|
+
limit = options[:limit] || -1
|
356
|
+
limit = nil if limit < 1
|
357
|
+
|
358
|
+
l = options[:native] ? Rufus::Tokyo::List.new : []
|
359
|
+
|
360
|
+
lib.tab_iterinit(@db)
|
361
|
+
|
362
|
+
while (k = (lib.tab_iternext2(@db) rescue nil))
|
363
|
+
break if limit and l.size >= limit
|
364
|
+
l << k
|
365
|
+
end
|
366
|
+
|
367
|
+
l
|
368
|
+
end
|
267
369
|
end
|
268
370
|
|
269
371
|
#
|
@@ -377,6 +479,17 @@ module Rufus
|
|
377
479
|
|
378
480
|
protected
|
379
481
|
|
482
|
+
#
|
483
|
+
# Returns the value (as a Ruby Hash) else nil
|
484
|
+
#
|
485
|
+
# (the actual #[] method is provided by HashMethods)
|
486
|
+
#
|
487
|
+
def get (k)
|
488
|
+
m = lib.tab_get(@db, k, CabinetLib.strlen(k))
|
489
|
+
return nil if m.address == 0 # :( too bad, but it works
|
490
|
+
Map.to_h(m) # which frees the map
|
491
|
+
end
|
492
|
+
|
380
493
|
def libcall (lib_method, *args)
|
381
494
|
|
382
495
|
#(lib.send(lib_method, @db, *args) == 1) or raise_error
|
@@ -179,7 +179,7 @@ module Rufus
|
|
179
179
|
# (by passing a list pointer, one can wrap an existing list pointer
|
180
180
|
# into a handy instance of this class)
|
181
181
|
#
|
182
|
-
def initialize (list_pointer
|
182
|
+
def initialize (list_pointer=nil)
|
183
183
|
@list = list_pointer || clib.tclistnew
|
184
184
|
end
|
185
185
|
|
@@ -333,6 +333,17 @@ module Rufus
|
|
333
333
|
alias :free :close
|
334
334
|
alias :destroy :close
|
335
335
|
|
336
|
+
#
|
337
|
+
# Closes (frees memory from it) this list and returns the ruby version
|
338
|
+
# of it
|
339
|
+
#
|
340
|
+
def release
|
341
|
+
|
342
|
+
a = self.to_a
|
343
|
+
self.close
|
344
|
+
a
|
345
|
+
end
|
346
|
+
|
336
347
|
protected
|
337
348
|
|
338
349
|
#
|
@@ -84,6 +84,8 @@ module Rufus
|
|
84
84
|
attfunc :abs_sync, :tcrdbsync, [ :pointer ], :int
|
85
85
|
attfunc :abs_copy, :tcrdbcopy, [ :pointer, :string ], :int
|
86
86
|
|
87
|
+
attfunc :abs_fwmkeys2, :tcrdbfwmkeys2, [ :pointer, :string, :int ], :pointer
|
88
|
+
|
87
89
|
#
|
88
90
|
# table functions
|
89
91
|
|
@@ -111,6 +113,8 @@ module Rufus
|
|
111
113
|
|
112
114
|
attfunc :tab_setindex, :tcrdbtblsetindex, [ :pointer, :string, :int ], :int
|
113
115
|
|
116
|
+
attfunc :tab_fwmkeys2, :tcrdbfwmkeys2, [ :pointer, :string, :int ], :pointer
|
117
|
+
|
114
118
|
#
|
115
119
|
# qry functions
|
116
120
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-tokyo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-02-
|
13
|
+
date: 2009-02-19 00:00:00 +09:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|