rufus-tokyo 0.1.4 → 0.1.5

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/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
-