perobs 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,125 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # = ClassMap.rb -- Persistent Ruby Object Store
4
+ #
5
+ # Copyright (c) 2015 by Chris Schlaeger <chris@taskjuggler.org>
6
+ #
7
+ # MIT License
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+
28
+ require 'perobs/DataBase'
29
+
30
+ module PEROBS
31
+
32
+ # PEROBS will usually store objects with a relatively small number of
33
+ # classes. Rather than storing the class name with each object, we map the
34
+ # class name to a numerical ID that represents the class in the store. This
35
+ # class handles the mapping and can convert class names into IDs and vice
36
+ # versa.
37
+ class ClassMap
38
+
39
+ # Create a ClassMap object for a given data base.
40
+ # @param db [DataBase]
41
+ def initialize(db)
42
+ @db = db
43
+ @by_class = {}
44
+ @by_id = []
45
+ read_map
46
+ end
47
+
48
+ # Get the ID for a given class.
49
+ # @param klass [String] Class
50
+ # @return [Fixnum] ID. If klass is not yet known a new ID will be
51
+ # allocated.
52
+ def class_to_id(klass)
53
+ @by_class[klass] || new_id(klass)
54
+ end
55
+
56
+ # Get the klass for a given ID.
57
+ # @param id [Fixnum]
58
+ # @return [String] String version of the class
59
+ def id_to_class(id)
60
+ @by_id[id]
61
+ end
62
+
63
+ # Rename a set of classes to new names.
64
+ # @param rename_map [Hash] Hash that maps old names to new names
65
+ def rename(rename_map)
66
+ @by_id.each.with_index do |klass, id|
67
+ # Some entries can be nil. Ignore them.
68
+ next unless klass
69
+
70
+ if (new_name = rename_map[klass])
71
+ # We have a rename request. Update the current @by_id entry.
72
+ @by_id[id] = new_name
73
+ # Remove the old class name from @by_class hash.
74
+ @by_class.delete(klass)
75
+ # Insert the new one with the current ID.
76
+ @by_class[new_name] = id
77
+ end
78
+ end
79
+ end
80
+
81
+ # Delete all classes unless they are contained in _classes_.
82
+ # @param classes [Array of String] List of the class names
83
+ def keep(classes)
84
+ @by_id.each.with_index do |klass, id|
85
+ unless classes.include?(klass)
86
+ # Delete the class from the @by_id list by setting the entry to nil.
87
+ @by_id[id] = nil
88
+ # Delete the corresponding @by_class entry as well.
89
+ @by_class.delete(klass)
90
+ end
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def new_id(klass)
97
+ # Find the first 'nil' entry and return the index.
98
+ idx = @by_id.find_index(nil) || @by_id.length
99
+
100
+ # Insert the new class/ID touple into the hash and reverse map.
101
+ @by_class[klass] = idx
102
+ @by_id[idx] = klass
103
+ # Write the updated version into the data base.
104
+ write_map
105
+
106
+ # Return the new ID.
107
+ idx
108
+ end
109
+
110
+ def read_map
111
+ # Get the hash from the data base
112
+ @by_class = @db.get_hash('class_map')
113
+ # Build the reverse map from the hash.
114
+ @by_class.each do |klass, id|
115
+ @by_id[id] = klass
116
+ end
117
+ end
118
+
119
+ def write_map
120
+ @db.put_hash('class_map', @by_class)
121
+ end
122
+
123
+ end
124
+
125
+ end
@@ -41,6 +41,7 @@ module PEROBS
41
41
 
42
42
  def initialize(serializer = :json)
43
43
  @serializer = serializer
44
+ @config = {}
44
45
  end
45
46
 
46
47
  # Serialize the given object using the object serializer.
@@ -83,8 +84,7 @@ module PEROBS
83
84
  end
84
85
 
85
86
  # Generate a new unique ID. It uses random numbers between 0 and 2**64 -
86
- # 1. Deriving classes can overwrite this method. They must implement a
87
- # include? method.
87
+ # 1.
88
88
  # @return [Fixnum or Bignum]
89
89
  def new_id
90
90
  begin
@@ -97,6 +97,25 @@ module PEROBS
97
97
  id
98
98
  end
99
99
 
