hashery 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.ruby +57 -92
  2. data/.yardopts +8 -0
  3. data/COPYING.rdoc +45 -0
  4. data/HISTORY.rdoc +18 -0
  5. data/QED.rdoc +1 -0
  6. data/README.rdoc +42 -16
  7. data/lib/hashery.rb +16 -9
  8. data/lib/hashery.yml +57 -92
  9. data/lib/hashery/association.rb +3 -1
  10. data/lib/hashery/basic_object.rb +74 -0
  11. data/lib/hashery/basic_struct.rb +288 -1
  12. data/lib/hashery/basicobject.rb +1 -74
  13. data/lib/hashery/basicstruct.rb +1 -280
  14. data/lib/hashery/casting_hash.rb +171 -1
  15. data/lib/hashery/castinghash.rb +1 -171
  16. data/lib/hashery/core_ext.rb +82 -0
  17. data/lib/hashery/dictionary.rb +3 -0
  18. data/lib/hashery/fuzzy_hash.rb +154 -1
  19. data/lib/hashery/fuzzyhash.rb +1 -154
  20. data/lib/hashery/ini.rb +3 -2
  21. data/lib/hashery/key_hash.rb +186 -0
  22. data/lib/hashery/keyhash.rb +1 -0
  23. data/lib/hashery/linked_list.rb +195 -1
  24. data/lib/hashery/linkedlist.rb +1 -195
  25. data/lib/hashery/lru_hash.rb +273 -1
  26. data/lib/hashery/lruhash.rb +1 -273
  27. data/lib/hashery/open_cascade.rb +99 -1
  28. data/lib/hashery/open_hash.rb +77 -1
  29. data/lib/hashery/opencascade.rb +1 -99
  30. data/lib/hashery/openhash.rb +1 -77
  31. data/lib/hashery/ordered_hash.rb +168 -1
  32. data/lib/hashery/orderedhash.rb +1 -167
  33. data/lib/hashery/property_hash.rb +97 -1
  34. data/lib/hashery/propertyhash.rb +1 -97
  35. data/lib/hashery/query_hash.rb +35 -1
  36. data/lib/hashery/queryhash.rb +1 -35
  37. data/lib/hashery/stash.rb +3 -174
  38. data/lib/hashery/static_hash.rb +48 -1
  39. data/lib/hashery/statichash.rb +1 -48
  40. data/qed/06_opencascade.rdoc +12 -12
  41. data/test/case_association.rb +29 -15
  42. data/test/case_basicstruct.rb +192 -0
  43. data/test/case_dictionary.rb +149 -109
  44. data/test/case_keyhash.rb +175 -0
  45. data/test/case_opencascade.rb +89 -43
  46. data/test/case_openhash.rb +15 -11
  47. metadata +85 -78
  48. data/LICENSE +0 -206
  49. data/NOTICE +0 -11
  50. data/lib/hashery/sparse_array.rb +0 -1
  51. data/lib/hashery/sparsearray.rb +0 -577
  52. data/test/case_openobject.rb +0 -130
  53. data/test/case_sparsearray.rb +0 -316
  54. data/test/case_stash.rb +0 -131
