hashery 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/.ruby +30 -17
  2. data/.yardopts +1 -0
  3. data/Config.rb +28 -0
  4. data/{QED.rdoc → DEMO.rdoc} +0 -0
  5. data/HISTORY.rdoc +37 -0
  6. data/LICENSE.txt +26 -0
  7. data/NOTICE.txt +46 -0
  8. data/README.rdoc +10 -7
  9. data/lib/hashery.rb +6 -6
  10. data/lib/hashery.yml +30 -17
  11. data/lib/hashery/association.rb +169 -109
  12. data/lib/hashery/casting_hash.rb +128 -135
  13. data/lib/hashery/core_ext.rb +89 -61
  14. data/lib/hashery/crud_hash.rb +365 -0
  15. data/lib/hashery/dictionary.rb +545 -345
  16. data/lib/hashery/fuzzy_hash.rb +177 -125
  17. data/lib/hashery/ini_hash.rb +321 -0
  18. data/lib/hashery/key_hash.rb +54 -179
  19. data/lib/hashery/linked_list.rb +245 -191
  20. data/lib/hashery/lru_hash.rb +292 -202
  21. data/lib/hashery/open_cascade.rb +133 -78
  22. data/lib/hashery/open_hash.rb +127 -61
  23. data/lib/hashery/ordered_hash.rb +128 -122
  24. data/lib/hashery/path_hash.rb +238 -0
  25. data/lib/hashery/property_hash.rb +144 -80
  26. data/lib/hashery/query_hash.rb +85 -29
  27. data/lib/hashery/stash.rb +7 -3
  28. data/lib/hashery/static_hash.rb +46 -41
  29. data/test/case_association.rb +65 -4
  30. data/test/case_dictionary.rb +149 -5
  31. data/test/{case_keyhash.rb → case_key_hash.rb} +20 -14
  32. data/test/case_lru_hash.rb +162 -0
  33. data/test/{case_opencascade.rb → case_open_cascade.rb} +4 -8
  34. data/test/case_open_hash.rb +87 -0
  35. data/test/case_query_hash.rb +226 -0
  36. data/test/helper.rb +8 -0
  37. metadata +33 -63
  38. data/COPYING.rdoc +0 -45
  39. data/lib/hashery/basic_object.rb +0 -74
  40. data/lib/hashery/basic_struct.rb +0 -288
  41. data/lib/hashery/basicobject.rb +0 -1
  42. data/lib/hashery/basicstruct.rb +0 -1
  43. data/lib/hashery/castinghash.rb +0 -1
  44. data/lib/hashery/fuzzyhash.rb +0 -1
  45. data/lib/hashery/ini.rb +0 -268
  46. data/lib/hashery/keyhash.rb +0 -1
  47. data/lib/hashery/linkedlist.rb +0 -1
  48. data/lib/hashery/lruhash.rb +0 -1
  49. data/lib/hashery/memoizer.rb +0 -64
  50. data/lib/hashery/open_object.rb +0 -1
  51. data/lib/hashery/opencascade.rb +0 -1
  52. data/lib/hashery/openhash.rb +0 -1
  53. data/lib/hashery/openobject.rb +0 -1
  54. data/lib/hashery/orderedhash.rb +0 -1
  55. data/lib/hashery/ostructable.rb +0 -186
  56. data/lib/hashery/propertyhash.rb +0 -1
  57. data/lib/hashery/queryhash.rb +0 -1
  58. data/lib/hashery/statichash.rb +0 -1
  59. data/qed/01_openhash.rdoc +0 -57
  60. data/qed/02_queryhash.rdoc +0 -21
  61. data/qed/03_castinghash.rdoc +0 -13
  62. data/qed/04_statichash.rdoc +0 -22
  63. data/qed/05_association.rdoc +0 -59
  64. data/qed/06_opencascade.rdoc +0 -58
  65. data/qed/07_fuzzyhash.rdoc +0 -141
  66. data/qed/08_properyhash.rdoc +0 -38
  67. data/qed/09_ostructable.rdoc +0 -56
  68. data/qed/applique/ae.rb +0 -1
  69. data/test/case_basicstruct.rb +0 -192
  70. data/test/case_openhash.rb +0 -22
@@ -1,273 +1,363 @@
1
1
  require 'enumerator'
2
2
 
3
- # Hash with LRU expiry policy. There are at most max_size elements in a
4
- # LRUHash. When adding more elements old elements are removed according
5
- # to LRU policy.
6
- #
7
- # http://github.com/rklemme/muppet-laboratories/blob/master/lib/lruhash.rb
8
- # Copyright (c) 2010 Robert Klemme
3
+ module Hashery
9
4
 
