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/BigTreeNode.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
# = BigTreeNode.rb -- Persistent Ruby Object Store
|
4
4
|
#
|
5
5
|
# Copyright (c) 2016, 2017 by Chris Schlaeger <chris@taskjuggler.org>
|
@@ -25,11 +25,10 @@
|
|
25
25
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
26
26
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
require_relative 'Object'
|
29
|
+
require_relative 'Array'
|
30
30
|
|
31
31
|
module PEROBS
|
32
|
-
|
33
32
|
# The BigTreeNode class provides the BTree nodes for the BigTree objects.
|
34
33
|
# A node can either be a branch node or a leaf node. Branch nodes don't
|
35
34
|
# store values, only references to child nodes. Leaf nodes don't have child
|
@@ -38,9 +37,8 @@ module PEROBS
|
|
38
37
|
# associated with a value or determines the lower key boundary for the
|
39
38
|
# following child node.
|
40
39
|
class BigTreeNode < PEROBS::Object
|
41
|
-
|
42
40
|
attr_persist :tree, :parent, :keys, :values, :children,
|
43
|
-
|
41
|
+
:prev_sibling, :next_sibling
|
44
42
|
|
45
43
|
# Internal constructor. Use Store.new(BigTreeNode, ...) instead.
|
46
44
|
# @param p [Handle]
|
@@ -94,23 +92,19 @@ module PEROBS
|
|
94
92
|
node = myself
|
95
93
|
|
96
94
|
# Traverse the tree to find the right node to add or replace the value.
|
97
|
-
while node
|
95
|
+
while node
|
98
96
|
# All nodes that we find on the way that are full will be split into
|
99
97
|
# two half-full nodes.
|
100
|
-
if node.keys.size >= @tree.node_size
|
101
|
-
node = node.split_node
|
102
|
-
end
|
98
|
+
node = node.split_node if node.keys.size >= @tree.node_size
|
103
99
|
|
104
100
|
# Once we have reached a leaf node we can insert or replace the value.
|
105
|
-
if node.is_leaf?
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
node = node.children[node.search_key_index(key)]
|
110
|
-
end
|
101
|
+
return node.insert_element(key, value) if node.is_leaf?
|
102
|
+
|
103
|
+
# Descend into the right child node to add the value to.
|
104
|
+
node = node.children[node.search_key_index(key)]
|
111
105
|
end
|
112
106
|
|
113
|
-
PEROBS.log.fatal
|
107
|
+
PEROBS.log.fatal 'Could not find proper node to insert into'
|
114
108
|
end
|
115
109
|
|
116
110
|
# Return the value that matches the given key or return nil if they key is
|
@@ -120,7 +114,7 @@ module PEROBS
|
|
120
114
|
def get(key)
|
121
115
|
node = self
|
122
116
|
|
123
|
-
while node
|
117
|
+
while node
|
124
118
|
# Find index of the entry that best fits the key.
|
125
119
|
i = node.search_key_index(key)
|
126
120
|
if node.is_leaf?
|
@@ -133,8 +127,8 @@ module PEROBS
|
|
133
127
|
node = node.children[i]
|
134
128
|
end
|
135
129
|
|
136
|
-
PEROBS.log.fatal
|
137
|
-
|
130
|
+
PEROBS.log.fatal 'Could not find proper node to get from while ' \
|
131
|
+
"looking for key #{key}"
|
138
132
|
end
|
139
133
|
|
140
134
|
# Return the node chain from the root to the leaf node storing the
|
@@ -143,9 +137,9 @@ module PEROBS
|
|
143
137
|
# @return [Array of BigTreeNode] node list (may be empty)
|
144
138
|
def node_chain(key)
|
145
139
|
node = myself
|
146
|
-
list = [
|
140
|
+
list = [node]
|
147
141
|
|
148
|
-
while node
|
142
|
+
while node
|
149
143
|
# Find index of the entry that best fits the key.
|
150
144
|
i = node.search_key_index(key)
|
151
145
|
if node.is_leaf?
|
@@ -169,7 +163,7 @@ module PEROBS
|
|
169
163
|
def has_key?(key)
|
170
164
|
node = self
|
171
165
|
|
172
|
-
while node
|
166
|
+
while node
|
173
167
|
# Find index of the entry that best fits the key.
|
174
168
|
i = node.search_key_index(key)
|
175
169
|
if node.is_leaf?
|
@@ -182,8 +176,8 @@ module PEROBS
|
|
182
176
|
node = node.children[i]
|
183
177
|
end
|
184
178
|
|
185
|
-
PEROBS.log.fatal
|
186
|
-
|
179
|
+
PEROBS.log.fatal 'Could not find proper node to get from while ' \
|
180
|
+
"looking for key #{key}"
|
187
181
|
end
|
188
182
|
|
189
183
|
# Return the value that matches the given key and remove the value from
|
@@ -193,18 +187,16 @@ module PEROBS
|
|
193
187
|
def remove(key)
|
194
188
|
node = self
|
195
189
|
|
196
|
-
while node
|
190
|
+
while node
|
197
191
|
# Find index of the entry that best fits the key.
|
198
192
|
i = node.search_key_index(key)
|
199
193
|
if node.is_leaf?
|
200
194
|
# This is a leaf node. Check if there is an exact match for the
|
201
195
|
# given key and return the corresponding value or nil.
|
202
|
-
if node.keys[i]
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
return nil
|
207
|
-
end
|
196
|
+
return nil if node.keys[i] != key
|
197
|
+
|
198
|
+
@tree.entry_counter -= 1
|
199
|
+
return node.remove_element(i)
|
208
200
|
end
|
209
201
|
|
210
202
|
# Descend into the right child node to continue the search.
|
@@ -217,10 +209,9 @@ module PEROBS
|
|
217
209
|
# Iterate over all the key/value pairs in this node and all sub-nodes.
|
218
210
|
# @yield [key, value]
|
219
211
|
def each
|
220
|
-
traverse do |node, position,
|
221
|
-
|
212
|
+
traverse do |node, position, _|
|
213
|
+
node.is_leaf? && position < node.keys.size &&
|
222
214
|
yield(node.keys[position], node.values[position])
|
223
|
-
end
|
224
215
|
end
|
225
216
|
end
|
226
217
|
|
@@ -252,7 +243,7 @@ module PEROBS
|
|
252
243
|
branch_depth = nil
|
253
244
|
|
254
245
|
traverse do |node, position, stack|
|
255
|
-
if position
|
246
|
+
if position.zero?
|
256
247
|
if node.parent
|
257
248
|
# After a split the nodes will only have half the maximum keys.
|
258
249
|
# For branch nodes one of the split nodes will have even 1 key
|
@@ -264,16 +255,16 @@ module PEROBS
|
|
264
255
|
end
|
265
256
|
|
266
257
|
if node.keys.size > @tree.node_size
|
267
|
-
node.error
|
268
|
-
|
258
|
+
node.error 'BigTree node must not have more then ' \
|
259
|
+
"#{@tree.node_size} keys, but has #{node.keys.size} keys"
|
269
260
|
return false
|
270
261
|
end
|
271
262
|
|
272
263
|
last_key = nil
|
273
264
|
node.keys.each do |key|
|
274
265
|
if last_key && key < last_key
|
275
|
-
node.error
|
276
|
-
|
266
|
+
node.error 'Keys are not increasing monotoneously: ' \
|
267
|
+
"#{node.keys.inspect}"
|
277
268
|
return false
|
278
269
|
end
|
279
270
|
last_key = key
|
@@ -282,7 +273,7 @@ module PEROBS
|
|
282
273
|
if node.is_leaf?
|
283
274
|
if branch_depth
|
284
275
|
unless branch_depth == stack.size
|
285
|
-
node.error
|
276
|
+
node.error 'All leaf nodes must have same distance from root'
|
286
277
|
return false
|
287
278
|
end
|
288
279
|
else
|
@@ -290,54 +281,54 @@ module PEROBS
|
|
290
281
|
end
|
291
282
|
if node.prev_sibling.nil?
|
292
283
|
if @tree.first_leaf != node
|
293
|
-
node.error "Leaf node #{node._id} has no previous sibling "
|
294
|
-
|
284
|
+
node.error "Leaf node #{node._id} has no previous sibling " \
|
285
|
+
'but is not the first leaf of the tree'
|
295
286
|
return false
|
296
287
|
end
|
297
288
|
elsif node.prev_sibling.next_sibling != node
|
298
|
-
node.error
|
299
|
-
|
289
|
+
node.error 'next_sibling of previous sibling does not point to ' \
|
290
|
+
'this node'
|
300
291
|
return false
|
301
292
|
end
|
302
293
|
if node.next_sibling.nil?
|
303
294
|
if @tree.last_leaf != node
|
304
|
-
node.error "Leaf node #{node._id} has no next sibling "
|
305
|
-
|
295
|
+
node.error "Leaf node #{node._id} has no next sibling " \
|
296
|
+
'but is not the last leaf of the tree'
|
306
297
|
return false
|
307
298
|
end
|
308
299
|
elsif node.next_sibling.prev_sibling != node
|
309
|
-
node.error
|
310
|
-
|
300
|
+
node.error 'previous_sibling of next sibling does not point to ' \
|
301
|
+
'this node'
|
311
302
|
return false
|
312
303
|
end
|
313
304
|
unless node.keys.size == node.values.size
|
314
|
-
node.error "Key count (#{node.keys.size}) and value "
|
315
|
-
|
316
|
-
|
305
|
+
node.error "Key count (#{node.keys.size}) and value " \
|
306
|
+
"count (#{node.values.size}) don't match"
|
307
|
+
return false
|
317
308
|
end
|
318
309
|
if node.children
|
319
|
-
node.error
|
310
|
+
node.error 'children must be nil for a leaf node'
|
320
311
|
return false
|
321
312
|
end
|
322
313
|
else
|
323
314
|
if node.values
|
324
|
-
node.error
|
315
|
+
node.error 'values must be nil for a branch node'
|
325
316
|
return false
|
326
317
|
end
|
327
318
|
unless node.children.size == node.keys.size + 1
|
328
|
-
node.error "Key count (#{node.keys.size}) must be one "
|
329
|
-
|
330
|
-
|
319
|
+
node.error "Key count (#{node.keys.size}) must be one " \
|
320
|
+
"less than children count (#{node.children.size})"
|
321
|
+
return false
|
331
322
|
end
|
332
323
|
node.children.each_with_index do |child, i|
|
333
324
|
unless child.is_a?(BigTreeNode)
|
334
|
-
node.error "Child #{i} is of class #{child.class} "
|
335
|
-
|
325
|
+
node.error "Child #{i} is of class #{child.class} " \
|
326
|
+
'instead of BigTreeNode'
|
336
327
|
return false
|
337
328
|
end
|
338
329
|
unless child.parent.is_a?(BigTreeNode)
|
339
|
-
node.error "Parent reference of child #{i} is of class "
|
340
|
-
|
330
|
+
node.error "Parent reference of child #{i} is of class " \
|
331
|
+
"#{child.class} instead of BigTreeNode"
|
341
332
|
return false
|
342
333
|
end
|
343
334
|
if child == node
|
@@ -349,25 +340,22 @@ module PEROBS
|
|
349
340
|
return false
|
350
341
|
end
|
351
342
|
unless child.parent == node
|
352
|
-
node.error "Child #{i} does not have parent pointing "
|
353
|
-
|
343
|
+
node.error "Child #{i} does not have parent pointing " \
|
344
|
+
'to this node'
|
354
345
|
return false
|
355
346
|
end
|
356
|
-
if i
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
return false
|
362
|
-
end
|
347
|
+
if i.positive? && node.children[i - 1].next_sibling != child
|
348
|
+
node.error 'next_sibling of node ' \
|
349
|
+
"#{node.children[i - 1]._id} " \
|
350
|
+
"must point to node #{child._id}"
|
351
|
+
return false
|
363
352
|
end
|
364
|
-
if i < node.children.length - 1
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
end
|
353
|
+
if i < node.children.length - 1 &&
|
354
|
+
child != node.children[i + 1].prev_sibling
|
355
|
+
node.error 'prev_sibling of node ' \
|
356
|
+
"#{node.children[i + 1]._id} " \
|
357
|
+
"must point to node #{child._id}"
|
358
|
+
return false
|
371
359
|
end
|
372
360
|
end
|
373
361
|
end
|
@@ -382,15 +370,15 @@ module PEROBS
|
|
382
370
|
end
|
383
371
|
else
|
384
372
|
unless node.children[index].keys.last < node.keys[index]
|
385
|
-
node.error "Child #{node.children[index]._id} "
|
386
|
-
|
387
|
-
|
373
|
+
node.error "Child #{node.children[index]._id} " \
|
374
|
+
"has too large key #{node.children[index].keys.last}. " \
|
375
|
+
"Must be smaller than #{node.keys[index]}."
|
388
376
|
return false
|
389
377
|
end
|
390
378
|
unless node.children[position].keys.first >= node.keys[index]
|
391
|
-
node.error "Child #{node.children[position]._id} "
|
392
|
-
|
393
|
-
|
379
|
+
node.error "Child #{node.children[position]._id} " \
|
380
|
+
"has too small key #{node.children[position].keys.first}. " \
|
381
|
+
"Must be larger than or equal to #{node.keys[index]}."
|
394
382
|
return false
|
395
383
|
end
|
396
384
|
end
|
@@ -404,12 +392,12 @@ module PEROBS
|
|
404
392
|
def to_s
|
405
393
|
str = ''
|
406
394
|
|
407
|
-
traverse do |node, position,
|
408
|
-
if position
|
395
|
+
traverse do |node, position, _|
|
396
|
+
if position.zero?
|
409
397
|
begin
|
410
|
-
str += "#{node.parent ? node.parent.tree_prefix + ' +' : 'o'}"
|
411
|
-
|
412
|
-
|
398
|
+
str += "#{node.parent ? node.parent.tree_prefix + ' +' : 'o'}" \
|
399
|
+
"#{node.tree_branch_mark}-" \
|
400
|
+
"#{node.keys.first.nil? ? '--' : 'v-'}#{node.tree_summary}\n"
|
413
401
|
rescue => e
|
414
402
|
str += "@@@@@@@@@@: #{e.message}\n"
|
415
403
|
end
|
@@ -417,14 +405,12 @@ module PEROBS
|
|
417
405
|
begin
|
418
406
|
if node.is_leaf?
|
419
407
|
if node.keys[position - 1]
|
420
|
-
str += "#{node.tree_prefix} |"
|
421
|
-
"[#{node.keys[position - 1]}, "
|
408
|
+
str += "#{node.tree_prefix} |" \
|
409
|
+
"[#{node.keys[position - 1]}, " \
|
422
410
|
"#{node.values[position - 1]}]\n"
|
423
411
|
end
|
424
|
-
|
425
|
-
|
426
|
-
str += "#{node.tree_prefix} #{node.keys[position - 1]}\n"
|
427
|
-
end
|
412
|
+
elsif node.keys[position - 1]
|
413
|
+
str += "#{node.tree_prefix} #{node.keys[position - 1]}\n"
|
428
414
|
end
|
429
415
|
rescue => e
|
430
416
|
str += "@@@@@@@@@@: #{e.message}\n"
|
@@ -518,10 +504,9 @@ module PEROBS
|
|
518
504
|
def remove_element(index)
|
519
505
|
# Delete the key at the specified index.
|
520
506
|
unless (key = @keys.delete_at(index))
|
521
|
-
PEROBS.log.fatal "Could not remove element #{index} from BigTreeNode "
|
522
|
-
"@#{@_id}"
|
507
|
+
PEROBS.log.fatal "Could not remove element #{index} from BigTreeNode @#{@_id}"
|
523
508
|
end
|
524
|
-
update_branch_key(key) if index
|
509
|
+
update_branch_key(key) if index.zero?
|
525
510
|
|
526
511
|
# Delete the corresponding value.
|
527
512
|
removed_value = @values.delete_at(index)
|
@@ -533,7 +518,7 @@ module PEROBS
|
|
533
518
|
borrow_from_next_sibling(@next_sibling) ||
|
534
519
|
merge_with_leaf_node(@next_sibling)
|
535
520
|
elsif @parent
|
536
|
-
PEROBS.log.fatal
|
521
|
+
PEROBS.log.fatal 'Cannot not find adjecent leaf siblings'
|
537
522
|
end
|
538
523
|
end
|
539
524
|
|
@@ -549,7 +534,7 @@ module PEROBS
|
|
549
534
|
PEROBS.log.fatal "Cannot remove child #{node._id} from node #{@_id}"
|
550
535
|
end
|
551
536
|
|
552
|
-
if index
|
537
|
+
if index.zero?
|
553
538
|
# Removing the first child is a bit more complicated as the
|
554
539
|
# corresponding branch key is in a parent node.
|
555
540
|
key = @keys.shift
|
@@ -592,7 +577,7 @@ module PEROBS
|
|
592
577
|
|
593
578
|
def merge_with_leaf_node(node)
|
594
579
|
if @keys.length + node.keys.length > @tree.node_size
|
595
|
-
PEROBS.log.fatal
|
580
|
+
PEROBS.log.fatal 'Leaf nodes are too big to merge'
|
596
581
|
end
|
597
582
|
|
598
583
|
self.keys += node.keys
|
@@ -603,7 +588,7 @@ module PEROBS
|
|
603
588
|
|
604
589
|
def merge_with_branch_node(node)
|
605
590
|
if @keys.length + 1 + node.keys.length > @tree.node_size
|
606
|
-
PEROBS.log.fatal
|
591
|
+
PEROBS.log.fatal 'Branch nodes are too big to merge'
|
607
592
|
end
|
608
593
|
|
609
594
|
index = @parent.search_node_index(node) - 1
|
@@ -670,9 +655,9 @@ module PEROBS
|
|
670
655
|
def traverse
|
671
656
|
# We use a non-recursive implementation to traverse the tree. This stack
|
672
657
|
# keeps track of all the known still to be checked nodes.
|
673
|
-
stack = [
|
658
|
+
stack = [[self, 0]]
|
674
659
|
|
675
|
-
|
660
|
+
until stack.empty?
|
676
661
|
node, position = stack.pop
|
677
662
|
|
678
663
|
# Call the payload method. The position marks where we are in the node
|
@@ -684,15 +669,15 @@ module PEROBS
|
|
684
669
|
# to return to the parent node.
|
685
670
|
yield(node, position, stack)
|
686
671
|
|
687
|
-
|
688
|
-
# Push the next position for this node onto the stack.
|
689
|
-
stack.push([ node, position + 1 ])
|
672
|
+
next unless position <= node.keys.size
|
690
673
|
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
674
|
+
# Push the next position for this node onto the stack.
|
675
|
+
stack.push([node, position + 1])
|
676
|
+
|
677
|
+
if !node.is_leaf? && node.children[position]
|
678
|
+
# If we have a child node for this position, push the linked node
|
679
|
+
# and the starting position onto the stack.
|
680
|
+
stack.push([node.children[position], 0])
|
696
681
|
end
|
697
682
|
end
|
698
683
|
end
|
@@ -701,16 +686,12 @@ module PEROBS
|
|
701
686
|
# @param stats [Stats] Data structure that stores the gathered data
|
702
687
|
def statistics(stats)
|
703
688
|
traverse do |node, position, stack|
|
704
|
-
if position
|
689
|
+
if position.zero?
|
705
690
|
if node.is_leaf?
|
706
691
|
stats.leaf_nodes += 1
|
707
692
|
depth = stack.size + 1
|
708
|
-
if stats.min_depth.nil? || stats.min_depth < depth
|
709
|
-
|
710
|
-
end
|
711
|
-
if stats.max_depth.nil? || stats.max_depth > depth
|
712
|
-
stats.max_depth = depth
|
713
|
-
end
|
693
|
+
stats.min_depth = depth if stats.min_depth.nil? || stats.min_depth < depth
|
694
|
+
stats.max_depth = depth if stats.max_depth.nil? || stats.max_depth > depth
|
714
695
|
else
|
715
696
|
stats.branch_nodes += 1
|
716
697
|
end
|
@@ -743,6 +724,7 @@ module PEROBS
|
|
743
724
|
# Branch node decoration for the inspection method.
|
744
725
|
def tree_branch_mark
|
745
726
|
return '' unless @parent
|
727
|
+
|
746
728
|
'-'
|
747
729
|
end
|
748
730
|
|
@@ -866,8 +848,5 @@ module PEROBS
|
|
866
848
|
|
867
849
|
# The smallest element has no branch key.
|
868
850
|
end
|
869
|
-
|
870
851
|
end
|
871
|
-
|
872
852
|
end
|
873
|
-
|
data/lib/perobs/ClassMap.rb
CHANGED
@@ -60,6 +60,12 @@ module PEROBS
|
|
60
60
|
@by_id[id]
|
61
61
|
end
|
62
62
|
|
63
|
+
# Get a list of all classes used in the Store.
|
64
|
+
# @return [Array] list of Ruby classes
|
65
|
+
def classes
|
66
|
+
@by_class.keys
|
67
|
+
end
|
68
|
+
|
63
69
|
# Rename a set of classes to new names.
|
64
70
|
# @param rename_map [Hash] Hash that maps old names to new names
|
65
71
|
def rename(rename_map)
|
data/lib/perobs/DataBase.rb
CHANGED
@@ -34,18 +34,23 @@ require 'fileutils'
|
|
34
34
|
|
35
35
|
require 'perobs/Log'
|
36
36
|
require 'perobs/ObjectBase'
|
37
|
+
require_relative 'ProgressMeter'
|
37
38
|
|
38
39
|
module PEROBS
|
39
|
-
|
40
40
|
# Base class for all storage back-ends.
|
41
41
|
class DataBase
|
42
|
-
|
43
42
|
# Create a new DataBase object. This method must be overwritten by the
|
44
43
|
# deriving classes and then called via their constructor.
|
45
44
|
def initialize(options)
|
46
45
|
@serializer = options[:serializer] || :json
|
47
46
|
@progressmeter = options[:progressmeter] || ProgressMeter.new
|
48
47
|
@config = {}
|
48
|
+
@class_map = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
# Register the class map object needed to de-serialize objects.
|
52
|
+
def register_class_map(class_map)
|
53
|
+
@class_map = class_map
|
49
54
|
end
|
50
55
|
|
51
56
|
# A dummy open method. Deriving classes must overload them to insert their
|
@@ -81,19 +86,21 @@ module PEROBS
|
|
81
86
|
# @param raw [String]
|
82
87
|
# @return [Hash] Deserialized version
|
83
88
|
def deserialize(raw)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
89
|
+
case @serializer
|
90
|
+
when :marshal
|
91
|
+
Marshal.load(raw)
|
92
|
+
when :json
|
93
|
+
JSON.parse(raw, create_additions: true)
|
94
|
+
when :yaml
|
95
|
+
if RUBY_VERSION < '3.2'
|
91
96
|
YAML.load(raw)
|
97
|
+
else
|
98
|
+
YAML.load(raw, permitted_classes: [Symbol, POReference] + @class_map.classes)
|
92
99
|
end
|
93
|
-
rescue => e
|
94
|
-
PEROBS.log.fatal "Cannot de-serialize object with #{@serializer} " +
|
95
|
-
"parser: " + e.message
|
96
100
|
end
|
101
|
+
rescue => e
|
102
|
+
PEROBS.log.fatal "Cannot de-serialize object with #{@serializer} " +
|
103
|
+
"parser: " + e.message
|
97
104
|
end
|
98
105
|
|
99
106
|
# Check a config option and adjust it if needed.
|
@@ -127,7 +134,5 @@ module PEROBS
|
|
127
134
|
end
|
128
135
|
end
|
129
136
|
end
|
130
|
-
|
131
137
|
end
|
132
|
-
|
133
138
|
end
|
data/lib/perobs/IDList.rb
CHANGED
@@ -46,7 +46,7 @@ module PEROBS
|
|
46
46
|
# that will be kept in memory. If the list is larger, values will
|
47
47
|
# be cached in the specified file.
|
48
48
|
# @param page_size [Integer] The number of values per page. The default
|
49
|
-
# value is 32 which was found the best performing config in
|
49
|
+
# value is 32 which was found the best performing config in tests.
|
50
50
|
def initialize(dir, name, max_in_memory, page_size = 32)
|
51
51
|
# The page_file manages the pages that store the values.
|
52
52
|
@page_file = IDListPageFile.new(self, dir, name,
|
@@ -63,7 +63,7 @@ module PEROBS
|
|
63
63
|
page = @page_records[index]
|
64
64
|
|
65
65
|
# In case the page is already full we'll have to create a new page.
|
66
|
-
# There is no guarantee that a split will yield
|
66
|
+
# There is no guarantee that a split will yield a page with space as we
|
67
67
|
# split by ID range, not by distributing the values evenly across the
|
68
68
|
# two pages.
|
69
69
|
while page.is_full?
|
data/lib/perobs/Store.rb
CHANGED
@@ -157,6 +157,7 @@ module PEROBS
|
|
157
157
|
# Create a map that can translate classes to numerical IDs and vice
|
158
158
|
# versa.
|
159
159
|
@class_map = ClassMap.new(@db)
|
160
|
+
@db.register_class_map(@class_map)
|
160
161
|
|
161
162
|
# List of PEROBS objects that are currently available as Ruby objects
|
162
163
|
# hashed by their ID.
|
@@ -712,4 +713,3 @@ module PEROBS
|
|
712
713
|
end
|
713
714
|
|
714
715
|
end
|
715
|
-
|
data/lib/perobs/version.rb
CHANGED
data/perobs.gemspec
CHANGED
@@ -16,9 +16,10 @@ GEM_SPEC = Gem::Specification.new do |spec|
|
|
16
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
|
-
spec.required_ruby_version = '>=2.
|
19
|
+
spec.required_ruby_version = '>=2.5'
|
20
20
|
|
21
|
-
spec.add_development_dependency 'bundler', '~> 2.
|
21
|
+
spec.add_development_dependency 'bundler', '~> 2.2'
|
22
22
|
spec.add_development_dependency 'yard', '~>0.9.12'
|
23
23
|
spec.add_development_dependency 'rake', '~> 13.0.3'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.12'
|
24
25
|
end
|