rufus-tokyo 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -2,6 +2,15 @@
2
2
  = rufus-tokyo CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-tokyo - 0.1.5 released 2009/02/13
6
+
7
+ - todo : implemented set_index (cabinet / tyrant tables)
8
+ - todo : namespace simplification (Justin)
9
+ - todo : implemented Rufus::Tokyo::TyrantTable
10
+ - todo : implemented Rufus::Tokyo::Tyrant
11
+ - todo : moved tests to bacon (spec/)
12
+
13
+
5
14
  == rufus-tokyo - 0.1.4 released 2009/02/02
6
15
 
7
16
  - todo #23780 : hmethods for Rufus::Tokyo::Table
data/CREDITS.txt CHANGED
@@ -5,10 +5,6 @@
5
5
  == authors
6
6
 
7
7
  John Mettraux http://jmettraux.wordpress.com
8
-
9
-
10
- == contributors
11
-
12
8
  Justin Reagor http://blog.kineticweb.com/
13
9
 
14
10
 
data/README.txt CHANGED
@@ -1,21 +1,24 @@
1
1
 
2
2
  = rufus-tokyo
3
3
 
4
- ruby-ffi based interface to Tokyo Cabinet.
4
+ ruby-ffi based interface to Tokyo Cabinet and Tokyo Tyrant.
5
5
 
6
6
  The 'abstract' and the 'table' API are covered for now.
7
7
 
8
8
 
9
9
  == installation
10
10
 
11
- sudo gem install ffi rufus-tokyo
11
+ sudo gem install rufus-tokyo
12
12
 
13
- (see after 'usage' for how to install Tokyo Cabinet if required)
13
+ (see after 'usage' for how to install Tokyo Cabinet (and Tyrant) if required)
14
14
 
15
15
 
16
16
  == usage
17
17
 
18
- === Abstract API
18
+ hereafter TC references Tokyo Cabinet, while TT references Tokyo Tyrant.
19
+
20
+
21
+ === TC Abstract API
19
22
 
20
23
  http://tokyocabinet.sourceforge.net/spex-en.html#tcadbapi
21
24
 
@@ -38,12 +41,12 @@ to create a hash (file named 'data.tch')
38
41
  db.close
39
42
 
40
43
 
41
- === Table API
44
+ === TC Table API
42
45
 
43
46
  http://tokyocabinet.sourceforge.net/spex-en.html#tctdbapi
44
47
 
45
48
  require 'rubygems'
46
- require 'rufus/tokyo/cabinet/table'
49
+ require 'rufus/tokyo'
47
50
 
48
51
  t = Rufus::Tokyo::Table.new('table.tdb', :create, :write)
49
52
 
@@ -62,17 +65,62 @@ http://tokyocabinet.sourceforge.net/spex-en.html#tctdbapi
62
65
 
63
66
  t.close
64
67
 
68
+ === TT remote db
69
+
70
+ http://tokyocabinet.sourceforge.net/tyrantdoc/
71
+
72
+ require 'rubygems'
73
+ require 'rufus/tokyo'
74
+
75
+ db = Rufus::Tokyo::Tyrant.new('tyrant.example.com', 45001)
76
+
77
+ db['nada'] = 'surf'
78
+
79
+ p db['nada'] # => 'surf'
80
+ p db['lost'] # => nil
81
+
82
+ db.close
83
+
84
+
85
+ === TT remote table
86
+
87
+ like a local table :
88
+
89
+ require 'rubygems'
90
+ require 'rufus/tokyo'
91
+
92
+ t = Rufus::Tokyo::TyrantTable.new('localhost', 45006)
93
+
94
+ t['pk0'] = { 'name' => 'alfred', 'age' => '22' }
95
+ t['pk1'] = { 'name' => 'bob', 'age' => '18' }
96
+ t['pk2'] = { 'name' => 'charly', 'age' => '45' }
97
+ t['pk3'] = { 'name' => 'doug', 'age' => '77' }
98
+ t['pk4'] = { 'name' => 'ephrem', 'age' => '32' }
99
+
100
+ p t.query { |q|
101
+ q.add_condition 'age', :numge, '32'
102
+ q.order_by 'age'
103
+ }
104
+ # => [ {"name"=>"ephrem", :pk=>"pk4", "age"=>"32"},
105
+ # {"name"=>"charly", :pk=>"pk2", "age"=>"45"} ]
106
+
107
+ t.close
108
+
65
109
 
66
110
  more in the rdoc
67
111
 
68
112
  http://rufus.rubyforge.org/rufus-tokyo/