10
- class LRUHash
11
-
12
- include Enumerable
13
-
14
- attr_reader :max_size
15
-
16
- attr_accessor :default
17
- attr_accessor :default_proc
18
- attr_accessor :release_proc
19
-
20
- def initialize(max_size, default_value = nil, &block)
21
- @max_size = normalize_max(max_size)
22
- @default = default_value
23
- @default_proc = block
24
-
25
- @h = {}
26
- @head = Node.new
27
- @tail = front(Node.new)
28
- end
5
+ # Hash with LRU expiry policy. There are at most max_size elements in a
6
+ # LRUHash. When adding more elements old elements are removed according
7
+ # to LRU policy.
8
+ #
9
+ # Based on Robert Klemme's LRUHash class.
10
+ #
11
+ # LRUHash, Copyright (c) 2010 Robert Klemme.
12
+ #
13
+ class LRUHash
14
+
15
+ include Enumerable
16
+
17
+ attr_reader :max_size
18
+
19
+ attr_accessor :default
20
+ attr_accessor :default_proc
21
+ attr_accessor :release_proc
22
+
23
+ #
24
+ # Initialize new LRUHash instance.
25
+ #
26
+ # max_size -
27
+ # default_value -
28
+ # block -
29
+ #
30
+ def initialize(max_size, default_value=nil, &block)
31
+ @max_size = normalize_max(max_size)
32
+ @default = default_value
33
+ @default_proc = block
34
+
35
+ @h = {}
36
+ @head = Node.new
37
+ @tail = front(Node.new)
38
+ end
29
39
 
30
- def each_pair
31
- if block_given?
32
- each_node do |n|
33
- yield [n.key, n.value]
40
+ #
41
+ # Iterate over each pair.
42
+ #
43
+ def each_pair
44
+ if block_given?
45
+ each_node do |n|
46
+ yield [n.key, n.value]
47
+ end
48
+ else
49
+ enum_for :each_pair
34
50
  end
35
- else
36
- enum_for :each_pair
37
51
  end
38
- end
39
-
40
- alias each each_pair
41
52
 
42
- def each_key
43
- if block_given?
44
- each_node do |n|
45
- yield n.key
53
+ #
54
+ # Same as each pair.
55
+ #
56
+ alias each each_pair
57
+
58
+ #
59
+ # Iterate over each key.
60
+ #
61
+ def each_key
62
+ if block_given?
63
+ each_node do |n|
64
+ yield n.key
65
+ end
66
+ else
67
+ enum_for :each_key
46
68
  end
47
- else
48
- enum_for :each_key
49
69
  end
50
- end
51
70
 
52
- def each_value
53
- if block_given?
54
- each_node do |n|
55
- yield n.value
71
+ #
72
+ # Iterate over each value.
73
+ #
74
+ def each_value
75
+ if block_given?
76
+ each_node do |n|
77
+ yield n.value
78
+ end
79
+ else
80
+ enum_for :each_value
56
81
  end
57
- else
58
- enum_for :each_value
59
82
  end
60
- end
61
83
 
62
- def size
63
- @h.size
64
- end
84
+ #
85
+ # Size of the hash.
86
+ #
87
+ def size
88
+ @h.size
89
+ end
65
90
 
66
- def empty?
67
- @head.succ.equal? @tail
68
- end
91
+ #
92
+ #
93
+ #
94
+ def empty?
95
+ @head.succ.equal? @tail
96
+ end
69
97
 
70
- def fetch(key, &b)
71
- n = @h[key]
98
+ #
99
+ #
100
+ #
101
+ def fetch(key, &b)
102
+ n = @h[key]
72
103
 
73
- if n
74
- front(n).value
75
- else
76
- (b || FETCH)[key]
104
+ if n
105
+ front(n).value
106
+ else
107
+ (b || FETCH)[key]
108
+ end
77
109
  end
78
- end
79
110
 
80
- def [](key)
81
- fetch(key) do |k|
82
- @default_proc ? @default_proc[self, k] : default
111
+ #
112
+ #
113
+ #
114
+ def [](key)
115
+ fetch(key) do |k|
116
+ @default_proc ? @default_proc[self, k] : default
117
+ end
83
118
  end
84
- end
85
-
86
- def keys
87
- @h.keys
88
- end
89
-
90
- def values
91
- @h.map {|k,n| n.value}
92
- end
93
119
 
94
- def has_key?(key)
95
- @h.has_key? key
96
- end
120
+ #
121
+ #
122
+ #
123
+ def keys
124
+ @h.keys
125
+ end
97
126
 