100
+ # Check a config option and adjust it if needed.
101
+ # @param name [String] Name of the config option.
102
+ def check_option(name)
103
+ value = instance_variable_get('@' + name)
104
+
105
+ if @config.include?(name)
106
+ # The database already existed and has a setting for this config
107
+ # option. If it does not match the instance variable, adjust the
108
+ # instance variable accordingly.
109
+ unless @config[name] == value
110
+ instance_variable_set('@' + name, @config[name])
111
+ end
112
+ else
113
+ # There is no such config option yet. Create it with the value of the
114
+ # corresponding instance variable.
115
+ @config[name] = value
116
+ end
117
+ end
118
+
100
119
  private
101
120
 
102
121
  # Ensure that we have a directory to store the DB items.
data/lib/perobs/Hash.rb CHANGED
@@ -163,6 +163,14 @@ module PEROBS
163
163
  @data = data
164
164
  end
165
165
 
166
+ # Textual dump for debugging purposes
167
+ # @return [String]
168
+ def inspect
169
+ "{\n" +
170
+ @data.map { |k, v| " #{k.inspect}=>#{v.inspect}" }.join(",\n") +
171
+ "\n}\n"
172
+ end
173
+
166
174
  private
167
175
 
168
176
  def _serialize
data/lib/perobs/Object.rb CHANGED
@@ -133,6 +133,17 @@ module PEROBS
133
133
  end
134
134
  end
135
135
 
136
+ # Textual dump for debugging purposes
137
+ # @return [String]
138
+ def inspect
139
+ "{\n" +
140
+ self.class.attributes.map do |attr|
141
+ ivar = ('@' + attr.to_s).to_sym
142
+ " #{attr.inspect}=>#{instance_variable_get(ivar).inspect}"
143
+ end.join(",\n") +
144
+ "\n}\n"
145
+ end
146
+
136
147
  private
137
148
 
138
149
  # Return a single data structure that holds all persistent data for this
@@ -25,6 +25,8 @@
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
+ require 'perobs/ClassMap'
29
+
28
30
  module PEROBS
29
31
 
30
32
  # This class is used to replace a direct reference to another Ruby object by
@@ -32,6 +34,13 @@ module PEROBS
32
34
  # since it's no longer referenced once it has been evicted from the
33
35
  # PEROBS::Store cache.
34
36
  class POReference < Struct.new(:id)
37
+
38
+ # Textual dump for debugging purposes
39
+ # @return [String]
40
+ def inspect
41
+ "@#{id}"
42
+ end
43
+
35
44
  end
36
45
 
37
46
  # Base class for all persistent objects. It provides the functionality
@@ -62,7 +71,7 @@ module PEROBS
62
71
  @_stash_map = nil
63
72
 
64
73
  db_obj = {
65
- 'class' => self.class.to_s,
74
+ 'class_id' => @store.class_map.class_to_id(self.class.to_s),
66
75
  'data' => _serialize
67
76
  }
68
77
  @store.db.put_object(db_obj, @_id)
@@ -74,8 +83,9 @@ module PEROBS
74
83
  # Read the object from database.
75
84
  db_obj = store.db.get_object(id)
76
85
 
86
+ klass = store.class_map.id_to_class(db_obj['class_id'])
77
87
  # Call the constructor of the specified class.
78
- obj = Object.const_get(db_obj['class']).new(store)
88
+ obj = Object.const_get(klass).new(store)
79
89
  # The object gets created with a new ID by default. We need to restore
80
90
  # the old one.
81
91
  obj._change_id(id)
data/lib/perobs/Store.rb CHANGED
@@ -26,8 +26,8 @@
26
26
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
27
 
28
28
  require 'perobs/Cache'
29
- require 'perobs/FileSystemDB'
30
- require 'perobs/HashedBlocksDB'
29
+ require 'perobs/ClassMap'
30
+ require 'perobs/BTreeDB'
31
31
  require 'perobs/Object'
32
32
  require 'perobs/Hash'
33
33
  require 'perobs/Array'
@@ -49,16 +49,16 @@ module PEROBS
49
49
  # objects are all going to persistent objects again.
50
50
  class Store
51
51
 
52
- attr_reader :db, :cache
52
+ attr_reader :db, :cache, :class_map
53
53
 
54
54
  # Create a new Store.
55
55
  # @param data_base [String] the name of the database
56
56
  # @param options [Hash] various options to affect the operation of the
57
57
  # database. Currently the following options are supported:
58
58
  # :engine : The class that provides the back-end storage
59
- # engine. By default HashedBlocksDB is used. A user
59
+ # engine. By default BTreeDB is used. A user
60
60
  # can provide it's own storage engine that must
61
- # conform to the same API exposed by HashedBlocksDB.
61
+ # conform to the same API exposed by BTreeBlobsDB.
62
62
  # :cache_bits : the number of bits used for cache indexing. The