69
113
  http://rufus.rubyforge.org/rufus-tokyo/classes/Rufus/Tokyo/Cabinet.html
70
114
  http://rufus.rubyforge.org/rufus-tokyo/classes/Rufus/Tokyo/Table.html
115
+ http://rufus.rubyforge.org/rufus-tokyo/classes/Rufus/Tokyo/Tyrant.html
116
+ http://rufus.rubyforge.org/rufus-tokyo/classes/Rufus/Tokyo/TyrantTable.html
71
117
 
72
118
  or directly in the source
73
119
 
74
120
  http://github.com/jmettraux/rufus-tokyo/blob/master/lib/rufus/tokyo/cabinet/abstract.rb
75
121
  http://github.com/jmettraux/rufus-tokyo/blob/master/lib/rufus/tokyo/cabinet/table.rb
122
+ http://github.com/jmettraux/rufus-tokyo/blob/master/lib/rufus/tokyo/tyrant/abstract.rb
123
+ http://github.com/jmettraux/rufus-tokyo/blob/master/lib/rufus/tokyo/tyrant/table.rb
76
124
 
77
125
 
78
126
  == Tokyo Cabinet install
@@ -86,11 +134,35 @@ If you don't have Tokyo Cabinet on your system, you can get it and compile it :
86
134
 
87
135
  git clone git://github.com/etrepum/tokyo-cabinet.git
88
136
  cd tokyo-cabinet
89
- git checkout 1.4.2
137
+ #git checkout 1.4.4
138
+ ./configure
139
+ make
140
+ sudo make install
141
+
142
+ or get the souce at
143
+
144
+ http://sourceforge.net/project/showfiles.php?group_id=200242&package_id=237686
145
+
146
+ (note : I tend to run rufus-tokyo against the latest version of Tokyo Cabinet)
147
+
148
+
149
+ == Tokyo Tyrant install
150
+
151
+ (Tokyo Tyrant requires Tokyo Cabinet)
152
+
153
+ If you don't have Tokyo Tyrant on your system, you can get it and compile it :
154
+
155
+ git clone git://github.com/etrepum/tokyo-tyrant.git
156
+ cd tokyo-cabinet
157
+ #git checkout 1.1.14
90
158
  ./configure
91
159
  make
92
160
  sudo make install
93
161
 
162
+ or get the souce at
163
+
164
+ http://sourceforge.net/project/showfiles.php?group_id=200242&package_id=237686
165
+
94
166
 
95
167
  == dependencies
96
168
 
@@ -101,7 +173,7 @@ If you don't have Tokyo Cabinet on your system, you can get it and compile it :
101
173
 