98
- alias key? has_key?
99
- alias member? has_key?
100
- alias include? has_key?
127
+ #
128
+ #
129
+ #
130
+ def values
131
+ @h.map {|k,n| n.value}
132
+ end
101
133
 
102
- def has_value?(value)
103
- each_pair do |k, v|
104
- return true if value.eql? v
134
+ #
135
+ #
136
+ #
137
+ def has_key?(key)
138
+ @h.has_key? key
105
139
  end
106
140
 
107
- false
108
- end
141
+ alias key? has_key?
142
+ alias member? has_key?
143
+ alias include? has_key?
109
144
 
110
- alias value? has_value?
145
+ #
146
+ #
147
+ #
148
+ def has_value?(value)
149
+ each_pair do |k, v|
150
+ return true if value.eql? v
151
+ end
111
152
 
112
- def values_at(*key_list)
113
- key_list.map {|k| self[k]}
114
- end
153
+ false
154
+ end
115
155
 
116
- def assoc(key)
117
- n = @h[key]
156
+ alias value? has_value?
118
157
 
119
- if n
120
- front(n)
121
- [n.key, n.value]
158
+ def values_at(*key_list)
159
+ key_list.map {|k| self[k]}
122
160
  end
123
- end
124
161
 
125
- def rassoc(value)
126
- each_node do |n|
127
- if value.eql? n.value
162
+ #
163
+ #
164
+ #
165
+ def assoc(key)
166
+ n = @h[key]
167
+
168
+ if n
128
169
  front(n)
129
- return [n.key, n.value]
170
+ [n.key, n.value]
130
171
  end
131
172
  end
132
- nil
133
- end
134
173
 
135
- def key(value)
136
- pair = rassoc(value) and pair.first
137
- end
138
-
139
- def store(key, value)
140
- # same optimization as in Hash
141
- key = key.dup.freeze if String === key && !key.frozen?
174
+ #
175
+ #
176
+ #
177
+ def rassoc(value)
178
+ each_node do |n|
179
+ if value.eql? n.value
180
+ front(n)
181
+ return [n.key, n.value]
182
+ end
183
+ end
184
+ nil
185
+ end
142
186
 
143
- n = @h[key]
187
+ #
188
+ #
189
+ #
190
+ def key(value)
191
+ pair = rassoc(value) and pair.first
192
+ end
144
193
 
145
- unless n
146
- if size == max_size
147
- # reuse node to optimize memory usage
148
- n = delete_oldest
149
- n.key = key
150
- n.value = value
151
- else
152
- n = Node.new key, value
194
+ #
195
+ #
196
+ #
197
+ def store(key, value)
198
+ # same optimization as in Hash
199
+ key = key.dup.freeze if String === key && !key.frozen?
200
+
201
+ n = @h[key]
202
+
203
+ unless n
204
+ if size == max_size
205
+ # reuse node to optimize memory usage
206
+ n = delete_oldest
207
+ n.key = key
208
+ n.value = value
209
+ else
210
+ n = Node.new key, value
211
+ end
212
+
213
+ @h[key] = n
153
214
  end
154
215
 
155
- @h[key] = n
216
+ front(n).value = value
156
217
  end
157
218
 
158
- front(n).value = value
159
- end
160
-
161
- alias []= store
219
+ alias []= store
162
220
 
163
- def delete(key)
164
- n = @h[key] and remove_node(n).value
165
- end
221
+ #
222
+ #
223
+ #
224
+ def delete(key)
225
+ n = @h[key] and remove_node(n).value
226
+ end
166
227
 
167
- def delete_if
168
- each_node do |n|
169
- remove_node n if yield n.key, n.value
228
+ #
229
+ #
230
+ #
231
+ def delete_if
232
+ each_node do |n|
233
+ remove_node n if yield n.key, n.value
234
+ end
170
235
  end
171
- end
172
236
 
173
- def max_size=(limit)
174
- limit = normalize_max(limit)
237
+ #
238
+ #
239
+ #
240
+ def max_size=(limit)
241
+ limit = normalize_max(limit)
175
242
 
176
- while size > limit
177
- delete_oldest
243
+ while size > limit
244
+ delete_oldest
245
+ end
246
+
247
+ @max_size = limit
178
248
  end
179
249
 
180
- @max_size = limit
181
- end
250
+ #
251
+ #
252
+ #
253
+ def clear
254
+ until empty?
255
+ delete_oldest
256
+ end
182
257
 
183
- def clear
184
- until empty?
185
- delete_oldest
258
+ self
186
259
  end
187
260
 
