perobs 4.4.0 → 4.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
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
- require 'perobs/Object'
30
- require 'perobs/Array'
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
- :prev_sibling, :next_sibling
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
- return count + node.values.size
123
- else
124
- count += node.offsets.last
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
- while node do
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 index >= node.values.size
142
- node.fatal "Set index (#{index}) larger than values array " +
143
- "(#{node.values.size})."
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[index] = value
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(index)
150
- if (index -= node.offsets[cidx]) < 0
151
- node.fatal "Index (#{index}) became negative"
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 "Could not find proper node to set the value while " +
158
- "looking for index #{index}"
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 do
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.adjust_offsets(node, 1) if 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]) < 0
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 "Could not find proper node to insert the value while " +
196
- "looking for index #{index}"
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 do
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
- return node.values[index]
211
- else
212
- # Descend into the right child node to add the value to.
213
- cidx = (node.offsets.bsearch_index { |o| o > index } ||
214
- node.offsets.length) - 1
215
- if (index -= node.offsets[cidx]) < 0
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 "Could not find proper node to get from while " +
223
- "looking for index #{index}"
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 do
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]) < 0
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 "Could not find proper node to delete from while " +
257
- "looking for index #{index}"
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 == 0
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
- "#{node.size} nodes instead of max. #{@tree.node_size}."
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 "All leaf nodes must have same distance from root"
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 "children must be nil for a leaf node"
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
- "to children count (#{node.children.size})"
323
- return false
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 "values must be nil for a branch node"
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 "prev_sibling and next_sibling must be nil for " +
333
- "branch nodes"
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
- if block_given?
346
- # If a block was given, call this block with the key and value.
347
- return false unless yield(node.first_index + index,
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
- "but is not the first leaf of the tree"
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 "next_sibling of previous sibling does not point to " +
366
- "this node"
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
- "but is not the last leaf of the tree"
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 "previous_sibling of next sibling does not point to " +
378
- "this node"
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 > 0
386
+ if i.positive?
396
387
  if offset < last_offset
397
- error "Offsets are not strictly monotoneously " +
398
- "increasing: #{@offsets.inspect}"
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
- "but is #{offset}."
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
- "instead of BigArrayNode"
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
- "#{child.class} instead of BigArrayNode"
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
- "#{child.parent._id}. It should be #{@_id}."
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
- "to this node"
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 == 0
456
+ if position.zero?
466
457
  begin
467
- str += "#{node.parent ? node.parent.tree_prefix + ' +' : 'o'}" +
468
- "#{node.tree_branch_mark}-" +
469
- "#{node.size == 0 ? '--' : 'v-'}#{node.tree_summary}\n"
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
- "#{position == node.size ? '-' : '|'} " +
479
- "[ #{node.value_index(position - 1)}: " +
480
- "#{node.values[position - 1].nil? ?
481
- 'nil' : node.values[position - 1]} ]\n"
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" + @tree.to_s
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
-
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
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
- else
143
- return entry.value if entry.key == key
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
- else
163
- return true if entry.key == key
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
- else
188
- return entry.value if entry.key == key
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 == 0
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 |index, entry|
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, v| ks << 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
- return @btree.check
227
+ @btree.check
235
228
  end
236
229
 
237
230
  private
238
231
 
239
232
  def hash_key(key)
240
- FNV_Hash_1a_64::digest(key)
233
+ FNV_Hash_1a_64.digest(key)
241
234
  end
242
-
243
235
  end
244
-
245
236
  end
246
-
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
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
- if !yield(k, v)
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 == 0
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
- "is #{@entry_counter}"
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
-