perobs 0.0.1 → 1.0.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.
@@ -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