perobs 3.0.1 → 4.3.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 +5 -5
- data/README.md +19 -18
- data/lib/perobs.rb +2 -0
- data/lib/perobs/Array.rb +68 -21
- data/lib/perobs/BTree.rb +110 -54
- data/lib/perobs/BTreeBlob.rb +14 -13
- data/lib/perobs/BTreeDB.rb +11 -10
- data/lib/perobs/BTreeNode.rb +551 -197
- data/lib/perobs/BTreeNodeCache.rb +10 -8
- data/lib/perobs/BTreeNodeLink.rb +11 -1
- data/lib/perobs/BigArray.rb +285 -0
- data/lib/perobs/BigArrayNode.rb +1002 -0
- data/lib/perobs/BigHash.rb +246 -0
- data/lib/perobs/BigTree.rb +197 -0
- data/lib/perobs/BigTreeNode.rb +873 -0
- data/lib/perobs/Cache.rb +47 -22
- data/lib/perobs/ClassMap.rb +2 -2
- data/lib/perobs/ConsoleProgressMeter.rb +61 -0
- data/lib/perobs/DataBase.rb +4 -3
- data/lib/perobs/DynamoDB.rb +62 -20
- data/lib/perobs/EquiBlobsFile.rb +174 -59
- data/lib/perobs/FNV_Hash_1a_64.rb +54 -0
- data/lib/perobs/FlatFile.rb +536 -242
- data/lib/perobs/FlatFileBlobHeader.rb +120 -84
- data/lib/perobs/FlatFileDB.rb +58 -27
- data/lib/perobs/FuzzyStringMatcher.rb +175 -0
- data/lib/perobs/Hash.rb +129 -35
- data/lib/perobs/IDList.rb +144 -0
- data/lib/perobs/IDListPage.rb +107 -0
- data/lib/perobs/IDListPageFile.rb +180 -0
- data/lib/perobs/IDListPageRecord.rb +142 -0
- data/lib/perobs/LockFile.rb +3 -0
- data/lib/perobs/Object.rb +28 -20
- data/lib/perobs/ObjectBase.rb +53 -10
- data/lib/perobs/PersistentObjectCache.rb +142 -0
- data/lib/perobs/PersistentObjectCacheLine.rb +99 -0
- data/lib/perobs/ProgressMeter.rb +97 -0
- data/lib/perobs/SpaceManager.rb +273 -0
- data/lib/perobs/SpaceTree.rb +63 -47
- data/lib/perobs/SpaceTreeNode.rb +134 -115
- data/lib/perobs/SpaceTreeNodeLink.rb +1 -1
- data/lib/perobs/StackFile.rb +1 -1
- data/lib/perobs/Store.rb +180 -70
- data/lib/perobs/version.rb +1 -1
- data/perobs.gemspec +4 -4
- data/test/Array_spec.rb +48 -39
- data/test/BTreeDB_spec.rb +2 -2
- data/test/BTree_spec.rb +50 -1
- data/test/BigArray_spec.rb +261 -0
- data/test/BigHash_spec.rb +152 -0
- data/test/BigTreeNode_spec.rb +153 -0
- data/test/BigTree_spec.rb +259 -0
- data/test/EquiBlobsFile_spec.rb +105 -5
- data/test/FNV_Hash_1a_64_spec.rb +59 -0
- data/test/FlatFileDB_spec.rb +199 -15
- data/test/FuzzyStringMatcher_spec.rb +261 -0
- data/test/Hash_spec.rb +27 -16
- data/test/IDList_spec.rb +77 -0
- data/test/LegacyDBs/LegacyDB.rb +155 -0
- data/test/LegacyDBs/version_3/class_map.json +1 -0
- data/test/LegacyDBs/version_3/config.json +1 -0
- data/test/LegacyDBs/version_3/database.blobs +0 -0
- data/test/LegacyDBs/version_3/database_spaces.blobs +0 -0
- data/test/LegacyDBs/version_3/index.blobs +0 -0
- data/test/LegacyDBs/version_3/version +1 -0
- data/test/LockFile_spec.rb +9 -6
- data/test/Object_spec.rb +5 -5
- data/test/SpaceManager_spec.rb +176 -0
- data/test/SpaceTree_spec.rb +27 -9
- data/test/Store_spec.rb +353 -206
- data/test/perobs_spec.rb +7 -3
- data/test/spec_helper.rb +9 -4
- metadata +59 -16
- data/lib/perobs/SpaceTreeNodeCache.rb +0 -76
- data/lib/perobs/TreeDB.rb +0 -277
data/lib/perobs/version.rb
CHANGED
data/perobs.gemspec
CHANGED
@@ -16,9 +16,9 @@ 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.4'
|
20
20
|
|
21
|
-
spec.add_development_dependency 'bundler', '~>
|
22
|
-
spec.add_development_dependency 'yard', '~>0.
|
23
|
-
spec.add_development_dependency 'rake', '~>
|
21
|
+
spec.add_development_dependency 'bundler', '~> 2.3'
|
22
|
+
spec.add_development_dependency 'yard', '~>0.9.12'
|
23
|
+
spec.add_development_dependency 'rake', '~> 12.3.3'
|
24
24
|
end
|
data/test/Array_spec.rb
CHANGED
@@ -33,7 +33,7 @@ require 'perobs'
|
|
33
33
|
|
34
34
|
class PO < PEROBS::Object
|
35
35
|
|
36
|
-
|
36
|
+
attr_persist :name
|
37
37
|
|
38
38
|
def initialize(store, name = nil)
|
39
39
|
super(store)
|
@@ -65,7 +65,7 @@ describe PEROBS::Array do
|
|
65
65
|
@store.transaction do
|
66
66
|
@store['b'] = @store.new(PEROBS::Array)
|
67
67
|
end
|
68
|
-
@store.
|
68
|
+
@store.exit
|
69
69
|
@store = nil
|
70
70
|
GC.start
|
71
71
|
|
@@ -85,7 +85,7 @@ describe PEROBS::Array do
|
|
85
85
|
expect(a[0]).to eq('A')
|
86
86
|
expect(a[1]).to eq('B')
|
87
87
|
expect(a[2].name).to eq('foobar')
|
88
|
-
@store.
|
88
|
+
@store.exit
|
89
89
|
|
90
90
|
@store = PEROBS::Store.new(@db_name)
|
91
91
|
a = @store['a']
|
@@ -102,7 +102,7 @@ describe PEROBS::Array do
|
|
102
102
|
vs = ''
|
103
103
|
a.each { |v| vs << v }
|
104
104
|
expect(vs).to eq('ABC')
|
105
|
-
@store.
|
105
|
+
@store.exit
|
106
106
|
|
107
107
|
@store = PEROBS::Store.new(@db_name)
|
108
108
|
a = @store['a']
|
@@ -113,15 +113,15 @@ describe PEROBS::Array do
|
|
113
113
|
end
|
114
114
|
|
115
115
|
# Utility method to create a PEROBS::Array from a normal Array.
|
116
|
-
def cpa(ary = nil)
|
116
|
+
def cpa(ary = nil, id = 'a')
|
117
117
|
a = @store.new(PEROBS::Array)
|
118
118
|
a.replace(ary) unless ary.nil?
|
119
|
-
@store[
|
119
|
+
@store[id] = a
|
120
120
|
end
|
121
121
|
|
122
122
|
def pcheck
|
123
123
|
yield
|
124
|
-
@store.
|
124
|
+
@store.exit
|
125
125
|
@store = PEROBS::Store.new(@db_name)
|
126
126
|
yield
|
127
127
|
end
|
@@ -147,44 +147,54 @@ describe PEROBS::Array do
|
|
147
147
|
it 'should support re-writing methods' do
|
148
148
|
x = cpa([2, 5, 3, 1, 7])
|
149
149
|
x.sort!{ |a, b| a <=> b }
|
150
|
-
pcheck { expect(
|
151
|
-
|
152
|
-
pcheck { expect(
|
150
|
+
pcheck { expect(@store['a']).to eq([ 1, 2, 3, 5, 7 ]) }
|
151
|
+
@store['a'].sort!{ |a, b| b - a }
|
152
|
+
pcheck { expect(@store['a']).to eq([ 7, 5, 3, 2, 1 ]) }
|
153
153
|
|
154
|
-
|
155
|
-
pcheck { expect(
|
154
|
+
@store['a'].clear
|
155
|
+
pcheck { expect(@store['a']).to eq([]) }
|
156
156
|
end
|
157
157
|
|
158
158
|
it 'should support <<()' do
|
159
159
|
a = cpa([ 0, 1, 2 ])
|
160
160
|
a << 4
|
161
|
-
pcheck { expect(a).to eq([ 0, 1, 2, 4 ]) }
|
161
|
+
pcheck { expect(@store['a']).to eq([ 0, 1, 2, 4 ]) }
|
162
162
|
end
|
163
163
|
|
164
164
|
it 'should support []=' do
|
165
165
|
a = cpa([ 0, nil, 2 ])
|
166
166
|
a[1] = 1
|
167
|
-
pcheck { expect(a).to eq([ 0, 1, 2 ]) }
|
167
|
+
pcheck { expect(@store['a']).to eq([ 0, 1, 2 ]) }
|
168
168
|
end
|
169
169
|
|
170
170
|
it 'should support collect!()' do
|
171
171
|
a = cpa([ 1, 'cat', 1..1 ])
|
172
|
-
|
173
|
-
|
172
|
+
if RUBY_VERSION < '2.2'
|
173
|
+
expect(a.collect! { |e| e.class.to_s }.to_a).to eq([ 'Fixnum', 'String', 'Range' ])
|
174
|
+
pcheck { expect(@store['a'].to_a).to eq([ 'Fixnum', 'String', 'Range' ]) }
|
175
|
+
else
|
176
|
+
expect(a.collect! { |e| e.class.to_s }.to_a).to eq([ 'Integer', 'String', 'Range' ])
|
177
|
+
pcheck { expect(@store['a'].to_a).to eq([ 'Integer', 'String', 'Range' ]) }
|
178
|
+
end
|
174
179
|
|
175
180
|
a = cpa([ 1, 'cat', 1..1 ])
|
176
181
|
expect(a.collect! { 99 }).to eq([ 99, 99, 99])
|
177
|
-
pcheck { expect(a).to eq([ 99, 99, 99]) }
|
182
|
+
pcheck { expect(@store['a']).to eq([ 99, 99, 99]) }
|
178
183
|
end
|
179
184
|
|
180
185
|
it 'should support map!()' do
|
181
186
|
a = cpa([ 1, 'cat', 1..1 ])
|
182
|
-
|
183
|
-
|
187
|
+
if RUBY_VERSION < '2.2'
|
188
|
+
expect(a.map! { |e| e.class.to_s }.to_a).to eq([ 'Fixnum', 'String', 'Range' ])
|
189
|
+
pcheck { expect(@store['a'].to_a).to eq([ 'Fixnum', 'String', 'Range' ]) }
|
190
|
+
else
|
191
|
+
expect(a.map! { |e| e.class.to_s }.to_a).to eq([ 'Integer', 'String', 'Range' ])
|
192
|
+
pcheck { expect(@store['a'].to_a).to eq([ 'Integer', 'String', 'Range' ]) }
|
193
|
+
end
|
184
194
|
|
185
195
|
a = cpa([ 1, 'cat', 1..1 ])
|
186
196
|
expect(a.map! { 99 }).to eq([ 99, 99, 99])
|
187
|
-
pcheck { expect(a).to eq ([ 99, 99, 99]) }
|
197
|
+
pcheck { expect(@store['a']).to eq ([ 99, 99, 99]) }
|
188
198
|
end
|
189
199
|
|
190
200
|
it 'should support fill()' do
|
@@ -194,39 +204,39 @@ describe PEROBS::Array do
|
|
194
204
|
end
|
195
205
|
|
196
206
|
it 'should support flatten!()' do
|
197
|
-
a1 = cpa([ 1, 2, 3])
|
198
|
-
a2 = cpa([ 5, 6 ])
|
199
|
-
a3 = cpa([ 4, a2 ])
|
200
|
-
a4 = cpa([ a1, a3 ])
|
201
|
-
pcheck { expect(a4.flatten).to eq([ 1, 2, 3, 4, 5, 6 ]) }
|
207
|
+
a1 = cpa([ 1, 2, 3], 'a1')
|
208
|
+
a2 = cpa([ 5, 6 ], 'a2')
|
209
|
+
a3 = cpa([ 4, a2 ], 'a3')
|
210
|
+
a4 = cpa([ a1, a3 ], 'a4')
|
211
|
+
pcheck { expect(@store['a4'].flatten).to eq([ 1, 2, 3, 4, 5, 6 ]) }
|
202
212
|
end
|
203
213
|
|
204
214
|
it 'should support replace()' do
|
205
|
-
|
206
|
-
a_id =
|
207
|
-
expect(
|
208
|
-
pcheck { expect(
|
215
|
+
a1 = cpa([ 1, 2, 3], 'a1')
|
216
|
+
a_id = a1.__id__
|
217
|
+
expect(a1.replace(cpa([4, 5, 6], 'a2'))).to eq([ 4, 5, 6 ])
|
218
|
+
pcheck { expect(@store['a1']).to eq ([ 4, 5, 6 ]) }
|
209
219
|
end
|
210
220
|
|
211
221
|
it 'should support insert()' do
|
212
222
|
a = cpa([ 0 ])
|
213
223
|
a.insert(1)
|
214
|
-
pcheck { expect(a).to eq([ 0 ]) }
|
215
|
-
a.insert(1, 1)
|
216
|
-
pcheck { expect(a).to eq([ 0, 1]) }
|
224
|
+
pcheck { expect(@store['a']).to eq([ 0 ]) }
|
225
|
+
@store['a'].insert(1, 1)
|
226
|
+
pcheck { expect(@store['a']).to eq([ 0, 1]) }
|
217
227
|
end
|
218
228
|
|
219
229
|
it 'should support push()' do
|
220
230
|
a = cpa([ 1, 2, 3 ])
|
221
231
|
a.push(4, 5)
|
222
|
-
pcheck { expect(a).to eq([ 1, 2, 3, 4, 5 ]) }
|
223
|
-
a.push(nil)
|
224
|
-
pcheck { expect(a).to eq([ 1, 2, 3, 4, 5, nil ]) }
|
232
|
+
pcheck { expect(@store['a']).to eq([ 1, 2, 3, 4, 5 ]) }
|
233
|
+
@store['a'].push(nil)
|
234
|
+
pcheck { expect(@store['a']).to eq([ 1, 2, 3, 4, 5, nil ]) }
|
225
235
|
end
|
226
236
|
|
227
237
|
it 'should support inspect' do
|
228
|
-
a1 = cpa([ 1 ])
|
229
|
-
a2 = cpa([ 1, a1 ])
|
238
|
+
a1 = cpa([ 1 ], 'a1')
|
239
|
+
a2 = cpa([ 1, a1 ], 'a2')
|
230
240
|
expect(a1.inspect).to eq("<PEROBS::Array:#{a1._id}>\n[\n 1\n]\n")
|
231
241
|
expect(a2.inspect).to eq("<PEROBS::Array:#{a2._id}>\n[\n 1,\n <PEROBS::ObjectBase:#{a1._id}>\n]\n")
|
232
242
|
end
|
@@ -242,9 +252,8 @@ describe PEROBS::Array do
|
|
242
252
|
it 'should catch a leaked PEROBS::ObjectBase object' do
|
243
253
|
@store['a'] = a = @store.new(PEROBS::Array)
|
244
254
|
o = @store.new(PO)
|
245
|
-
a[0] = o.get_self
|
246
255
|
PEROBS.log.open(StringIO.new)
|
247
|
-
expect {
|
256
|
+
expect { a[0] = o.get_self }.to raise_error(PEROBS::FatalError)
|
248
257
|
PEROBS.log.open($stderr)
|
249
258
|
end
|
250
259
|
|
data/test/BTreeDB_spec.rb
CHANGED
@@ -56,7 +56,7 @@ describe PEROBS::BTreeDB do
|
|
56
56
|
expect(@db.include?(0)).to be false
|
57
57
|
h = {
|
58
58
|
'String' => 'What god has wrought',
|
59
|
-
'
|
59
|
+
'Integer' => 42,
|
60
60
|
'Float' => 3.14,
|
61
61
|
'True' => true,
|
62
62
|
'False' => false,
|
@@ -75,7 +75,7 @@ describe PEROBS::BTreeDB do
|
|
75
75
|
expect(@db.include?(0)).to be false
|
76
76
|
h = {
|
77
77
|
'String' => 'What god has wrought',
|
78
|
-
'
|
78
|
+
'Integer' => 42,
|
79
79
|
'Float' => 3.14,
|
80
80
|
'True' => true,
|
81
81
|
'False' => false,
|
data/test/BTree_spec.rb
CHANGED
@@ -27,13 +27,16 @@ require 'fileutils'
|
|
27
27
|
|
28
28
|
require 'spec_helper'
|
29
29
|
require 'perobs/BTree'
|
30
|
+
require 'perobs/ProgressMeter'
|
30
31
|
|
31
32
|
describe PEROBS::BTree do
|
32
33
|
|
33
34
|
before(:all) do
|
34
35
|
@db_dir = generate_db_name('BTree')
|
35
36
|
FileUtils.mkdir_p(@db_dir)
|
36
|
-
@m = PEROBS::BTree.new(@db_dir, 'btree', 11)
|
37
|
+
@m = PEROBS::BTree.new(@db_dir, 'btree', 11, PEROBS::ProgressMeter.new)
|
38
|
+
PEROBS.log.level = Logger::ERROR
|
39
|
+
PEROBS.log.open($stderr)
|
37
40
|
end
|
38
41
|
|
39
42
|
after(:all) do
|
@@ -48,6 +51,7 @@ describe PEROBS::BTree do
|
|
48
51
|
@m.open
|
49
52
|
expect(@m.to_s).to eql("o--- @1\n")
|
50
53
|
#expect(@m.to_a).to eql([])
|
54
|
+
expect(@m.check).to be true
|
51
55
|
end
|
52
56
|
|
53
57
|
it 'should support adding sequential key/value pairs' do
|
@@ -125,4 +129,49 @@ describe PEROBS::BTree do
|
|
125
129
|
end
|
126
130
|
end
|
127
131
|
|
132
|
+
it 'should survive a real-world usage test' do
|
133
|
+
@m.clear
|
134
|
+
ref = {}
|
135
|
+
0.upto(20000) do
|
136
|
+
case rand(5)
|
137
|
+
when 0
|
138
|
+
0.upto(2) do
|
139
|
+
key = rand(100000)
|
140
|
+
value = rand(10000000)
|
141
|
+
@m.insert(key, value)
|
142
|
+
ref[key] = value
|
143
|
+
end
|
144
|
+
when 1
|
145
|
+
if ref.length > 0
|
146
|
+
key = ref.keys[rand(ref.keys.length)]
|
147
|
+
expect(@m.remove(key)).to eql(ref[key])
|
148
|
+
ref.delete(key)
|
149
|
+
end
|
150
|
+
when 2
|
151
|
+
if ref.length > 0
|
152
|
+
0.upto(3) do
|
153
|
+
key = ref.keys[rand(ref.keys.length)]
|
154
|
+
expect(@m.get(key)).to eql(ref[key])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
when 3
|
158
|
+
if ref.length > 0
|
159
|
+
key = ref.keys[rand(ref.keys.length)]
|
160
|
+
value = rand(10000000)
|
161
|
+
@m.insert(key, value)
|
162
|
+
ref[key] = value
|
163
|
+
end
|
164
|
+
when 4
|
165
|
+
if rand(50) == 0
|
166
|
+
expect(@m.check).to be true
|
167
|
+
end
|
168
|
+
when 5
|
169
|
+
if rand(50) == 0
|
170
|
+
@m.close
|
171
|
+
@m.open
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
128
177
|
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2015, 2016 by Chris Schlaeger <chris@taskjuggler.org>
|
4
|
+
#
|
5
|
+
# This file contains tests for Array that are similar to the tests for the
|
6
|
+
# Array implementation in MRI. The ideas of these tests were replicated in
|
7
|
+
# this code.
|
8
|
+
#
|
9
|
+
# MIT License
|
10
|
+
#
|
11
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
12
|
+
# a copy of this software and associated documentation files (the
|
13
|
+
# "Software"), to deal in the Software without restriction, including
|
14
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
15
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
16
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
17
|
+
# the following conditions:
|
18
|
+
#
|
19
|
+
# The above copyright notice and this permission notice shall be
|
20
|
+
# included in all copies or substantial portions of the Software.
|
21
|
+
#
|
22
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
23
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
24
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
25
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
26
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
27
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
28
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
29
|
+
|
30
|
+
require 'spec_helper'
|
31
|
+
|
32
|
+
require 'perobs'
|
33
|
+
require 'perobs/BigArray'
|
34
|
+
|
35
|
+
NODE_ENTRIES = 6
|
36
|
+
|
37
|
+
describe PEROBS::BigArray do
|
38
|
+
|
39
|
+
before(:all) do
|
40
|
+
@db_name = generate_db_name(__FILE__)
|
41
|
+
@store = PEROBS::Store.new(@db_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
before(:each) do
|
45
|
+
@store['array'] = @a = @store.new(PEROBS::BigArray, NODE_ENTRIES)
|
46
|
+
end
|
47
|
+
|
48
|
+
after(:each) do
|
49
|
+
@store['array'] = @a = nil
|
50
|
+
@store.gc
|
51
|
+
end
|
52
|
+
|
53
|
+
after(:all) do
|
54
|
+
@store.delete_store
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should be empty on create' do
|
58
|
+
expect(@a.empty?).to be true
|
59
|
+
expect(@a.length).to eq(0)
|
60
|
+
expect(@a.check).to be true
|
61
|
+
expect(@a[0]).to be nil
|
62
|
+
expect(@a.first).to be nil
|
63
|
+
expect(@a.last).to be nil
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should append the first element' do
|
67
|
+
@a << 0
|
68
|
+
expect(@a.empty?).to be false
|
69
|
+
expect(@a[0]).to eq(0)
|
70
|
+
expect(@a.first).to eq(0)
|
71
|
+
expect(@a.last).to eq(0)
|
72
|
+
expect(@a.length).to eq(1)
|
73
|
+
expect(@a.check).to be true
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should fill 10 nodes with appends' do
|
77
|
+
(10 * NODE_ENTRIES).times do |i|
|
78
|
+
@a << i
|
79
|
+
expect(@a.check).to be true
|
80
|
+
expect(@a.length).to eq(i + 1)
|
81
|
+
end
|
82
|
+
expect(@a.first).to eq(0)
|
83
|
+
expect(@a.last).to eq(10 * NODE_ENTRIES - 1)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should insert at 0' do
|
87
|
+
@a.insert(0, 0)
|
88
|
+
expect(@a.empty?).to be false
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should insert at end' do
|
92
|
+
0.upto(3 * NODE_ENTRIES) do |i|
|
93
|
+
@a.insert(i, i)
|
94
|
+
expect(@a.check).to be true
|
95
|
+
expect(@a.length).to eq(i + 1)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should insert in the middle' do
|
100
|
+
0.upto(NODE_ENTRIES - 1) do |i|
|
101
|
+
@a << 9999
|
102
|
+
end
|
103
|
+
0.upto(3 * NODE_ENTRIES) do |i|
|
104
|
+
@a.insert(i, i)
|
105
|
+
expect(@a.check).to be true
|
106
|
+
expect(@a.length).to eq(i + 1 + NODE_ENTRIES)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should convert to a Ruby Array' do
|
111
|
+
expect(@a.to_a).to eql([])
|
112
|
+
(3 * NODE_ENTRIES).times do |i|
|
113
|
+
@a << i
|
114
|
+
end
|
115
|
+
expect(@a.to_a).to eql((0..3 * NODE_ENTRIES - 1).to_a)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should support the [] operator' do
|
119
|
+
expect(@a[0]).to be nil
|
120
|
+
expect(@a[-1]).to be nil
|
121
|
+
@a[0] = 0
|
122
|
+
expect(@a[0]).to eq(0)
|
123
|
+
1.upto(3 * NODE_ENTRIES) do |i|
|
124
|
+
@a.insert(i, i)
|
125
|
+
end
|
126
|
+
0.upto(3 * NODE_ENTRIES) do |i|
|
127
|
+
expect(@a[i]).to eq(i)
|
128
|
+
end
|
129
|
+
expect(@a[3 * NODE_ENTRIES + 1]).to be nil
|
130
|
+
0.upto(3 * NODE_ENTRIES) do |i|
|
131
|
+
expect(@a[-3 * NODE_ENTRIES + i - 1]).to eq(i)
|
132
|
+
end
|
133
|
+
expect(@a[-3 * NODE_ENTRIES - 2]).to be nil
|
134
|
+
(3 * NODE_ENTRIES + 1).upto(4 * NODE_ENTRIES) do |i|
|
135
|
+
expect(@a[i]).to be nil
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should delete elements' do
|
140
|
+
expect(@a.delete_at(0)).to be nil
|
141
|
+
expect(@a.length).to eq(0)
|
142
|
+
expect(@a.check).to be true
|
143
|
+
expect(@a.delete_at(-1)).to be nil
|
144
|
+
expect(@a.length).to eq(0)
|
145
|
+
expect(@a.check).to be true
|
146
|
+
@a << 0
|
147
|
+
expect(@a.delete_at(0)).to eql(0)
|
148
|
+
expect(@a.length).to eq(0)
|
149
|
+
expect(@a.check).to be true
|
150
|
+
|
151
|
+
n = 5 * NODE_ENTRIES
|
152
|
+
0.upto(n) { |i| @a.insert(i, i) }
|
153
|
+
0.upto(n) do |i|
|
154
|
+
expect(@a.delete_at(0)).to eql(i)
|
155
|
+
expect(@a.check).to be true
|
156
|
+
end
|
157
|
+
|
158
|
+
0.upto(n) { |i| @a.insert(i, i) }
|
159
|
+
n.downto(0) do |i|
|
160
|
+
expect(@a.delete_at(-1)).to eql(i)
|
161
|
+
expect(@a.check).to be true
|
162
|
+
end
|
163
|
+
|
164
|
+
n = 15 * NODE_ENTRIES
|
165
|
+
0.upto(n - 1) { |i| @a.insert(i, i) }
|
166
|
+
expect(@a.delete_at(n + 2)).to be nil
|
167
|
+
expect(@a.delete_at(-(n + 2))).to be nil
|
168
|
+
expect(@a.size).to eql(n)
|
169
|
+
|
170
|
+
n.times do |i|
|
171
|
+
idx = rand(@a.size)
|
172
|
+
@a.delete_at(idx)
|
173
|
+
expect(@a.size).to be (n - 1 - i)
|
174
|
+
expect(@a.check).to be true
|
175
|
+
end
|
176
|
+
expect(@a.size).to eql(0)
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should fill the gaps' do
|
180
|
+
1.upto(4) do |i|
|
181
|
+
idx = i * NODE_ENTRIES * NODE_ENTRIES
|
182
|
+
@a[idx] = idx
|
183
|
+
expect(@a[idx - 1]).to be nil
|
184
|
+
expect(@a[idx + 1]).to be nil
|
185
|
+
expect(@a.check).to be true
|
186
|
+
end
|
187
|
+
expect(@a[0]).to be nil
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should insert after a gap' do
|
191
|
+
ref = []
|
192
|
+
10.times do |i|
|
193
|
+
idx = 10 + i * 3
|
194
|
+
@a[idx] = idx
|
195
|
+
ref[idx] = idx
|
196
|
+
expect(@a[idx]).to eql(idx)
|
197
|
+
expect(@a.check).to be true
|
198
|
+
end
|
199
|
+
10.times do |i|
|
200
|
+
idx = i * 5
|
201
|
+
@a[idx] = idx
|
202
|
+
ref[idx] = idx
|
203
|
+
expect(@a[idx]).to eql(idx)
|
204
|
+
expect(@a.check).to be true
|
205
|
+
end
|
206
|
+
expect(@a.check).to be true
|
207
|
+
expect(@a.to_a).to eql(ref)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should iterate over all values' do
|
211
|
+
n = 3 * NODE_ENTRIES
|
212
|
+
0.upto(n) { |i| @a.insert(i, i) }
|
213
|
+
|
214
|
+
i = 0
|
215
|
+
@a.each do |v|
|
216
|
+
expect(v).to eql(i)
|
217
|
+
i += 1
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should iterate over all values in reverse order' do
|
222
|
+
n = 3 * NODE_ENTRIES
|
223
|
+
0.upto(n) { |i| @a.insert(i, i) }
|
224
|
+
|
225
|
+
i = 0
|
226
|
+
@a.reverse_each do |v|
|
227
|
+
expect(v).to eql(n - i)
|
228
|
+
i += 1
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'should insert at the beginning' do
|
233
|
+
(5 * NODE_ENTRIES).downto(0) do |i|
|
234
|
+
@a.insert(0, i)
|
235
|
+
end
|
236
|
+
expect(@a.check).to be true
|
237
|
+
a = Array.new(5 * NODE_ENTRIES + 1) { |i| i }
|
238
|
+
expect(@a.to_a).to eq(a)
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'should persist the data' do
|
242
|
+
db_name = generate_db_name(__FILE__ + "_persist")
|
243
|
+
store = PEROBS::Store.new(db_name)
|
244
|
+
store['array'] = a = store.new(PEROBS::BigArray, NODE_ENTRIES)
|
245
|
+
|
246
|
+
(3 * NODE_ENTRIES).times do |i|
|
247
|
+
a.insert(i, i)
|
248
|
+
end
|
249
|
+
expect(a.length).to eq(3 * NODE_ENTRIES)
|
250
|
+
store.exit
|
251
|
+
|
252
|
+
store = PEROBS::Store.new(db_name)
|
253
|
+
a = store['array']
|
254
|
+
(3 * NODE_ENTRIES).times do |i|
|
255
|
+
expect(a[i]).to eql(i)
|
256
|
+
end
|
257
|
+
expect(a.length).to eq(3 * NODE_ENTRIES)
|
258
|
+
store.delete_store
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|