perobs 4.4.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 +87 -99
- data/lib/perobs/BigHash.rb +14 -24
- data/lib/perobs/BigTree.rb +7 -17
- data/lib/perobs/BigTreeNode.rb +101 -122
- data/lib/perobs/Cache.rb +13 -0
- data/lib/perobs/ClassMap.rb +6 -0
- data/lib/perobs/DataBase.rb +19 -14
- data/lib/perobs/IDList.rb +2 -2
- data/lib/perobs/Log.rb +5 -0
- data/lib/perobs/Store.rb +17 -3
- 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
|
@@ -135,27 +130,29 @@ module PEROBS
|
|
135
130
|
node = self
|
136
131
|
|
137
132
|
# Traverse the tree to find the right node to add or replace the value.
|
138
|
-
|
133
|
+
idx = index
|
134
|
+
while node
|
139
135
|
# Once we have reached a leaf node we can insert or replace the value.
|
140
136
|
if node.is_leaf?
|
141
|
-
if
|
142
|
-
node.fatal "Set index (#{index}) larger than values array "
|
143
|
-
|
137
|
+
if idx >= node.values.size
|
138
|
+
node.fatal "Set index (#{index}) larger than values array " \
|
139
|
+
"(#{idx} >= #{node.values.size})."
|
144
140
|
end
|
145
|
-
node.values[
|
141
|
+
node.values[idx] = value
|
146
142
|
return
|
147
143
|
else
|
148
144
|
# Descend into the right child node to add the value to.
|
149
|
-
cidx = node.search_child_index(
|
150
|
-
if (
|
151
|
-
node.fatal "
|
145
|
+
cidx = node.search_child_index(idx)
|
146
|
+
if (idx -= node.offsets[cidx]).negative?
|
147
|
+
node.fatal "Idx (#{idx}) became negative while looking for " \
|
148
|
+
"index #{index}."
|
152
149
|
end
|
153
150
|
node = node.children[cidx]
|
154
151
|
end
|
155
152
|
end
|
156
153
|
|
157
|
-
node.fatal
|
158
|
-
|
154
|
+
node.fatal 'Could not find proper node to set the value while ' \
|
155
|
+
"looking for index #{index}."
|
159
156
|
end
|
160
157
|
|
161
158
|
# Insert the given value at the given index. All following values will be
|
@@ -167,7 +164,7 @@ module PEROBS
|
|
167
164
|
cidx = nil
|
168
165
|
|
169
166
|
# Traverse the tree to find the right node to add or replace the value.
|
170
|
-
while node
|
167
|
+
while node
|
171
168
|
# All nodes that we find on the way that are full will be split into
|
172
169
|
# two half-full nodes.
|
173
170
|
if node.size >= @tree.node_size
|
@@ -180,20 +177,20 @@ module PEROBS
|
|
180
177
|
# Once we have reached a leaf node we can insert or replace the value.
|
181
178
|
if node.is_leaf?
|
182
179
|
node.values.insert(index, value)
|
183
|
-
node.parent
|
180
|
+
node.parent&.adjust_offsets(node, 1)
|
184
181
|
return
|
185
182
|
else
|
186
183
|
# Descend into the right child node to add the value to.
|
187
184
|
cidx = node.search_child_index(index)
|
188
|
-
if (index -= node.offsets[cidx])
|
185
|
+
if (index -= node.offsets[cidx]).negative?
|
189
186
|
node.fatal "Index (#{index}) became negative"
|
190
187
|
end
|
191
188
|
node = node.children[cidx]
|
192
189
|
end
|
193
190
|
end
|
194
191
|
|
195
|
-
node.fatal
|
196
|
-
|
192
|
+
node.fatal 'Could not find proper node to insert the value while ' \
|
193
|
+
"looking for index #{index}"
|
197
194
|
end
|
198
195
|
|
199
196
|
# Return the value that matches the given key or return nil if they key is
|
@@ -204,23 +201,21 @@ module PEROBS
|
|
204
201
|
node = self
|
205
202
|
|
206
203
|
# Traverse the tree to find the right node to add or replace the value.
|
207
|
-
while node
|
204
|
+
while node
|
208
205
|
# Once we have reached a leaf node we can insert or replace the value.
|
209
|
-
if node.is_leaf?
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
node.fatal "Index (#{index}) became negative"
|
217
|
-
end
|
218
|
-
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"
|
219
213
|
end
|
214
|
+
node = node.children[cidx]
|
220
215
|
end
|
221
216
|
|
222
|
-
PEROBS.log.fatal
|
223
|
-
|
217
|
+
PEROBS.log.fatal 'Could not find proper node to get from while ' \
|
218
|
+
"looking for index #{index}"
|
224
219
|
end
|
225
220
|
|
226
221
|
# Delete the element at the specified index, returning that element, or
|
@@ -231,14 +226,12 @@ module PEROBS
|
|
231
226
|
node = self
|
232
227
|
deleted_value = nil
|
233
228
|
|
234
|
-
while node
|
229
|
+
while node
|
235
230
|
if node.is_leaf?
|
236
231
|
deleted_value = node.values.delete_at(index)
|
237
232
|
if node.parent
|
238
233
|
node.parent.adjust_offsets(node, -1)
|
239
|
-
if node.size < min_size
|
240
|
-
node.parent.consolidate_child_nodes(node)
|
241
|
-
end
|
234
|
+
node.parent.consolidate_child_nodes(node) if node.size < min_size
|
242
235
|
end
|
243
236
|
|
244
237
|
return deleted_value
|
@@ -246,15 +239,15 @@ module PEROBS
|
|
246
239
|
# Descend into the right child node to add the value to.
|
247
240
|
cidx = (node.offsets.bsearch_index { |o| o > index } ||
|
248
241
|
node.offsets.length) - 1
|
249
|
-
if (index -= node.offsets[cidx])
|
242
|
+
if (index -= node.offsets[cidx]).negative?
|
250
243
|
node.fatal "Index (#{index}) became negative"
|
251
244
|
end
|
252
245
|
node = node.children[cidx]
|
253
246
|
end
|
254
247
|
end
|
255
248
|
|
256
|
-
PEROBS.log.fatal
|
257
|
-
|
249
|
+
PEROBS.log.fatal 'Could not find proper node to delete from while ' \
|
250
|
+
"looking for index #{index}"
|
258
251
|
end
|
259
252
|
|
260
253
|
# Iterate over all the values of the node.
|
@@ -285,13 +278,13 @@ module PEROBS
|
|
285
278
|
branch_depth = nil
|
286
279
|
|
287
280
|
traverse do |node, position, stack|
|
288
|
-
if position
|
281
|
+
if position.zero?
|
289
282
|
# Nodes should have between min_size() and
|
290
283
|
# @tree.node_size children or values. Only the root node may have
|
291
284
|
# less.
|
292
285
|
if node.size > @tree.node_size
|
293
|
-
node.error "BigArray node #{node._id} is too large. It has "
|
294
|
-
|
286
|
+
node.error "BigArray node #{node._id} is too large. It has " \
|
287
|
+
"#{node.size} nodes instead of max. #{@tree.node_size}."
|
295
288
|
return false
|
296
289
|
end
|
297
290
|
if node.parent && node.size < min_size
|
@@ -303,7 +296,7 @@ module PEROBS
|
|
303
296
|
# All leaf nodes must have same distance from root node.
|
304
297
|
if branch_depth
|
305
298
|
unless branch_depth == stack.size
|
306
|
-
node.error
|
299
|
+
node.error 'All leaf nodes must have same distance from root'
|
307
300
|
return false
|
308
301
|
end
|
309
302
|
else
|
@@ -313,24 +306,24 @@ module PEROBS
|
|
313
306
|
return false unless node.check_leaf_node_links
|
314
307
|
|
315
308
|
if node.children
|
316
|
-
node.error
|
309
|
+
node.error 'children must be nil for a leaf node'
|
317
310
|
return false
|
318
311
|
end
|
319
312
|
else
|
320
313
|
unless node.children.size == node.offsets.size
|
321
|
-
node.error "Offset count (#{node.offsets.size}) must be equal "
|
322
|
-
|
323
|
-
|
314
|
+
node.error "Offset count (#{node.offsets.size}) must be equal " \
|
315
|
+
"to children count (#{node.children.size})"
|
316
|
+
return false
|
324
317
|
end
|
325
318
|
|
326
319
|
if node.values
|
327
|
-
node.error
|
320
|
+
node.error 'values must be nil for a branch node'
|
328
321
|
return false
|
329
322
|
end
|
330
323
|
|
331
324
|
unless @prev_sibling.nil? && @next_sibling.nil?
|
332
|
-
node.error
|
333
|
-
|
325
|
+
node.error 'prev_sibling and next_sibling must be nil for ' \
|
326
|
+
'branch nodes'
|
334
327
|
end
|
335
328
|
|
336
329
|
return false unless node.check_offsets
|
@@ -341,12 +334,10 @@ module PEROBS
|
|
341
334
|
# These checks are done after we have completed the respective child
|
342
335
|
# node with index 'position - 1'.
|
343
336
|
index = position - 1
|
344
|
-
if node.is_leaf?
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
node.values[index])
|
349
|
-
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])
|
350
341
|
end
|
351
342
|
end
|
352
343
|
end
|
@@ -357,25 +348,25 @@ module PEROBS
|
|
357
348
|
def check_leaf_node_links
|
358
349
|
if @prev_sibling.nil?
|
359
350
|
if @tree.first_leaf != self
|
360
|
-
error "Leaf node #{@_id} has no previous sibling "
|
361
|
-
|
351
|
+
error "Leaf node #{@_id} has no previous sibling " \
|
352
|
+
'but is not the first leaf of the tree'
|
362
353
|
return false
|
363
354
|
end
|
364
355
|
elsif @prev_sibling.next_sibling != self
|
365
|
-
error
|
366
|
-
|
356
|
+
error 'next_sibling of previous sibling does not point to ' \
|
357
|
+
'this node'
|
367
358
|
return false
|
368
359
|
end
|
369
360
|
|
370
361
|
if @next_sibling.nil?
|
371
362
|
if @tree.last_leaf != self
|
372
|
-
error "Leaf node #{@_id} has no next sibling "
|
373
|
-
|
363
|
+
error "Leaf node #{@_id} has no next sibling " \
|
364
|
+
'but is not the last leaf of the tree'
|
374
365
|
return false
|
375
366
|
end
|
376
367
|
elsif @next_sibling.prev_sibling != self
|
377
|
-
error
|
378
|
-
|
368
|
+
error 'previous_sibling of next sibling does not point to ' \
|
369
|
+
'this node'
|
379
370
|
return false
|
380
371
|
end
|
381
372
|
|
@@ -392,16 +383,16 @@ module PEROBS
|
|
392
383
|
|
393
384
|
last_offset = nil
|
394
385
|
@offsets.each_with_index do |offset, i|
|
395
|
-
if i
|
386
|
+
if i.positive?
|
396
387
|
if offset < last_offset
|
397
|
-
error
|
398
|
-
|
388
|
+
error 'Offsets are not strictly monotoneously ' \
|
389
|
+
"increasing: #{@offsets.inspect}"
|
399
390
|
return false
|
400
391
|
end
|
401
392
|
expected_offset = last_offset + @children[i - 1].values_count
|
402
393
|
if offset != expected_offset
|
403
|
-
error "Offset #{i} must be #{expected_offset} "
|
404
|
-
|
394
|
+
error "Offset #{i} must be #{expected_offset} " \
|
395
|
+
"but is #{offset}."
|
405
396
|
return false
|
406
397
|
end
|
407
398
|
end
|
@@ -420,20 +411,20 @@ module PEROBS
|
|
420
411
|
|
421
412
|
@children.each_with_index do |child, i|
|
422
413
|
unless child.is_a?(BigArrayNode)
|
423
|
-
error "Child #{@_id} is of class #{child.class} "
|
424
|
-
|
414
|
+
error "Child #{@_id} is of class #{child.class} " \
|
415
|
+
'instead of BigArrayNode'
|
425
416
|
return false
|
426
417
|
end
|
427
418
|
|
428
419
|
unless child.parent.is_a?(BigArrayNode)
|
429
|
-
error "Parent reference of child #{i} is of class "
|
430
|
-
|
420
|
+
error "Parent reference of child #{i} is of class " \
|
421
|
+
"#{child.class} instead of BigArrayNode"
|
431
422
|
return false
|
432
423
|
end
|
433
424
|
|
434
425
|
if child.parent != self
|
435
|
-
error "Child node #{child._id} has wrong parent "
|
436
|
-
|
426
|
+
error "Child node #{child._id} has wrong parent " \
|
427
|
+
"#{child.parent._id}. It should be #{@_id}."
|
437
428
|
return false
|
438
429
|
end
|
439
430
|
|
@@ -448,8 +439,8 @@ module PEROBS
|
|
448
439
|
end
|
449
440
|
|
450
441
|
unless child.parent == self
|
451
|
-
error "Child #{i} does not have parent pointing "
|
452
|
-
|
442
|
+
error "Child #{i} does not have parent pointing " \
|
443
|
+
'to this node'
|
453
444
|
return false
|
454
445
|
end
|
455
446
|
end
|
@@ -462,11 +453,11 @@ module PEROBS
|
|
462
453
|
str = ''
|
463
454
|
|
464
455
|
traverse do |node, position, stack|
|
465
|
-
if position
|
456
|
+
if position.zero?
|
466
457
|
begin
|
467
|
-
str += "#{node.parent ? node.parent.tree_prefix + ' +' : 'o'}"
|
468
|
-
|
469
|
-
|
458
|
+
str += "#{node.parent ? node.parent.tree_prefix + ' +' : 'o'}" \
|
459
|
+
"#{node.tree_branch_mark}-" \
|
460
|
+
"#{node.empty? ? '--' : 'v-'}#{node.tree_summary}\n"
|
470
461
|
rescue => e
|
471
462
|
str += "@@@@@@@@@@: #{e.message}\n"
|
472
463
|
end
|
@@ -474,11 +465,11 @@ module PEROBS
|
|
474
465
|
begin
|
475
466
|
if node.is_leaf?
|
476
467
|
if position <= node.size
|
477
|
-
str += "#{node.tree_prefix} "
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
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"
|
482
473
|
end
|
483
474
|
end
|
484
475
|
rescue => e
|
@@ -811,7 +802,7 @@ module PEROBS
|
|
811
802
|
|
812
803
|
# Print and log an error message for the node.
|
813
804
|
def fatal(msg)
|
814
|
-
msg = "Fatal error in BigArray node @#{@_id}: #{msg}\n"
|
805
|
+
msg = "Fatal error in BigArray node @#{@_id}: #{msg}\n"
|
815
806
|
$stderr.puts msg
|
816
807
|
PEROBS.log.fatal msg
|
817
808
|
end
|
@@ -995,8 +986,5 @@ module PEROBS
|
|
995
986
|
@parent.consolidate_child_nodes(self)
|
996
987
|
end
|
997
988
|
end
|
998
|
-
|
999
989
|
end
|
1000
|
-
|
1001
990
|
end
|
1002
|
-
|
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
|
-
|