102
174
  On the rufus-ruby list[http://groups.google.com/group/rufus-ruby] :
103
175
 
104
- http://groups.google.com/group/rufus-ruby
176
+ http://groups.google.com/group/rufus-ruby
105
177
 
106
178
 
107
179
  == issue tracker
@@ -118,7 +190,7 @@ irc.freenode.net #ruote
118
190
 
119
191
  http://github.com/jmettraux/rufus-tokyo
120
192
 
121
- git clone git://github.com/jmettraux/rufus-tokyo.git
193
+ git clone git://github.com/jmettraux/rufus-tokyo.git
122
194
 
123
195
 
124
196
  == credits
@@ -129,10 +201,10 @@ many thanks to the author of Tokyo Cabinet, Mikio Hirabayashi, and to the author
129
201
  http://kenai.com/projects/ruby-ffi
130
202
 
131
203
 
132
- == author
204
+ == authors
133
205
 
134
- John Mettraux, jmettraux@gmail.com
135
- http://jmettraux.wordpress.com
206
+ John Mettraux, jmettraux@gmail.com, http://jmettraux.wordpress.com
207
+ Justin Reagor, http://blog.kineticweb.com/
136
208
 
137
209
 
138
210
  == the rest of Rufus
data/lib/rufus/tokyo.rb CHANGED
@@ -22,6 +22,24 @@
22
22
  #++
23
23
  #
24
24
 
25
+ require 'ffi' # sudo gem install ffi
26
+
27
+
28
+ module Rufus
29
+ module Tokyo
30
+
31
+ VERSION = '0.1.5'
32
+
33
+ #
34
+ # A common error class
35
+ #
36
+ class TokyoError < RuntimeError; end
37
+
38
+ end
39
+ end
40
+
41
+ require File.dirname(__FILE__) + '/tokyo/hmethods'
25
42
  require File.dirname(__FILE__) + '/tokyo/cabinet'
26
- #require 'rufus/tokyo/cabinet'
43
+ require File.dirname(__FILE__) + '/tokyo/tyrant'
44
+ require File.dirname(__FILE__) + '/tokyo/dystopia'
27
45
 
@@ -1,3 +1,6 @@
1
1
 
2
- require 'rufus/tokyo/cabinet/abstract'
2
+ require File.dirname(__FILE__) + '/cabinet/lib'
3
+ require File.dirname(__FILE__) + '/cabinet/util'
4
+ require File.dirname(__FILE__) + '/cabinet/table'
5
+ require File.dirname(__FILE__) + '/cabinet/abstract'
3
6
 
@@ -28,209 +28,214 @@
28
28
  # jmettraux@gmail.com
29
29
  #
30
30
 
31
- require 'rufus/tokyo/hmethods'
32
- require 'rufus/tokyo/cabinet/lib'
33
-
34
-
35
- module Rufus::Tokyo
36
-
37
- #
38
- # A 'cabinet', ie a Tokyo Cabinet [abstract] database.
39
- #
40
- # Follows the abstract API described at :
41
- #
42
- # http://tokyocabinet.sourceforge.net/spex-en.html#tcadbapi
43
- #
44
- # An usage example :
45
- #
46
- # db = Rufus::Tokyo::Cabinet.new('test_data.tch')
47
- # db['pillow'] = 'Shonagon'
48
- #
49
- # db.size # => 1
50
- # db['pillow'] # => 'Shonagon'
51
- #
52
- # db.delete('pillow') # => 'Shonagon'
53
- # db.size # => 0
54
- #
55
- # db.close
56
- #
57
- class Cabinet
58
- include CabinetLibMixin
59
- include HashMethods
31
+ module Rufus
32
+ module Tokyo
60
33
 
61
34
  #
62
- # Creates/opens the cabinet, raises an exception in case of
63
- # creation/opening failure.
35
+ # A 'cabinet', ie a Tokyo Cabinet [abstract] database.
64
36
  #
65
- # This method accepts a 'name' parameter and an optional 'params' hash
66
- # parameter.
67
- #
68
- # 'name' follows the syntax described at
37
+ # Follows the abstract API described at :
69
38
  #
70
39
  # http://tokyocabinet.sourceforge.net/spex-en.html#tcadbapi
71
40
  #
72
- # under tcadbopen(). For example :
73
- #
74
- # db = Rufus::Tokyo::Cabinet.new('casket.tch#bnum=100000#opts=ld')
75
- #
76
- # will open (eventually create) a hash database backed in the file
77
- # 'casket.tch' with a bucket number of 100000 and the 'large' and
78
- # 'deflate' options (opts) turned on.
79
- #
80
- # == :hash or :tree
81
- #
82
- # Setting the name to :hash or :tree simply will create a in-memory hash
83
- # or tree respectively (see #new_tree and #new_hash).
84
- #
85
- # == tuning parameters
86
- #
87
- # It's ok to use the optional params hash to pass tuning parameters and
88
- # options, thus
89
- #
90
- # db = Rufus::Tokyo::Cabinet.new('casket.tch#bnum=100000#opts=ld')
91
- #
92
- # and
93
- #
94
- # db = Rufus::Tokyo::Cabinet.new(
95
- # 'casket.tch', :bnum => 100000, :opts => 'ld')
96
- #
97
- # are equivalent.
98
- #
99
- # == mode
100
- #
101
- # To open a db in read-only mode :
102
- #
103
- # db = Rufus::Tokyo::Cabinet.new('casket.tch#mode=r')
104
- # db = Rufus::Tokyo::Cabinet.new('casket.tch', :mode => 'r')
105
- #
106
- def initialize (name, params={})
107
-
108
- @db = lib.tcadbnew
109
-
110
- name = '*' if name == :hash # in memory hash database
111
- name = '+' if name == :tree # in memory B+ tree database
112
-
113
- name = name + params.collect { |k, v| "##{k}=#{v}" }.join('')
114
-
115
- (lib.tcadbopen(@db, name) == 1) ||
116
- raise("failed to open/create db '#{name}'")
117
-
118
- self.default = params[:default]
119
- @default_proc ||= params[:default_proc]
120
- end
121
-
122
- #
123
- # Returns a new in-memory hash. Accepts the same optional params hash
124
- # as new().
125
- #
126
- def self.new_hash (params={})
127
- self.new(:hash, params)
41
+ # An usage example :
42
+ #
43
+ # db = Rufus::Tokyo::Cabinet.new('test_data.tch')
44
+ # db['pillow'] = 'Shonagon'
45
+ #
46
+ # db.size # => 1
47
+ # db['pillow'] # => 'Shonagon'
48
+ #
49
+ # db.delete('pillow') # => 'Shonagon'
50
+ # db.size # => 0
51
+ #
52
+ # db.close
53
+ #
54
+ class Cabinet
55
+
56
+ include HashMethods
57
+
58
+ #
59
+ # Creates/opens the cabinet, raises an exception in case of
60
+ # creation/opening failure.
61
+ #
62
+ # This method accepts a 'name' parameter and an optional 'params' hash
63
+ # parameter.
64
+ #
65
+ # 'name' follows the syntax described at
66
+ #
67
+ # http://tokyocabinet.sourceforge.net/spex-en.html#tcadbapi
68
+ #
69
+ # under tcadbopen(). For example :
70
+ #
71
+ # db = Rufus::Tokyo::Cabinet.new('casket.tch#bnum=100000#opts=ld')
72
+ #
73
+ # will open (eventually create) a hash database backed in the file
74
+ # 'casket.tch' with a bucket number of 100000 and the 'large' and
75
+ # 'deflate' options (opts) turned on.
76
+ #
77
+ # == :hash or :tree
78
+ #
79
+ # Setting the name to :hash or :tree simply will create a in-memory hash
80
+ # or tree respectively (see #new_tree and #new_hash).
81
+ #
82
+ # == tuning parameters
83
+ #
84
+ # It's ok to use the optional params hash to pass tuning parameters and
85
+ # options, thus
86
+ #
87
+ # db = Rufus::Tokyo::Cabinet.new('casket.tch#bnum=100000#opts=ld')
88
+ #
89
+ # and
90
+ #
91
+ # db = Rufus::Tokyo::Cabinet.new(
92
+ # 'casket.tch', :bnum => 100000, :opts => 'ld')
93
+ #
94
+ # are equivalent.
95
+ #
96
+ # == mode
97
+ #
98
+ # To open a db in read-only mode :
99
+ #
100
+ # db = Rufus::Tokyo::Cabinet.new('casket.tch#mode=r')
101
+ # db = Rufus::Tokyo::Cabinet.new('casket.tch', :mode => 'r')
102
+ #
103
+ def initialize (name, params={})
104
+
105
+ @db = lib.tcadbnew
106
+
107
+ name = '*' if name == :hash # in memory hash database
108
+ name = '+' if name == :tree # in memory B+ tree database
109
+
110
+ name = name + params.collect { |k, v| "##{k}=#{v}" }.join('')
111
+
112
+ (lib.tcadbopen(@db, name) == 1) ||
113
+ raise("failed to open/create db '#{name}'")
114
+
115
+ self.default = params[:default]
116
+ @default_proc ||= params[:default_proc]
117
+ end
118
+
119
+ #
120
+ # Returns a new in-memory hash. Accepts the same optional params hash
121
+ # as new().
122
+ #
123
+ def self.new_hash (params={})
124
+ self.new(:hash, params)
125
+ end
126
+
127
+ #
128
+ # Returns a new in-memory B+ tree. Accepts the same optional params hash
129
+ # as new().
130
+ #
131
+ def self.new_tree (params={})
132
+ self.new(:tree, params)
133
+ end
134
+
135
+ #
136
+ # using the cabinet lib
137
+ #
138
+ def lib
139
+ CabinetLib
140
+ end
141
+
142
+ #
143
+ # No comment
144
+ #
145
+ def []= (k, v)
146
+ lib.abs_put2(@db, k, v)
147
+ end
148
+
149
+ #
150
+ # (The actual #[] method is provided by HashMethods
151
+ #
152
+ def get (k)
153
+ lib.abs_get2(@db, k) rescue nil
154
+ end
155
+ protected :get
156
+
157
+ #
158
+ # Removes a record from the cabinet, returns the value if successful
159
+ # else nil.
160
+ #
161
+ def delete (k)
162
+ v = self[k]
163
+ (lib.abs_out2(@db, k) == 1) ? v : nil
164
+ end
165
+
166
+ #
167
+ # Returns the number of records in the 'cabinet'
168
+ #
169
+ def size
170
+ lib.abs_rnum(@db)
171
+ end
172
+
173
+ #
174
+ # Removes all the records in the cabinet (use with care)
175
+ #
176
+ # Returns self (like Ruby's Hash does).
177
+ #
178
+ def clear
179
+ lib.abs_vanish(@db)
180
+ self
181
+ end
182
+
183
+ #
184
+ # Returns the 'weight' of the db (in bytes)
185
+ #
186
+ def weight
187
+ lib.abs_size(@db)
188
+ end
189
+
190
+ #
191
+ # Closes the cabinet (and frees the datastructure allocated for it),
192
+ # returns true in case of success.
193
+ #
194
+ def close
195
+ result = lib.abs_close(@db)
196
+ lib.abs_del(@db)
197
+ (result == 1)
198
+ end
199
+
200
+ #
201
+ # Copies the current cabinet to a new file.
202
+ #
203
+ # Returns true if it was successful.
204
+ #
205
+ def copy (target_path)
206
+ (lib.abs_copy(@db, target_path) == 1)
207
+ end
208
+
209
+ #
210
+ # Copies the current cabinet to a new file.
211
+ #
212
+ # Does it by copying each entry afresh to the target file. Spares some
213
+ # space, hence the 'compact' label...
214
+ #
215
+ def compact_copy (target_path)
216
+ @other_db = Cabinet.new(target_path)
217
+ self.each { |k, v| @other_db[k] = v }
218
+ @other_db.close
219
+ end
220
+
221
+ #
222
+ # "synchronize updated contents of an abstract database object with
223
+ # the file and the device"
224
+ #
225
+ def sync
226
+ (lib.abs_sync(@db) == 1)
227
+ end
228
+
229
+ #
230
+ # Returns an array with all the keys in the databse
231
+ #
232
+ def keys
233
+ a = []
234
+ lib.abs_iterinit(@db)
235
+ while (k = (lib.abs_iternext2(@db) rescue nil)); a << k; end
236
+ a
237
+ end
128
238
  end
129
239
 
130
- #
131
- # Returns a new in-memory B+ tree. Accepts the same optional params hash
132
- # as new().
133
- #
134
- def self.new_tree (params={})
135
- self.new(:tree, params)
136
- end
137
-
138
- #
139
- # No comment
140
- #
141
- def []= (k, v)
142
- lib.tcadbput2(@db, k, v)
143
- end
144
-
145
- #
146
- # (The actual #[] method is provided by HashMethods
147
- #
148
- def get (k)
149
- lib.tcadbget2(@db, k) rescue nil
150
- end
151
- protected :get
152
-
153
- #
154
- # Removes a record from the cabinet, returns the value if successful
155
- # else nil.
156
- #
157
- def delete (k)
158
- v = self[k]
159
- (lib.tcadbout2(@db, k) == 1) ? v : nil
160
- end
161
-
162
- #
163
- # Returns the number of records in the 'cabinet'
164
- #
165
- def size
166
- lib.tcadbrnum(@db)
167
- end
168
-
169
- #
170
- # Removes all the records in the cabinet (use with care)
171
- #
172
- # Returns self (like Ruby's Hash does).
173
- #
174
- def clear
175
- lib.tcadbvanish(@db)
176
- self
177
- end
178
-
179
- #
180
- # Returns the 'weight' of the db (in bytes)
181
- #
182
- def weight
183
- lib.tcadbsize(@db)
184
- end
185
-
186
- #
187
- # Closes the cabinet (and frees the datastructure allocated for it),
188
- # returns true in case of success.
189
- #
190
- def close
191
- result = lib.tcadbclose(@db)
192
- lib.tcadbdel(@db)
193
- (result == 1)
194
- end
195
-
196
- #
197
- # Copies the current cabinet to a new file.
198
- #
199
- # Returns true if it was successful.
200
- #
201
- def copy (target_path)
202
- (lib.tcadbcopy(@db, target_path) == 1)
203
- end
204
-
205
- #
206
- # Copies the current cabinet to a new file.
207
- #
208
- # Does it by copying each entry afresh to the target file. Spares some
209
- # space, hence the 'compact' label...
210
- #
211
- def compact_copy (target_path)
212
- @other_db = Rufus::Tokyo::Cabinet.new(target_path)
213
- self.each { |k, v| @other_db[k] = v }
214
- @other_db.close
215
- end
216
-
217
- #
218
- # "synchronize updated contents of an abstract database object with
219
- # the file and the device"
220
- #
221
- def sync
222
- (lib.tcadbsync(@db) == 1)
223
- end
224
-
225
- #
226
- # Returns an array with all the keys in the databse
227
- #
228
- def keys
229
- a = []
230
- lib.tcadbiterinit(@db)
231
- while (k = (lib.tcadbiternext2(@db) rescue nil)); a << k; end
232
- a
233
- end
234
240
  end
235
241
  end
236
-