perobs 4.5.0 → 4.6.0
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.
- 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
|
-
|