188
- self
189
- end
190
-
191
- def to_s
192
- s = nil
193
- each_pair {|k, v| (s ? (s << ', ') : s = '{') << k.to_s << '=>' << v.to_s}
194
- s ? (s << '}') : '{}'
195
- end
261
+ #
262
+ #
263
+ #
264
+ def to_s
265
+ s = nil
266
+ each_pair {|k, v| (s ? (s << ', ') : s = '{') << k.to_s << '=>' << v.to_s}
267
+ s ? (s << '}') : '{}'
268
+ end
196
269
 
197
- alias inspect to_s
270
+ alias inspect to_s
198
271
 
199
272
  private
200
273
 
201
- # iterate nodes
202
- def each_node
203
- n = @head.succ
274
+ #
275
+ # Iterate nodes.
276
+ #
277
+ def each_node
278
+ n = @head.succ
279
+
280
+ until n.equal? @tail
281
+ succ = n.succ
282
+ yield n
283
+ n = succ
284
+ end
204
285
 
205
- until n.equal? @tail
206
- succ = n.succ
207
- yield n
208
- n = succ
286
+ self
209
287
  end
210
288
 
211
- self
212
- end
289
+ #
290
+ # Move node to front.
291
+ #
292
+ # node - [Node]
293
+ #
294
+ def front(node)
295
+ node.insert_after(@head)
296
+ end
213
297
 
214
- # move node to front
215
- def front(node)
216
- node.insert_after(@head)
217
- end
298
+ #
299
+ # Remove the node and invoke release_proc
300
+ # if set
301
+ #
302
+ # node - [Node]
303
+ #
304
+ def remove_node(node)
305
+ n = @h.delete(node.key)
306
+ n.unlink
307
+ release_proc and release_proc[n.key, n.value]
308
+ n
309
+ end
218
310
 
219
- # remove the node and invoke release_proc
220
- # if set
221
- def remove_node(node)
222
- n = @h.delete(node.key)
223
- n.unlink
224
- release_proc and release_proc[n.key, n.value]
225
- n
226
- end
311
+ #
312
+ # Remove the oldest node returning the node
313
+ #
314
+ def delete_oldest
315
+ n = @tail.pred
316
+ raise "Cannot delete from empty hash" if @head.equal? n
317
+ remove_node n
318
+ end
227
319
 
228
- # remove the oldest node returning the node
229
- def delete_oldest
230
- n = @tail.pred
231
- raise "Cannot delete from empty hash" if @head.equal? n
232
- remove_node n
233
- end
320
+ #
321
+ # Normalize the argument in order to be usable as max_size
322
+ # criterion is that n.to_i must be an Integer and it must
323
+ # be larger than zero.
324
+ #
325
+ # n - [#to_i] max size
326
+ #
327
+ def normalize_max(n)
328
+ n = n.to_i
329
+ raise ArgumentError, 'Invalid max_size: %p' % n unless Integer === n && n > 0
330
+ n
331
+ end
234
332
 
235
- # Normalize the argument in order to be usable as max_size
236
- # criterion is that n.to_i must be an Integer and it must
237
- # be larger than zero.
238
- def normalize_max(n)
239
- n = n.to_i
240
- raise ArgumentError, 'Invalid max_size: %p' % n unless Integer === n && n > 0
241
- n
242
- end
333
+ #
334
+ FETCH = Proc.new {|k| raise KeyError, 'key not found'}
243
335
 
244
- #
245
- FETCH = Proc.new {|k| raise KeyError, 'key not found'}
246
-
247
- # A single node in the doubly linked LRU list of nodes
248
- Node = Struct.new :key, :value, :pred, :succ do
249
- def unlink
250
- pred.succ = succ if pred
251
- succ.pred = pred if succ
252
- self.succ = self.pred = nil
253
- self
254
- end
336
+ # A single node in the doubly linked LRU list of nodes.
337
+ Node = Struct.new :key, :value, :pred, :succ do
338
+ def unlink
339
+ pred.succ = succ if pred
340
+ succ.pred = pred if succ
341
+ self.succ = self.pred = nil
342
+ self
343
+ end
255
344
 
256
- def insert_after(node)
257
- raise 'Cannot insert after self' if equal? node
258
- return self if node.succ.equal? self
345
+ def insert_after(node)
346
+ raise 'Cannot insert after self' if equal? node
347
+ return self if node.succ.equal? self
259
348
 
260
- unlink
349
+ unlink
261
350
 
262
- self.succ = node.succ
263
- self.pred = node
351
+ self.succ = node.succ
352
+ self.pred = node
264
353
 
265
- node.succ.pred = self if node.succ
266
- node.succ = self
354
+ node.succ.pred = self if node.succ
355
+ node.succ = self
267
356
 
268
- self
357
+ self
358
+ end
269
359
  end
360
+
270
361
  end
271
362
 
272
363
  end
273
-