perobs 4.5.0 → 4.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +38 -0
- data/.gitignore +0 -1
- data/Gemfile +1 -0
- data/lib/perobs/Array.rb +25 -30
- data/lib/perobs/BigArray.rb +16 -29
- data/lib/perobs/BigArrayNode.rb +82 -96
- data/lib/perobs/BigHash.rb +14 -24
- data/lib/perobs/BigTree.rb +7 -17
- data/lib/perobs/BigTreeNode.rb +101 -122
- data/lib/perobs/ClassMap.rb +6 -0
- data/lib/perobs/DataBase.rb +19 -14
- data/lib/perobs/IDList.rb +2 -2
- data/lib/perobs/Store.rb +1 -1
- data/lib/perobs/version.rb +1 -1
- data/perobs.gemspec +3 -2
- data/test/Array_spec.rb +55 -59
- data/test/BTreeDB_spec.rb +5 -1
- data/test/BigTreeNode_spec.rb +5 -8
- data/test/LegacyDBs/version_4.1/class_map.json +1 -0
- data/test/LegacyDBs/version_4.1/config.json +1 -0
- data/test/LegacyDBs/version_4.1/database.blobs +0 -0
- data/test/LegacyDBs/version_4.1/database_spaces.blobs +0 -0
- data/test/LegacyDBs/version_4.1/index.blobs +0 -0
- data/test/LegacyDBs/version_4.1/log +5 -0
- data/test/LegacyDBs/version_4.1/version +1 -0
- data/test/spec_helper.rb +1 -1
- metadata +38 -9
data/lib/perobs/BigArrayNode.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# # frozen_string_literal: true
|
2
2
|
#
|
3
3
|
# = BigArrayNode.rb -- Persistent Ruby Object Store
|
4
4
|
#
|
@@ -26,11 +26,10 @@
|
|
26
26
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
27
27
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
require_relative 'Object'
|
30
|
+
require_relative 'Array'
|
31
31
|
|
32
32
|
module PEROBS
|
33
|
-
|
34
33
|
# The BigArrayNode class provides the BTree nodes for the BigArray objects.
|
35
34
|
# A node can either be a branch node or a leaf node. Branch nodes don't
|
36
35
|
# store values, only offsets and references to child nodes. Leaf nodes don't
|
@@ -57,9 +56,8 @@ module PEROBS
|
|
57
56
|
# Index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
58
57
|
#
|
59
58
|
class BigArrayNode < PEROBS::Object
|
60
|
-
|
61
59
|
attr_persist :tree, :parent, :offsets, :values, :children,
|
62
|
-
|
60
|
+
:prev_sibling, :next_sibling
|
63
61
|
|
64
62
|
# Internal constructor. Use Store.new(BigArrayNode, ...) instead.
|
65
63
|
# @param p [Handle]
|
@@ -118,16 +116,13 @@ module PEROBS
|
|
118
116
|
count = 0
|
119
117
|
node = self
|
120
118
|
while node
|
121
|
-
if node.is_leaf?
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
node = node.children.last
|
126
|
-
end
|
119
|
+
return count + node.values.size if node.is_leaf?
|
120
|
+
|
121
|
+
count += node.offsets.last
|
122
|
+
node = node.children.last
|
127
123
|
end
|
128
124
|
end
|
129
125
|
|
130
|
-
|
131
126
|
# Set the given value at the given index.
|
132
127
|
# @param index [Integer] Position to insert at
|
133
128
|
# @param value [Integer] value to insert
|
@@ -136,28 +131,28 @@ module PEROBS
|
|
136
131
|
|
137
132
|
# Traverse the tree to find the right node to add or replace the value.
|
138
133
|
idx = index
|
139
|
-
while node
|
134
|
+
while node
|
140
135
|
# Once we have reached a leaf node we can insert or replace the value.
|
141
136
|
if node.is_leaf?
|
142
137
|
if idx >= node.values.size
|
143
|
-
node.fatal "Set index (#{index}) larger than values array "
|
144
|
-
|
138
|
+
node.fatal "Set index (#{index}) larger than values array " \
|
139
|
+
"(#{idx} >= #{node.values.size})."
|
145
140
|
end
|
146
141
|
node.values[idx] = value
|
147
142
|
return
|
148
143
|
else
|
149
144
|
# Descend into the right child node to add the value to.
|
150
145
|
cidx = node.search_child_index(idx)
|
151
|
-
if (idx -= node.offsets[cidx])
|
152
|
-
node.fatal "Idx (#{idx}) became negative while looking for "
|
153
|
-
|
146
|
+
if (idx -= node.offsets[cidx]).negative?
|
147
|
+
node.fatal "Idx (#{idx}) became negative while looking for " \
|
148
|
+
"index #{index}."
|
154
149
|
end
|
155
150
|
node = node.children[cidx]
|
156
151
|
end
|
157
152
|
end
|
158
153
|
|
159
|
-
node.fatal
|
160
|
-
|
154
|
+
node.fatal 'Could not find proper node to set the value while ' \
|
155
|
+
"looking for index #{index}."
|
161
156
|
end
|
162
157
|
|
163
158
|
# Insert the given value at the given index. All following values will be
|
@@ -169,7 +164,7 @@ module PEROBS
|
|
169
164
|
cidx = nil
|
170
165
|
|
171
166
|
# Traverse the tree to find the right node to add or replace the value.
|
172
|
-
while node
|
167
|
+
while node
|
173
168
|
# All nodes that we find on the way that are full will be split into
|
174
169
|
# two half-full nodes.
|
175
170
|
if node.size >= @tree.node_size
|
@@ -182,20 +177,20 @@ module PEROBS
|
|
182
177
|
# Once we have reached a leaf node we can insert or replace the value.
|
183
178
|
if node.is_leaf?
|
184
179
|
node.values.insert(index, value)
|
185
|
-
node.parent
|
180
|
+
node.parent&.adjust_offsets(node, 1)
|
186
181
|
return
|
187
182
|
else
|
188
183
|
# Descend into the right child node to add the value to.
|
189
184
|
cidx = node.search_child_index(index)
|
190
|
-
if (index -= node.offsets[cidx])
|
185
|
+
if (index -= node.offsets[cidx]).negative?
|
191
186
|
node.fatal "Index (#{index}) became negative"
|
192
187
|
end
|
193
188
|
node = node.children[cidx]
|
194
189
|
end
|
195
190
|
end
|
196
191
|
|
197
|
-
node.fatal
|
198
|
-
|
192
|
+
node.fatal 'Could not find proper node to insert the value while ' \
|
193
|
+
"looking for index #{index}"
|
199
194
|
end
|
200
195
|
|
201
196
|
# Return the value that matches the given key or return nil if they key is
|
@@ -206,23 +201,21 @@ module PEROBS
|
|
206
201
|
node = self
|
207
202
|
|
208
203
|
# Traverse the tree to find the right node to add or replace the value.
|
209
|
-
while node
|
204
|
+
while node
|
210
205
|
# Once we have reached a leaf node we can insert or replace the value.
|
211
|
-
if node.is_leaf?
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
node.fatal "Index (#{index}) became negative"
|
219
|
-
end
|
220
|
-
node = node.children[cidx]
|
206
|
+
return node.values[index] if node.is_leaf?
|
207
|
+
|
208
|
+
# Descend into the right child node to add the value to.
|
209
|
+
cidx = (node.offsets.bsearch_index { |o| o > index } ||
|
210
|
+
node.offsets.length) - 1
|
211
|
+
if (index -= node.offsets[cidx]).negative?
|
212
|
+
node.fatal "Index (#{index}) became negative"
|
221
213
|
end
|
214
|
+
node = node.children[cidx]
|
222
215
|
end
|
223
216
|
|
224
|
-
PEROBS.log.fatal
|
225
|
-
|
217
|
+
PEROBS.log.fatal 'Could not find proper node to get from while ' \
|
218
|
+
"looking for index #{index}"
|
226
219
|
end
|
227
220
|
|
228
221
|
# Delete the element at the specified index, returning that element, or
|
@@ -233,14 +226,12 @@ module PEROBS
|
|
233
226
|
node = self
|
234
227
|
deleted_value = nil
|
235
228
|
|
236
|
-
while node
|
229
|
+
while node
|
237
230
|
if node.is_leaf?
|
238
231
|
deleted_value = node.values.delete_at(index)
|
239
232
|
if node.parent
|
240
233
|
node.parent.adjust_offsets(node, -1)
|
241
|
-
if node.size < min_size
|
242
|
-
node.parent.consolidate_child_nodes(node)
|
243
|
-
end
|
234
|
+
node.parent.consolidate_child_nodes(node) if node.size < min_size
|
244
235
|
end
|
245
236
|
|
246
237
|
return deleted_value
|
@@ -248,15 +239,15 @@ module PEROBS
|
|
248
239
|
# Descend into the right child node to add the value to.
|
249
240
|
cidx = (node.offsets.bsearch_index { |o| o > index } ||
|
250
241
|
node.offsets.length) - 1
|
251
|
-
if (index -= node.offsets[cidx])
|
242
|
+
if (index -= node.offsets[cidx]).negative?
|
252
243
|
node.fatal "Index (#{index}) became negative"
|
253
244
|
end
|
254
245
|
node = node.children[cidx]
|
255
246
|
end
|
256
247
|
end
|
257
248
|
|
258
|
-
PEROBS.log.fatal
|
259
|
-
|
249
|
+
PEROBS.log.fatal 'Could not find proper node to delete from while ' \
|
250
|
+
"looking for index #{index}"
|
260
251
|
end
|
261
252
|
|
262
253
|
# Iterate over all the values of the node.
|
@@ -287,13 +278,13 @@ module PEROBS
|
|
287
278
|
branch_depth = nil
|
288
279
|
|
289
280
|
traverse do |node, position, stack|
|
290
|
-
if position
|
281
|
+
if position.zero?
|
291
282
|
# Nodes should have between min_size() and
|
292
283
|
# @tree.node_size children or values. Only the root node may have
|
293
284
|
# less.
|
294
285
|
if node.size > @tree.node_size
|
295
|
-
node.error "BigArray node #{node._id} is too large. It has "
|
296
|
-
|
286
|
+
node.error "BigArray node #{node._id} is too large. It has " \
|
287
|
+
"#{node.size} nodes instead of max. #{@tree.node_size}."
|
297
288
|
return false
|
298
289
|
end
|
299
290
|
if node.parent && node.size < min_size
|
@@ -305,7 +296,7 @@ module PEROBS
|
|
305
296
|
# All leaf nodes must have same distance from root node.
|
306
297
|
if branch_depth
|
307
298
|
unless branch_depth == stack.size
|
308
|
-
node.error
|
299
|
+
node.error 'All leaf nodes must have same distance from root'
|
309
300
|
return false
|
310
301
|
end
|
311
302
|
else
|
@@ -315,24 +306,24 @@ module PEROBS
|
|
315
306
|
return false unless node.check_leaf_node_links
|
316
307
|
|
317
308
|
if node.children
|
318
|
-
node.error
|
309
|
+
node.error 'children must be nil for a leaf node'
|
319
310
|
return false
|
320
311
|
end
|
321
312
|
else
|
322
313
|
unless node.children.size == node.offsets.size
|
323
|
-
node.error "Offset count (#{node.offsets.size}) must be equal "
|
324
|
-
|
325
|
-
|
314
|
+
node.error "Offset count (#{node.offsets.size}) must be equal " \
|
315
|
+
"to children count (#{node.children.size})"
|
316
|
+
return false
|
326
317
|
end
|
327
318
|
|
328
319
|
if node.values
|
329
|
-
node.error
|
320
|
+
node.error 'values must be nil for a branch node'
|
330
321
|
return false
|
331
322
|
end
|
332
323
|
|
333
324
|
unless @prev_sibling.nil? && @next_sibling.nil?
|
334
|
-
node.error
|
335
|
-
|
325
|
+
node.error 'prev_sibling and next_sibling must be nil for ' \
|
326
|
+
'branch nodes'
|
336
327
|
end
|
337
328
|
|
338
329
|
return false unless node.check_offsets
|
@@ -343,12 +334,10 @@ module PEROBS
|
|
343
334
|
# These checks are done after we have completed the respective child
|
344
335
|
# node with index 'position - 1'.
|
345
336
|
index = position - 1
|
346
|
-
if node.is_leaf?
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
node.values[index])
|
351
|
-
end
|
337
|
+
if node.is_leaf? && block_given?
|
338
|
+
# If a block was given, call this block with the key and value.
|
339
|
+
return false unless yield(node.first_index + index,
|
340
|
+
node.values[index])
|
352
341
|
end
|
353
342
|
end
|
354
343
|
end
|
@@ -359,25 +348,25 @@ module PEROBS
|
|
359
348
|
def check_leaf_node_links
|
360
349
|
if @prev_sibling.nil?
|
361
350
|
if @tree.first_leaf != self
|
362
|
-
error "Leaf node #{@_id} has no previous sibling "
|
363
|
-
|
351
|
+
error "Leaf node #{@_id} has no previous sibling " \
|
352
|
+
'but is not the first leaf of the tree'
|
364
353
|
return false
|
365
354
|
end
|
366
355
|
elsif @prev_sibling.next_sibling != self
|
367
|
-
error
|
368
|
-
|
356
|
+
error 'next_sibling of previous sibling does not point to ' \
|
357
|
+
'this node'
|
369
358
|
return false
|
370
359
|
end
|
371
360
|
|
372
361
|
if @next_sibling.nil?
|
373
362
|
if @tree.last_leaf != self
|
374
|
-
error "Leaf node #{@_id} has no next sibling "
|
375
|
-
|
363
|
+
error "Leaf node #{@_id} has no next sibling " \
|
364
|
+
'but is not the last leaf of the tree'
|
376
365
|
return false
|
377
366
|
end
|
378
367
|
elsif @next_sibling.prev_sibling != self
|
379
|
-
error
|
380
|
-
|
368
|
+
error 'previous_sibling of next sibling does not point to ' \
|
369
|
+
'this node'
|
381
370
|
return false
|
382
371
|
end
|
383
372
|
|
@@ -394,16 +383,16 @@ module PEROBS
|
|
394
383
|
|
395
384
|
last_offset = nil
|
396
385
|
@offsets.each_with_index do |offset, i|
|
397
|
-
if i
|
386
|
+
if i.positive?
|
398
387
|
if offset < last_offset
|
399
|
-
error
|
400
|
-
|
388
|
+
error 'Offsets are not strictly monotoneously ' \
|
389
|
+
"increasing: #{@offsets.inspect}"
|
401
390
|
return false
|
402
391
|
end
|
403
392
|
expected_offset = last_offset + @children[i - 1].values_count
|
404
393
|
if offset != expected_offset
|
405
|
-
error "Offset #{i} must be #{expected_offset} "
|
406
|
-
|
394
|
+
error "Offset #{i} must be #{expected_offset} " \
|
395
|
+
"but is #{offset}."
|
407
396
|
return false
|
408
397
|
end
|
409
398
|
end
|
@@ -422,20 +411,20 @@ module PEROBS
|
|
422
411
|
|
423
412
|
@children.each_with_index do |child, i|
|
424
413
|
unless child.is_a?(BigArrayNode)
|
425
|
-
error "Child #{@_id} is of class #{child.class} "
|
426
|
-
|
414
|
+
error "Child #{@_id} is of class #{child.class} " \
|
415
|
+
'instead of BigArrayNode'
|
427
416
|
return false
|
428
417
|
end
|
429
418
|
|
430
419
|
unless child.parent.is_a?(BigArrayNode)
|
431
|
-
error "Parent reference of child #{i} is of class "
|
432
|
-
|
420
|
+
error "Parent reference of child #{i} is of class " \
|
421
|
+
"#{child.class} instead of BigArrayNode"
|
433
422
|
return false
|
434
423
|
end
|
435
424
|
|
436
425
|
if child.parent != self
|
437
|
-
error "Child node #{child._id} has wrong parent "
|
438
|
-
|
426
|
+
error "Child node #{child._id} has wrong parent " \
|
427
|
+
"#{child.parent._id}. It should be #{@_id}."
|
439
428
|
return false
|
440
429
|
end
|
441
430
|
|
@@ -450,8 +439,8 @@ module PEROBS
|
|
450
439
|
end
|
451
440
|
|
452
441
|
unless child.parent == self
|
453
|
-
error "Child #{i} does not have parent pointing "
|
454
|
-
|
442
|
+
error "Child #{i} does not have parent pointing " \
|
443
|
+
'to this node'
|
455
444
|
return false
|
456
445
|
end
|
457
446
|
end
|
@@ -464,11 +453,11 @@ module PEROBS
|
|
464
453
|
str = ''
|
465
454
|
|
466
455
|
traverse do |node, position, stack|
|
467
|
-
if position
|
456
|
+
if position.zero?
|
468
457
|
begin
|
469
|
-
str += "#{node.parent ? node.parent.tree_prefix + ' +' : 'o'}"
|
470
|
-
|
471
|
-
|
458
|
+
str += "#{node.parent ? node.parent.tree_prefix + ' +' : 'o'}" \
|
459
|
+
"#{node.tree_branch_mark}-" \
|
460
|
+
"#{node.empty? ? '--' : 'v-'}#{node.tree_summary}\n"
|
472
461
|
rescue => e
|
473
462
|
str += "@@@@@@@@@@: #{e.message}\n"
|
474
463
|
end
|
@@ -476,11 +465,11 @@ module PEROBS
|
|
476
465
|
begin
|
477
466
|
if node.is_leaf?
|
478
467
|
if position <= node.size
|
479
|
-
str += "#{node.tree_prefix} "
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
468
|
+
str += "#{node.tree_prefix} " \
|
469
|
+
"#{position == node.size ? '-' : '|'} " \
|
470
|
+
"[ #{node.value_index(position - 1)}: " \
|
471
|
+
"#{node.values[position - 1].nil? ?
|
472
|
+
'nil' : node.values[position - 1]} ]\n"
|
484
473
|
end
|
485
474
|
end
|
486
475
|
rescue => e
|
@@ -997,8 +986,5 @@ module PEROBS
|
|
997
986
|
@parent.consolidate_child_nodes(self)
|
998
987
|
end
|
999
988
|
end
|
1000
|
-
|
1001
989
|
end
|
1002
|
-
|
1003
990
|
end
|
1004
|
-
|
data/lib/perobs/BigHash.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# # frozen_string_literal: true
|
2
2
|
#
|
3
3
|
# = BigHash.rb -- Persistent Ruby Object Store
|
4
4
|
#
|
@@ -31,7 +31,6 @@ require 'perobs/Array'
|
|
31
31
|
require 'perobs/FNV_Hash_1a_64'
|
32
32
|
|
33
33
|
module PEROBS
|
34
|
-
|
35
34
|
# The BigHash is similar to the Hash object in that it provides a simple
|
36
35
|
# hash functionality. The difference is that this class scales to much
|
37
36
|
# larger data sets essentially limited to the amount of space available on
|
@@ -40,7 +39,6 @@ module PEROBS
|
|
40
39
|
# subset of the methods provided by the native Hash class that make sense
|
41
40
|
# for giant data sets.
|
42
41
|
class BigHash < PEROBS::Object
|
43
|
-
|
44
42
|
# Internally this class uses BigTree to store the values by the hashed
|
45
43
|
# key. We are using a 64 bit hash space so collisions are fairly unlikely
|
46
44
|
# but not impossible. Therefor we have to store the originial key with the
|
@@ -52,7 +50,6 @@ module PEROBS
|
|
52
50
|
# hashed key in a Collisions object instead of storing the Entry
|
53
51
|
# directly in the BigTree.
|
54
52
|
class Entry < PEROBS::Object
|
55
|
-
|
56
53
|
attr_persist :key, :value
|
57
54
|
|
58
55
|
def initialize(p, key, value)
|
@@ -60,7 +57,6 @@ module PEROBS
|
|
60
57
|
self.key = key
|
61
58
|
self.value = value
|
62
59
|
end
|
63
|
-
|
64
60
|
end
|
65
61
|
|
66
62
|
# Since the BigHash can also store PEROBS::Array values we need to
|
@@ -78,8 +74,7 @@ module PEROBS
|
|
78
74
|
self.btree = @store.new(PEROBS::BigTree)
|
79
75
|
end
|
80
76
|
|
81
|
-
def restore
|
82
|
-
end
|
77
|
+
def restore; end
|
83
78
|
|
84
79
|
# Insert a value that is associated with the given key. If a value for
|
85
80
|
# this key already exists, the value will be overwritten with the newly
|
@@ -139,8 +134,8 @@ module PEROBS
|
|
139
134
|
entry.each do |ae|
|
140
135
|
return ae.value if ae.key == key
|
141
136
|
end
|
142
|
-
|
143
|
-
return entry.value
|
137
|
+
elsif entry.key == key
|
138
|
+
return entry.value
|
144
139
|
end
|
145
140
|
|
146
141
|
nil
|
@@ -159,8 +154,8 @@ module PEROBS
|
|
159
154
|
entry.each do |ae|
|
160
155
|
return true if ae.key == key
|
161
156
|
end
|
162
|
-
|
163
|
-
return true
|
157
|
+
elsif entry.key == key
|
158
|
+
return true
|
164
159
|
end
|
165
160
|
|
166
161
|
false
|
@@ -180,12 +175,10 @@ module PEROBS
|
|
180
175
|
|
181
176
|
if entry.is_a?(PEROBS::Array)
|
182
177
|
entry.each_with_index do |ae, i|
|
183
|
-
if ae.key == key
|
184
|
-
return entry.delete_at(i).value
|
185
|
-
end
|
178
|
+
return entry.delete_at(i).value if ae.key == key
|
186
179
|
end
|
187
|
-
|
188
|
-
return entry.value
|
180
|
+
elsif entry.key == key
|
181
|
+
return entry.value
|
189
182
|
end
|
190
183
|
|
191
184
|
nil
|
@@ -202,13 +195,13 @@ module PEROBS
|
|
202
195
|
# Return true if hash is empty. False otherweise.
|
203
196
|
# @return [TrueClass, FalseClass]
|
204
197
|
def empty?
|
205
|
-
@btree.entry_counter
|
198
|
+
@btree.entry_counter.zero?
|
206
199
|
end
|
207
200
|
|
208
201
|
# Calls the given block for each key/value pair.
|
209
202
|
# @yield(key, value)
|
210
203
|
def each(&block)
|
211
|
-
@btree.each do |
|
204
|
+
@btree.each do |_, entry|
|
212
205
|
if entry.is_a?(Collisions)
|
213
206
|
break if entry.each do |c_entry|
|
214
207
|
yield(c_entry.key, c_entry.value)
|
@@ -224,23 +217,20 @@ module PEROBS
|
|
224
217
|
# @return [Array] A list of all keys
|
225
218
|
def keys
|
226
219
|
ks = []
|
227
|
-
each { |k,
|
220
|
+
each { |k, _| ks << k }
|
228
221
|
ks
|
229
222
|
end
|
230
223
|
|
231
224
|
# Check if the data structure contains any errors.
|
232
225
|
# @return [Boolean] true if no erros were found, false otherwise
|
233
226
|
def check
|
234
|
-
|
227
|
+
@btree.check
|
235
228
|
end
|
236
229
|
|
237
230
|
private
|
238
231
|
|
239
232
|
def hash_key(key)
|
240
|
-
FNV_Hash_1a_64
|
233
|
+
FNV_Hash_1a_64.digest(key)
|
241
234
|
end
|
242
|
-
|
243
235
|
end
|
244
|
-
|
245
236
|
end
|
246
|
-
|
data/lib/perobs/BigTree.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
#
|
3
3
|
# = BigTree.rb -- Persistent Ruby Object Store
|
4
4
|
#
|
@@ -35,10 +35,7 @@ module PEROBS
|
|
35
35
|
# entries is limited by the space on the backing store, not the main
|
36
36
|
# memory. Entries are addressed by a Integer key.
|
37
37
|
class BigTree < PEROBS::Object
|
38
|
-
|
39
|
-
class Stats < Struct.new(:leaf_nodes, :branch_nodes, :min_depth,
|
40
|
-
:max_depth)
|
41
|
-
end
|
38
|
+
Stats = Struct.new(:leaf_nodes, :branch_nodes, :min_depth, :max_depth)
|
42
39
|
|
43
40
|
attr_persist :node_size, :root, :first_leaf, :last_leaf, :entry_counter
|
44
41
|
|
@@ -118,9 +115,7 @@ module PEROBS
|
|
118
115
|
old_root = @root
|
119
116
|
clear
|
120
117
|
old_root.each do |k, v|
|
121
|
-
|
122
|
-
insert(k, v)
|
123
|
-
end
|
118
|
+
insert(k, v) unless yield(k, v)
|
124
119
|
end
|
125
120
|
end
|
126
121
|
|
@@ -131,7 +126,7 @@ module PEROBS
|
|
131
126
|
|
132
127
|
# Return true if the BigTree has no stored entries.
|
133
128
|
def empty?
|
134
|
-
@entry_counter
|
129
|
+
@entry_counter.zero?
|
135
130
|
end
|
136
131
|
|
137
132
|
# Iterate over all entries in the tree. Entries are always sorted by the
|
@@ -141,6 +136,7 @@ module PEROBS
|
|
141
136
|
node = @first_leaf
|
142
137
|
while node
|
143
138
|
break if node.each_element(&block).nil?
|
139
|
+
|
144
140
|
node = node.next_sibling
|
145
141
|
end
|
146
142
|
end
|
@@ -156,7 +152,6 @@ module PEROBS
|
|
156
152
|
end
|
157
153
|
end
|
158
154
|
|
159
|
-
|
160
155
|
# @return [String] Human reable form of the tree.
|
161
156
|
def to_s
|
162
157
|
@root.to_s
|
@@ -173,8 +168,8 @@ module PEROBS
|
|
173
168
|
end
|
174
169
|
|
175
170
|
unless @entry_counter == i
|
176
|
-
PEROBS.log.error "BigTree contains #{i} values but entry counter "
|
177
|
-
|
171
|
+
PEROBS.log.error "BigTree contains #{i} values but entry counter " \
|
172
|
+
"is #{@entry_counter}"
|
178
173
|
return false
|
179
174
|
end
|
180
175
|
|
@@ -188,10 +183,5 @@ module PEROBS
|
|
188
183
|
@root.statistics(stats)
|
189
184
|
stats
|
190
185
|
end
|
191
|
-
|
192
|
-
private
|
193
|
-
|
194
186
|
end
|
195
|
-
|
196
187
|
end
|
197
|
-
|