rufus-tokyo 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,332 +31,363 @@
31
31
  require 'rufus/tokyo/hmethods'
32
32
 
33
33
 
34
- module Rufus
35
- module Tokyo
34
+ module Rufus::Tokyo
35
+
36
+ #
37
+ # A Tokyo Cabinet in-memory (tcutil.h) map
38
+ #
39
+ # http://tokyocabinet.sourceforge.net/spex-en.html#tcutilapi
40
+ #
41
+ class Map
42
+
43
+ include HashMethods
36
44
 
37
45
  #
38
- # A Tokyo Cabinet in-memory (tcutil.h) map
46
+ # Creates an empty instance of a Tokyo Cabinet in-memory map
39
47
  #
40
- # http://tokyocabinet.sourceforge.net/spex-en.html#tcutilapi
48
+ # (It's OK to pass the pointer of a C map directly, this is in fact
49
+ # used in rufus/tokyo/table when retrieving entries)
41
50
  #
42
- class Map
51
+ def initialize (pointer = nil)
52
+ @map = pointer || clib.tcmapnew
53
+ end
43
54
 
44
- include HashMethods
55
+ #
56
+ # a shortcut
57
+ #
58
+ def clib
59
+ CabinetLib
60
+ end
45
61
 
46
- #
47
- # Creates an empty instance of a Tokyo Cabinet in-memory map
48
- #
49
- # (It's OK to pass the pointer of a C map directly, this is in fact
50
- # used in rufus/tokyo/table when retrieving entries)
51
- #
52
- def initialize (pointer = nil)
53
- @map = pointer || clib.tcmapnew
54
- end
62
+ #
63
+ # Inserts key/value pair
64
+ #
65
+ def []= (k, v)
66
+ clib.tcmapput2(m, k, v)
67
+ v
68
+ end
55
69
 
56
- #
57
- # a shortcut
58
- #
59
- def clib
60
- CabinetLib
61
- end
70
+ #
71
+ # Deletes an entry
72
+ #
73
+ def delete (k)
74
+ v = self[k]
75
+ return nil unless v
76
+ (clib.tcmapout2(m, k) == 1) || raise("failed to remove key '#{k}'")
77
+ v
78
+ end
62
79
 
63
- #
64
- # Inserts key/value pair
65
- #
66
- def []= (k, v)
67
- clib.tcmapput2(m, k, v)
68
- v
69
- end
80
+ #
81
+ # Empties the map
82
+ #
83
+ def clear
84
+ clib.tcmapclear(m)
85
+ end
70
86
 
71
- #
72
- # Deletes an entry
73
- #
74
- def delete (k)
75
- v = self[k]
76
- return nil unless v
77
- (clib.tcmapout2(m, k) == 1) || raise("failed to remove key '#{k}'")
78
- v
79
- end
87
+ #
88
+ # (the actual #[] method is provided by HashMethods)
89
+ #
90
+ def get (k)
91
+ m; clib.tcmapget2(m, k) rescue nil
92
+ end
93
+ protected :get
80
94
 
81
- #
82
- # Empties the map
83
- #
84
- def clear
85
- clib.tcmapclear(m)
86
- end
95
+ #
96
+ # Returns an array of all the keys in the map
97
+ #
98
+ def keys
99
+ a = []
100
+ clib.tcmapiterinit(m)
101
+ while (k = (clib.tcmapiternext2(m) rescue nil)); a << k; end
102
+ a
103
+ end
87
104
 
88
- #
89
- # (the actual #[] method is provided by HashMethods)
90
- #
91
- def get (k)
92
- m; clib.tcmapget2(m, k) rescue nil
93
- end
94
- protected :get
95
-
96
- #
97
- # Returns an array of all the keys in the map
98
- #
99
- def keys
100
- a = []
101
- clib.tcmapiterinit(m)
102
- while (k = (clib.tcmapiternext2(m) rescue nil)); a << k; end
103
- a
104
- end
105
+ #
106
+ # Returns the count of entries in the map
107
+ #
108
+ def size
109
+ clib.tcmaprnum(m)
110
+ end
105
111
 
106
- #
107
- # Returns the count of entries in the map
108
- #
109
- def size
110
- clib.tcmaprnum(m)
111
- end
112
+ alias :length :size
113
+
114
+ #
115
+ # Frees the map (nukes it from memory)
116
+ #
117
+ def free
118
+ clib.tcmapdel(@map)
119
+ @map = nil
120
+ end
112
121
 