@@ -1 +1,273 @@
1
- require 'hashery/lruhash'
1
+ require 'enumerator'
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
9
+
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
29
+
30
+ def each_pair
31
+ if block_given?
32
+ each_node do |n|
33
+ yield [n.key, n.value]
34
+ end
35
+ else
36
+ enum_for :each_pair
37
+ end
38
+ end
39
+
40
+ alias each each_pair
41
+
42
+ def each_key
43
+ if block_given?
44
+ each_node do |n|
45
+ yield n.key
46
+ end
47
+ else
48
+ enum_for :each_key
49
+ end
50
+ end
51
+
52
+ def each_value
53
+ if block_given?
54
+ each_node do |n|
55
+ yield n.value
56
+ end
57
+ else
58
+ enum_for :each_value
59
+ end
60
+ end
61
+
62
+ def size
63
+ @h.size
64
+ end
65
+
66
+ def empty?
67
+ @head.succ.equal? @tail
68
+ end
69
+
70
+ def fetch(key, &b)
71
+ n = @h[key]
72
+
73
+ if n
74
+ front(n).value
75
+ else
76
+ (b || FETCH)[key]
77
+ end
78
+ end
79
+
80
+ def [](key)
81
+ fetch(key) do |k|
82
+ @default_proc ? @default_proc[self, k] : default
83
+ 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
+
94
+ def has_key?(key)
95
+ @h.has_key? key
96
+ end
97
+
98
+ alias key? has_key?
99
+ alias member? has_key?
100
+ alias include? has_key?
101
+
102
+ def has_value?(value)
103
+ each_pair do |k, v|
104
+ return true if value.eql? v
105
+ end
106
+
107
+ false
108
+ end
109
+
110
+ alias value? has_value?
111
+
112
+ def values_at(*key_list)
113
+ key_list.map {|k| self[k]}
114
+ end
115
+
116
+ def assoc(key)
117
+ n = @h[key]
118
+
119
+ if n
120
+ front(n)
121
+ [n.key, n.value]
122
+ end
123
+ end
124
+
125
+ def rassoc(value)
126
+ each_node do |n|
127
+ if value.eql? n.value
128
+ front(n)
129
+ return [n.key, n.value]
130
+ end
131
+ end
132
+ nil
133
+ end
134
+
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?
142
+
143
+ n = @h[key]
144
+
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
153
+ end
154
+
155
+ @h[key] = n
156
+ end
157
+
158
+ front(n).value = value
159
+ end
160
+
161
+ alias []= store
162
+
163
+ def delete(key)
164
+ n = @h[key] and remove_node(n).value
165
+ end
166
+
167
+ def delete_if
168
+ each_node do |n|
169
+ remove_node n if yield n.key, n.value
170
+ end
171
+ end
172
+
173
+ def max_size=(limit)
174
+ limit = normalize_max(limit)
175
+
176
+ while size > limit
177
+ delete_oldest
178
+ end
179
+
180
+ @max_size = limit
181
+ end
182
+
183
+ def clear
184
+ until empty?
185
+ delete_oldest
186
+ end
187
+
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
196
+
197
+ alias inspect to_s
198
+
199
+ private
200
+
201
+ # iterate nodes
202
+ def each_node
203
+ n = @head.succ
204
+
205
+ until n.equal? @tail
206
+ succ = n.succ
207
+ yield n
208
+ n = succ
209
+ end
210
+
211
+ self
212
+ end
213
+
214
+ # move node to front
215
+ def front(node)
216
+ node.insert_after(@head)
217
+ end
218
+
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
227
+
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
234
+
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
243
+
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
255
+
256
+ def insert_after(node)
257
+ raise 'Cannot insert after self' if equal? node
258
+ return self if node.succ.equal? self
259
+
260
+ unlink
261
+
262
+ self.succ = node.succ
263
+ self.pred = node
264
+
265
+ node.succ.pred = self if node.succ
266
+ node.succ = self
267
+
268
+ self
269
+ end
270
+ end
271
+
272
+ end
273
+
@@ -1,273 +1 @@
1
- require 'enumerator'
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
9
-
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
29
-
30
- def each_pair
31
- if block_given?
32
- each_node do |n|
33
- yield [n.key, n.value]
34
- end
35
- else
36
- enum_for :each_pair
37
- end
38
- end
39
-
40
- alias each each_pair
41
-
42
- def each_key
43
- if block_given?
44
- each_node do |n|
45
- yield n.key
46
- end
47
- else
48
- enum_for :each_key
49
- end
50
- end
51
-
52
- def each_value
53
- if block_given?
54
- each_node do |n|
55
- yield n.value
56
- end
57
- else
58
- enum_for :each_value
59
- end
60
- end
61
-
62
- def size
63
- @h.size
64
- end
65
-
66
- def empty?
67
- @head.succ.equal? @tail
68
- end
69
-
70
- def fetch(key, &b)
71
- n = @h[key]
72
-
73
- if n
74
- front(n).value
75
- else
76
- (b || FETCH)[key]
77
- end
78
- end
79
-
80
- def [](key)
81
- fetch(key) do |k|
82
- @default_proc ? @default_proc[self, k] : default
83
- 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
-
94
- def has_key?(key)
95
- @h.has_key? key
96
- end
97
-
98
- alias key? has_key?
99
- alias member? has_key?
100
- alias include? has_key?
101
-
102
- def has_value?(value)
103
- each_pair do |k, v|
104
- return true if value.eql? v
105
- end
106
-
107
- false
108
- end
109
-
110
- alias value? has_value?
111
-
112
- def values_at(*key_list)
113
- key_list.map {|k| self[k]}
114
- end
115
-
116
- def assoc(key)
117
- n = @h[key]
118
-
119
- if n
120
- front(n)
121
- [n.key, n.value]
122
- end
123
- end
124
-
125
- def rassoc(value)
126
- each_node do |n|
127
- if value.eql? n.value
128
- front(n)
129
- return [n.key, n.value]
130
- end
131
- end
132
- nil
133
- end
134
-
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?
142
-
143
- n = @h[key]
144
-
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
153
- end
154
-
155
- @h[key] = n
156
- end
157
-
158
- front(n).value = value
159
- end
160
-
161
- alias []= store
162
-
163
- def delete(key)
164
- n = @h[key] and remove_node(n).value
165
- end
166
-
167
- def delete_if
168
- each_node do |n|
169
- remove_node n if yield n.key, n.value
170
- end
171
- end
172
-
173
- def max_size=(limit)
174
- limit = normalize_max(limit)
175
-
176
- while size > limit
177
- delete_oldest
178
- end
179
-
180
- @max_size = limit
181
- end
182
-
183
- def clear
184
- until empty?
185
- delete_oldest
186
- end
187
-
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
196
-
197
- alias inspect to_s
198
-
199
- private
200
-
201
- # iterate nodes
202
- def each_node
203
- n = @head.succ
204
-
205
- until n.equal? @tail
206
- succ = n.succ
207
- yield n
208
- n = succ
209
- end
210
-
211
- self
212
- end
213
-
214
- # move node to front
215
- def front(node)
216
- node.insert_after(@head)
217
- end
218
-
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
227
-
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
234
-
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
243
-
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
255
-
256
- def insert_after(node)
257
- raise 'Cannot insert after self' if equal? node
258
- return self if node.succ.equal? self
259
-
260
- unlink
261
-
262
- self.succ = node.succ
263
- self.pred = node
264
-
265
- node.succ.pred = self if node.succ
266
- node.succ = self
267
-
268
- self
269
- end
270
- end
271
-
272
- end
273
-
1
+ require 'hashery/lru_hash'