63
63
  # cache will hold 2 to the power of bits number of
64
64
  # objects. We have separate caches for reading and
@@ -81,7 +81,10 @@ module PEROBS
81
81
  # Unfortunately, it is 10x slower than marshal.
82
82
  def initialize(data_base, options = {})
83
83
  # Create a backing store handler
84
- @db = (options[:engine] || HashedBlocksDB).new(data_base, options)
84
+ @db = (options[:engine] || BTreeDB).new(data_base, options)
85
+ # Create a map that can translate classes to numerical IDs and vice
86
+ # versa.
87
+ @class_map = ClassMap.new(@db)
85
88
 
86
89
  # The Cache reduces read and write latencies by keeping a subset of the
87
90
  # objects in memory.
@@ -192,6 +195,9 @@ module PEROBS
192
195
  # @param repair [TrueClass/FalseClass] true if a repair attempt should be
193
196
  # made.
194
197
  def check(repair = true)
198
+ # Run basic consistency checks first.
199
+ @db.check_db(repair)
200
+
195
201
  @db.clear_marks
196
202
  # A buffer to hold a working set of object IDs.
197
203
  stack = []
@@ -269,12 +275,20 @@ module PEROBS
269
275
  end
270
276
  end
271
277
 
278
+ # Rename classes of objects stored in the data base.
279
+ # @param rename_map [Hash] Hash that maps the old name to the new name
280
+ def rename_classes(rename_map)
281
+ @class_map.rename(rename_map)
282
+ end
283
+
272
284
  private
273
285
 
274
286
  # Mark phase of a mark-and-sweep garbage collector. It will mark all
275
287
  # objects that are reachable from the root objects.
276
288
  def mark
277
- each
289
+ classes = Set.new
290
+ each { |obj| classes.add(obj.class) }
291
+ @class_map.keep(classes.map { |c| c.to_s })
278
292
  end
279
293
 
280
294
  # Sweep phase of a mark-and-sweep garbage collector. It will remove all
@@ -1,4 +1,4 @@
1
1
  module PEROBS
2
2
  # The version number
3
- VERSION = "0.0.1"
3
+ VERSION = "1.0.0"
4
4
  end
@@ -28,12 +28,12 @@ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
28
28
  require 'fileutils'
29
29
  require 'time'
30
30
 
31
- require 'perobs/FileSystemDB'
31
+ require 'perobs/BTreeDB'
32
32
 
33
- class TempStruct < Struct.new(:first, :second, :third)
34
- end
33
+ describe PEROBS::BTreeDB do
35
34
 
36
- describe PEROBS::FileSystemDB do
35
+ class UStruct < Struct.new(:first, :second, :third)
36
+ end
37
37
 
38
38
  before(:all) do
39
39
  FileUtils.rm_rf('fs_test')
@@ -44,12 +44,20 @@ describe PEROBS::FileSystemDB do
44
44
  end
45
45
 
46
46
  it 'should create database' do
47
- @db = PEROBS::FileSystemDB.new('fs_test')
47
+ @db = PEROBS::BTreeDB.new('fs_test')
48
48
  Dir.exists?('fs_test').should be_true
49
49
  end
50
50
 
51
+ it 'should write and read a simple Hash' do
52
+ @db = PEROBS::BTreeDB.new('fs_test')
53
+ @db.get_hash('test').should == {}
54
+ h = { 'A' => 1, 'B' => 2, 'D' => 4 }
55
+ @db.put_hash('test', h)
56
+ @db.get_hash('test').should == h
57
+ end
58
+
51
59
  it 'should support object insertion and retrieval' do
52
- @db = PEROBS::FileSystemDB.new('fs_test')
60
+ @db = PEROBS::BTreeDB.new('fs_test')
53
61
  @db.include?(0).should be_false