113
- alias :length :size
122
+ alias :destroy :free
123
+ alias :close :free
114
124
 
115
- #
116
- # Frees the map (nukes it from memory)
117
- #
118
- def free
119
- clib.tcmapdel(@map)
120
- @map = nil
121
- end
125
+ #
126
+ # Returns the pointer to the underlying Tokyo Cabinet map
127
+ #
128
+ def pointer
129
+ @map || raise('map got freed, cannot use anymore')
130
+ end
122
131
 
123
- alias :destroy :free
124
- alias :close :free
132
+ alias :m :pointer
125
133
 
126
- #
127
- # Returns the pointer to the underlying Tokyo Cabinet map
128
- #
129
- def pointer
130
- @map || raise('map got freed, cannot use anymore')
131
- end
134
+ #
135
+ # Turns a given Tokyo map structure into a Ruby Hash. By default
136
+ # (free = true) will dispose of the map before replying with the Ruby
137
+ # Hash.
138
+ #
139
+ def self.to_h (map_pointer, free=true)
140
+ m = self.new(map_pointer)
141
+ h = m.to_h
142
+ m.free if free
143
+ h
144
+ end
132
145
 
133
- alias :m :pointer
134
-
135
- #
136
- # Turns a given Tokyo map structure into a Ruby Hash. By default
137
- # (free = true) will dispose of the map before replying with the Ruby Hash.
138
- #
139
- def self.to_h (map_pointer, free = true)
140
- m = self.new(map_pointer)
141
- h = m.to_h
142
- m.free if free
143
- h
144
- end
146
+ #
147
+ # Turns a Ruby hash into a Tokyo Cabinet Map and returns it
148
+ # (don't forget to free the map when you're done with it !)
149
+ #
150
+ def self.from_h (h)
151
+ h.inject(Map.new) { |m, (k, v)| m[k] = v; m }
152
+ end
153
+
154
+ #
155
+ # Behaves much like Hash#[] but outputs a Rufus::Tokyo::Map
156
+ # (don't forget to free the map when you're done with it !)
157
+ #
158
+ def self.[] (*h_or_a)
145
159
 
146
- #
147
- # Turns a Ruby hash into a Tokyo Cabinet Map and returns it
148
- # (don't forget to free the map when you're done with it !)
149
- #
150
- def self.from_h (h)
151
- h.inject(Map.new) { |m, (k, v)| m[k] = v; m }
160
+ if h_or_a.is_a?(Array) && h_or_a.size == 1 && h_or_a.first.is_a?(Array)
161
+ h_or_a = h_or_a.first
152
162
  end
153
163
 
154
- #
155
- # Behaves much like Hash#[] but outputs a Rufus::Tokyo::Map
156
- # (don't forget to free the map when you're done with it !)
157
- #
158
- def self.[] (*h_or_a)
164
+ from_h(::Hash[*h_or_a])
165
+ end
166
+ end
159
167
 
160
- if h_or_a.is_a?(Array) && h_or_a.size == 1 && h_or_a.first.is_a?(Array)
161
- h_or_a = h_or_a.first
162
- end
168
+ #
169
+ # A Tokyo Cabinet in-memory (tcutil.h) list
170
+ #
171
+ # http://tokyocabinet.sourceforge.net/spex-en.html#tcutilapi
172
+ #
173
+ class List
174
+ include Enumerable
163
175
 
164
- from_h(::Hash[*h_or_a])
176
+ #
177
+ # Creates a new Tokyo Cabinet list.
178
+ #
179
+ # (by passing a list pointer, one can wrap an existing list pointer
180
+ # into a handy instance of this class)
181
+ #
182
+ def initialize (list_pointer=nil)
183
+
184
+ if list_pointer.is_a?(FFI::Pointer)
185
+ @list = list_pointer
186
+ else
187
+ @list = clib.tclistnew
188
+ list_pointer.each { |e| self << e } if list_pointer
165
189
  end
166
190
  end
167
191
 
168
192
  #
169
- # A Tokyo Cabinet in-memory (tcutil.h) list
193
+ # a shortcut
170
194
  #
171
- # http://tokyocabinet.sourceforge.net/spex-en.html#tcutilapi
195
+ def clib
196
+ CabinetLib
197
+ end
198
+
172
199
  #
173
- class List
174
- include Enumerable
200
+ # Inserts an element in the list (note that the lib will raise an
201
+ # ArgumentError if s is not a String)
202
+ #
203
+ def << (s)
204
+ clib.tclistpush2(@list, s)
205
+ self
206
+ end
175
207
 
176
- #
177
- # Creates a new Tokyo Cabinet list.
178
- #
179
- # (by passing a list pointer, one can wrap an existing list pointer
180
- # into a handy instance of this class)
181
- #
182
- def initialize (list_pointer=nil)
183
- @list = list_pointer || clib.tclistnew
184
- end
208
+ #
209
+ # Pushes an argument or a list of arguments to this list
210
+ #
211
+ def push (*args)
212
+ args.each { |a| self << a }
213
+ self
214
+ end
185
215
 
186
- #
187
- # a shortcut
188
- #
189
- def clib
190
- CabinetLib
191
- end
216
+ #
217
+ # Pops the last element in the list
218
+ #
219
+ def pop
220
+ clib.tclistpop2(@list) rescue nil
221
+ end
192
222
 
193
- #
194
- # Inserts an element in the list (note that the lib will raise an
195
- # ArgumentError if s is not a String)
196
- #
197
- def << (s)
198
- clib.tclistpush2(@list, s)
199
- self
200
- end
223
+ #
224
+ # Removes and returns the first element in a list
225
+ #
226
+ def shift
227
+ clib.tclistshift2(@list) rescue nil
228
+ end
201
229
 
202
- #
203
- # Pushes an argument or a list of arguments to this list
204
- #
205
- def push (*args)
206
- args.each { |a| self << a }
207
- self
208
- end
230
+ #
231
+ # Inserts a string at the beginning of the list
232
+ #
233
+ def unshift (s)
234
+ clib.tclistunshift2(@list, s)
235
+ self
236
+ end
209
237
 
210
- #
211
- # Pops the last element in the list
212
- #
213
- def pop
214
- clib.tclistpop2(@list) rescue nil
215
- end
238
+ def []= (a, b, c=nil)
216
239
 
217
- #
218
- # Removes and returns the first element in a list
219
- #
220
- def shift
221
- clib.tclistshift2(@list) rescue nil
222
- end
240
+ i, s = c.nil? ? [ a, b ] : [ [a, b], c ]
241
+
242
+ range = if i.is_a?(Range)
243
+ i
244
+ elsif i.is_a?(Array)
245
+ start, count = i
246
+ (start..start + count - 1)
247
+ else
248
+ [ i ]
249
+ end
223
250
 
224
- #
225
- # Inserts a string at the beginning of the list
226
- #
227
- def unshift (s)
228
- clib.tclistunshift2(@list, s)
229
- self
251
+ range = norm(range)
252
+
253
+ values = s.is_a?(Array) ? s : [ s ]
254
+ # not "values = Array(s)"
255
+
256
+ range.each_with_index do |offset, index|
257
+ val = values[index]
258
+ if val
259
+ clib.tclistover2(@list, offset, val)
260
+ else
261
+ clib.tclistremove2(@list, values.size)
262
+ end
230
263
  end
231
264
 
232
- def []= (a, b, c=nil)
265
+ self
266
+ end
233
267
 
234
- i, s = c.nil? ? [ a, b ] : [ [a, b], c ]
268
+ #
269
+ # Removes the value at a given index and returns the value
270
+ # (returns nil if no value available)
271
+ #
272
+ def delete_at (i)
273
+ clib.tclistremove2(@list, i)
274
+ end
235
275
 
236
- range = if i.is_a?(Range)
237
- i
238
- elsif i.is_a?(Array)
239
- start, count = i
240
- (start..start + count - 1)
241
- else
242
- [ i ]
243
- end
276
+ def delete_if
277
+ # TODO
278
+ end
244
279
 
245
- range = norm(range)
280
+ def slice
281
+ # TODO
282
+ end
283
+ def slice!
284
+ # TODO
285
+ end
246
286
 
247
- values = s.is_a?(Array) ? s : [ s ]
248
- # not "values = Array(s)"
287
+ #
288
+ # Returns the size of this Tokyo Cabinet list
289
+ #
290
+ def size
291
+ clib.tclistnum(@list)
292
+ end
249
293
 
250
- range.each_with_index do |offset, index|
251
- val = values[index]
252
- if val
253
- clib.tclistover2(@list, offset, val)
254
- else
255
- clib.tclistremove2(@list, values.size)
256
- end
257
- end
294
+ alias :length :size
258
295
 
259
- self
260
- end
296
+ #
297
+ # The equivalent of Ruby Array#[]
298
+ #
299
+ def [] (i, count=nil)
261
300
 