54
62
  h = {
55
63
  'String' => 'What god has wrought',
@@ -68,7 +76,7 @@ describe PEROBS::FileSystemDB do
68
76
 
69
77
  it 'should support most Ruby objects types' do
70
78
  [ :marshal, :yaml ].each do |serializer|
71
- @db = PEROBS::FileSystemDB.new('fs_test', { :serializer => serializer })
79
+ @db = PEROBS::BTreeDB.new('fs_test', { :serializer => serializer })
72
80
  @db.include?(0).should be_false
73
81
  h = {
74
82
  'String' => 'What god has wrought',
@@ -79,17 +87,53 @@ describe PEROBS::FileSystemDB do
79
87
  'nil' => nil,
80
88
  'Array' => [ 0, 1, 2, 3 ],
81
89
  'Time' => Time.parse('2015-05-14-13:52:17'),
82
- 'Struct' => TempStruct.new("Where's", 'your', 'towel?')
90
+ 'Struct' => UStruct.new("Where's", 'your', 'towel?')
83
91
  }
84
92
  @db.put_object(h, 0)
85
93
  @db.include?(0).should be_true
86
94
  @db.check(0, false).should be_true
87
95
  @db.get_object(0).should == h
96
+ FileUtils.rm_rf('fs_test')
97
+ end
98
+ end
99
+
100
+ it 'should put and get multiple objects in same dir' do
101
+ @db = PEROBS::BTreeDB.new('fs_test')
102
+ 0.upto(10) do |i|
103
+ @db.put_object({ "foo #{i}" => i }, i)
88
104
  end
105
+ 0.upto(10) do |i|
106
+ @db.get_object(i)["foo #{i}"].should == i
107
+ end
108
+ end
109
+
110
+ it 'should handle deleted objects propery' do
111
+ @db = PEROBS::BTreeDB.new('fs_test')
112
+ @db.put_object({ 'a' => 'a' * 257 }, 0)
113
+ @db.put_object({ 'b' => 'b' * 513 }, 1)
114
+ @db.put_object({ 'c' => 'c' * 129 }, 2)
115
+ @db.put_object({ 'd' => 'd' * 1025 }, 3)
116
+ # Delete some objects
117
+ @db.clear_marks
118
+ @db.mark(0)
119
+ @db.mark(2)
120
+ @db.delete_unmarked_objects
121
+
122
+ @db.put_object({ 'A' => 'a' * 257 }, 4)
123
+ @db.put_object({ 'B' => 'b' * 513 }, 5)
124
+ @db.put_object({ 'C' => 'c' * 129 }, 6)
125
+ @db.put_object({ 'D' => 'd' * 1025 }, 7)
126
+
127
+ @db.get_object(0).should == { 'a' => 'a' * 257 }
128
+ @db.get_object(2).should == { 'c' => 'c' * 129 }
129
+ @db.get_object(4).should == { 'A' => 'a' * 257 }
130
+ @db.get_object(5).should == { 'B' => 'b' * 513 }
131
+ @db.get_object(6).should == { 'C' => 'c' * 129 }
132
+ @db.get_object(7).should == { 'D' => 'd' * 1025 }
89
133
  end
90
134
 
91
135
  it 'should mark objects and detect markings' do
92
- @db = PEROBS::FileSystemDB.new('fs_test')
136
+ @db = PEROBS::BTreeDB.new('fs_test')
93
137
  h = { 'a' => 'z' }
94
138
  @db.put_object(h, 1)
95
139
  @db.put_object(h, 2)
@@ -0,0 +1,70 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2015 by Chris Schlaeger <chris@taskjuggler.org>
4
+ #
5
+ # MIT License
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+
26
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
27
+
28
+ require 'perobs/ClassMap'
29
+ require 'perobs/BTreeDB'
30
+
31
+ describe PEROBS::ClassMap do
32
+
33
+ before(:all) do
34
+ FileUtils.rm_rf('fs_test')
35
+ @db = PEROBS::BTreeDB.new('fs_test')
36
+ @map = PEROBS::ClassMap.new(@db)
37
+ end
38
+
39
+ after(:all) do
40
+ FileUtils.rm_rf('fs_test')
41
+ end
42
+
43
+ it 'should return nil for an unknown ID' do
44
+ @map.id_to_class(0).should be_nil
45
+ end
46
+
47
+ it 'should add a class' do
48
+ @map.class_to_id('Foo').should == 0
49
+ end
50
+
51
+ it 'should find the class again' do
52
+ @map.id_to_class(0).should == 'Foo'
53
+ end
54
+
55
+ it 'should still return nil for an unknown ID' do
56
+ @map.id_to_class(1).should be_nil
57
+ end
58
+
59
+ it 'should forget classes not in keep list' do
60
+ @map.class_to_id('Bar').should == 1
61
+ @map.class_to_id('Foobar').should == 2
62
+ @map.keep([ 'Bar' ])
63
+ @map.id_to_class(0).should be_nil
64
+ @map.id_to_class(1).should == 'Bar'
65
+ @map.id_to_class(2).should be_nil
66
+ @map.class_to_id('Foo1').should == 0
67
+ @map.class_to_id('Foo2').should == 2
68
+ end
69
+
70
+ end
data/spec/Store_spec.rb CHANGED
@@ -45,6 +45,19 @@ class Person < PEROBS::Object
45
45
 
46
46
  end
47
47
 
48
+ class PersonN < PEROBS::Object
49
+
50
+ po_attr :name, :zip, :bmi, :married, :related, :relatives
51
+
52
+ def initialize(store)
53
+ super
54
+ init_attr(:name, '')
55
+ init_attr(:bmi, 22.2)
56
+ init_attr(:married, false)
57
+ end
58
+
59
+ end
60
+
48
61
  describe PEROBS::Store do
49
62
 
50
63
  before(:all) do
@@ -96,7 +109,7 @@ describe PEROBS::Store do
96
109
 
97
110
  @store.sync
98
111
 
99
- @store = PEROBS::Store.new('test_db', { :serializer => serializer })
112
+ @store = PEROBS::Store.new('test_db')
100
113
  john = @store['john']
101
114
  john.name.should == 'John'
102
115
  john.zip.should == 4060
@@ -127,6 +140,34 @@ describe PEROBS::Store do
127
140
  end
128
141
  end
129
142
 
143
+ it 'should support renaming of classes' do
144
+ @store = PEROBS::Store.new('test_db')
145
+ @store['john'] = john = Person.new(@store)
146
+ john.name = 'John'
147
+ john.zip = 4060
148
+ john.bmi = 25.5
149
+ @store['jane'] = jane = Person.new(@store)
150
+ jane.name = 'Jane'
151
+ jane.related = john
152
+ jane.married = true
153
+ jane.relatives = 'test'
154
+
155
+ @store.sync
156
+
157
+ @store = PEROBS::Store.new('test_db')
158
+ @store.rename_classes({ 'Person' => 'PersonN' })
159
+ john = @store['john']
160
+ john.name.should == 'John'
161
+ john.zip.should == 4060
162
+ john.bmi.should == 25.5
163
+ john.married.should be_false
164
+ john.related.should be_nil
165
+ jane = @store['jane']
166
+ jane.name.should == 'Jane'
167
+ jane.related.should == john
168
+ jane.married.should be_true
169
+ end
170
+
130
171
  it 'should detect modification to non-working objects' do
131
172
  @store = PEROBS::Store.new('test_db', :cache_bits => 3)
132
173
  0.upto(20) do |i|
@@ -346,7 +387,7 @@ describe PEROBS::Store do
346
387
  end
347
388
 
348
389
  it 'should survive a real world usage test' do
349
- options = { :engine => PEROBS::HashedBlocksDB, :dir_nibbles => 1 }
390
+ options = { :engine => PEROBS::BTreeDB, :dir_bits => 4 }
350
391
  @store = PEROBS::Store.new('test_db', options)
351
392
  ref = {}
352
393
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Schlaeger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-29 00:00:00.000000000 Z
11
+ date: 2015-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,19 +66,20 @@ files:
66
66
  - Rakefile
67
67
  - lib/perobs.rb
68
68
  - lib/perobs/Array.rb
69
- - lib/perobs/BlockDB.rb
69
+ - lib/perobs/BTreeBlob.rb
70
+ - lib/perobs/BTreeDB.rb
70
71
  - lib/perobs/Cache.rb
72
+ - lib/perobs/ClassMap.rb
71
73
  - lib/perobs/DataBase.rb
72
- - lib/perobs/FileSystemDB.rb
73
74
  - lib/perobs/Hash.rb
74
- - lib/perobs/HashedBlocksDB.rb
75
75
  - lib/perobs/Object.rb
76
76
  - lib/perobs/ObjectBase.rb
77
77
  - lib/perobs/Store.rb
78
78
  - lib/perobs/version.rb
79
79
  - perobs.gemspec
80
80
  - spec/Array_spec.rb
81
- - spec/FileSystemDB_spec.rb
81
+ - spec/BTreeDB_spec.rb
82
+ - spec/ClassMap_spec.rb
82
83
  - spec/Hash_spec.rb
83
84
  - spec/Object_spec.rb
84
85
  - spec/Store_spec.rb
@@ -113,7 +114,8 @@ specification_version: 4
113
114
  summary: Persistent Ruby Object Store
114
115
  test_files:
115
116
  - spec/Array_spec.rb
116
- - spec/FileSystemDB_spec.rb
117
+ - spec/BTreeDB_spec.rb
118
+ - spec/ClassMap_spec.rb
117
119
  - spec/Hash_spec.rb
118
120
  - spec/Object_spec.rb
119
121
  - spec/Store_spec.rb