262
- #
263
- # Removes the value at a given index and returns the value
264
- # (returns nil if no value available)
265
- #
266
- def delete_at (i)
267
- clib.tclistremove2(@list, i)
268
- end
301
+ return nil if (count != nil) && count < 1
269
302
 
270
- def delete_if
271
- # TODO
272
- end
303
+ len = self.size
273
304
 
274
- def slice
275
- # TODO
276
- end
277
- def slice!
278
- # TODO
279
- end
305
+ range = if count.nil?
306
+ i.is_a?(Range) ? i : [i]
307
+ else
308
+ (i..i + count - 1)
309
+ end
280
310
 
281
- #
282
- # Returns the size of this Tokyo Cabinet list
283
- #
284
- def size
285
- clib.tclistnum(@list)
286
- end
311
+ r = norm(range).collect { |i| clib.tclistval2(@list, i) rescue nil }
287
312
 
288
- alias :length :size
313
+ range.first == range.last ? r.first : r
314
+ end
289
315
 
290
- #
291
- # The equivalent of Ruby Array#[]
292
- #
293
- def [] (i, count=nil)
316
+ def clear
317
+ clib.tclistclear(@list)
318
+ end
294
319
 
295
- return nil if (count != nil) && count < 1
320
+ def each
321
+ (0..self.size - 1).each { |i| yield self[i] }
322
+ end
296
323
 
297
- len = self.size
324
+ #
325
+ # Turns this Tokyo Cabinet list into a Ruby array
326
+ #
327
+ def to_a
328
+ self.collect { |e| e }
329
+ end
298
330
 
299
- range = if count.nil?
300
- i.is_a?(Range) ? i : [i]
301
- else
302
- (i..i + count - 1)
303
- end
331
+ #
332
+ # Closes (frees) this list
333
+ #
334
+ def free
335
+ self.class.free(@list)
336
+ @list = nil
337
+ end
304
338
 
305
- r = norm(range).collect { |i| clib.tclistval2(@list, i) rescue nil }
339
+ alias :close :free
340
+ alias :destroy :free
306
341
 
307
- range.first == range.last ? r.first : r
308
- end
342
+ #
343
+ # Frees (closes) the given 'native' (FFI) list (memory pointer)
344
+ #
345
+ def self.free (list_pointer)
309
346
 
310
- def clear
311
- clib.tclistclear(@list)
312
- end
347
+ CabinetLib.tclistdel(list_pointer)
348
+ end
313
349
 
314
- def each
315
- (0..self.size - 1).each { |i| yield self[i] }
316
- end
350
+ #
351
+ # Closes (frees memory from it) this list and returns the ruby version
352
+ # of it
353
+ #
354
+ def release
317
355
 
318
- #
319
- # Turns this Tokyo Cabinet list into a Ruby array
320
- #
321
- def to_a
322
- self.collect { |e| e }
323
- end
356
+ a = self.to_a
357
+ self.close
358
+ a
359
+ end
324
360
 
325
- #
326
- # Closes (frees) this list
327
- #
328
- def close
329
- clib.tclistdel(@list)
330
- @list = nil
331
- end
361
+ #
362
+ # Returns the underlying 'native' (FFI) memory pointer
363
+ #
364
+ def pointer
365
+
366
+ @list
367
+ end
332
368
 
333
- alias :free :close
334
- alias :destroy :close
369
+ #
370
+ # Turns a list pointer into a Ruby Array instance (and makes sure to
371
+ # release the pointer
372
+ #
373
+ def self.release (list_pointer)
335
374
 
336
- #
337
- # Closes (frees memory from it) this list and returns the ruby version
338
- # of it
339
- #
340
- def release
375
+ Rufus::Tokyo::List.new(list_pointer).release
376
+ end
341
377
 
342
- a = self.to_a
343
- self.close
344
- a
345
- end
378
+ protected
346
379
 
347
- protected
348
-
349
- #
350
- # Makes sure this offset/range fits the size of the list
351
- #
352
- def norm (i)
353
- l = self.length
354
- case i
355
- when Range then ((i.first % l)..(i.last % l))
356
- when Array then [ i.first % l ]
357
- else i % l
358
- end
380
+ #
381
+ # Makes sure this offset/range fits the size of the list
382
+ #
383
+ def norm (i)
384
+ l = self.length
385
+ case i
386
+ when Range then ((i.first % l)..(i.last % l))
387
+ when Array then [ i.first % l ]
388
+ else i % l
359
389
  end
360
390
  end
361
391
  end
362
392
  end
393
+