Skip to content

Commit

Permalink
Major problems with FileStorage are fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
Yurii Rashkovskii committed May 22, 2008
1 parent 72805eb commit 0c90865
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 22 deletions.
20 changes: 16 additions & 4 deletions lib/strokedb/store.rb
Expand Up @@ -49,11 +49,11 @@ def save!(doc)
@index_store.save!
end
end

def save_as_head!(doc)
@storage.save_as_head!(doc,timestamp)
end



def each(options = {},&block)
Expand Down Expand Up @@ -83,18 +83,30 @@ def inspect
def autosync!
@autosync_mutex ||= Mutex.new
@autosync = nil if @autosync && !@autosync.status
at_exit { stop_autosync! }
@stop_autosync = false
at_exit do
stop_autosync! unless @stop_autosync
end
@autosync ||= Thread.new do
until @stop_autosync
@autosync_mutex.synchronize { storage.sync_chained_storages! }
sleep(1)
end
end
end

def autosync?
@autosync && !@autosync.status
end

def stop_autosync!
if @autosync_mutex
@autosync_mutex.synchronize { @stop_autosync = true; storage.sync_chained_storages! }
@autosync_mutex.synchronize do
unless @stop_autosync
@stop_autosync = true
storage.sync_chained_storages!
end
end
end
end

Expand Down
29 changes: 17 additions & 12 deletions lib/strokedb/stores/file_storage.rb
Expand Up @@ -7,14 +7,14 @@ def initialize(options = {})
end

def save_as_head!(document, timestamp)
write(document.uuid, document, timestamp)
save!(document,timestamp, :head => true)
end

def find(uuid, version=nil, opts = {}, &block)
uuid_version = uuid + (version ? ".#{version}" : "")
key = uuid.to_raw_uuid + (version ? version.to_raw_uuid : RAW_FULL_UUID)
if (ptr = @uindex.find(key)) && (ptr != "\x00" * 20) # no way ptr will be zero
raw_doc = StrokeDB::deserialize(read_at_ptr(ptr))[0]
if (ptr = @uindex.find(key)) && (ptr[0,20] != "\x00" * 20) # no way ptr will be zero
raw_doc = StrokeDB::deserialize(read_at_ptr(ptr[0,20]))
unless opts[:no_instantiation]
doc = Document.from_raw(opts[:store], raw_doc.freeze, &block) # FIXME: there should be a better source for store (probably)
doc.extend(VersionedDocument) if version
Expand All @@ -26,8 +26,10 @@ def find(uuid, version=nil, opts = {}, &block)
end

def include?(uuid,version=nil)
!!find(uuid,version,:no_instantiation => true)
key = uuid.to_raw_uuid + (version ? version.to_raw_uuid : RAW_FULL_UUID)
!@uindex.find(key).nil?
end

# using #include? to match with Array, but #contains sounds much nicer
alias_method :contains?, :include?

Expand All @@ -40,20 +42,23 @@ def head_version(uuid, opts = {})
def each(options = {})
after = options[:after_timestamp]
include_versions = options[:include_versions]
@container.each do |key, value|
next if after && (value[1] <= after)
if uuid_match = key.match(/^#{UUID_RE}$/) || (include_versions && uuid_match = key.match(/#{UUID_RE}./) )
yield Document.from_raw(options[:store],value[0])
@uindex.each do |key, value|
timestamp = StrokeDB.deserialize(read_at_ptr(value[20,20]))
next if after && (timestamp <= after)
if key[16,16] == RAW_FULL_UUID || include_versions
yield Document.from_raw(options[:store],StrokeDB.deserialize(read_at_ptr(value[0,20])))
end
end
end

def perform_save!(document, timestamp, options = {})
position = @archive.insert(StrokeDB::serialize([document,timestamp.counter]))
ts_position = @archive.insert(StrokeDB::serialize(timestamp.counter))
position = @archive.insert(StrokeDB::serialize(document))
ts_ptr = DistributedPointer.pack(@archive.raw_uuid,ts_position)
ptr = DistributedPointer.pack(@archive.raw_uuid,position)
uuid = document.raw_uuid
@uindex.insert(uuid + RAW_FULL_UUID, ptr) if options[:head] || !document.is_a?(VersionedDocument)
@uindex.insert(uuid + document.version.to_raw_uuid, ptr) unless options[:head]
@uindex.insert(uuid + RAW_FULL_UUID, ptr + ts_ptr) if options[:head] || !document.is_a?(VersionedDocument)
@uindex.insert(uuid + document.version.to_raw_uuid, ptr + ts_ptr) unless options[:head]
rescue ArchiveVolume::VolumeCapacityExceeded
create_new_archive!
end
Expand Down Expand Up @@ -111,7 +116,7 @@ def close!
def initialize_files
FileUtils.mkdir_p(@options['path'])
@archive = ArchiveVolume.new(:path => @options['path'], :uuid => last_archive_uuid)
@uindex = FixedLengthSkiplistVolume.new(:path => File.join(@options['path'],'uindex'), :key_length => 32 , :value_length => 20)
@uindex = FixedLengthSkiplistVolume.new(:path => File.join(@options['path'],'uindex'), :key_length => 32 , :value_length => 40)
end

end
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/strokedb/stores/store_spec.rb
Expand Up @@ -84,7 +84,7 @@
end

it "should report versioned document that does not exist as such" do
@store.include?(@documents.first.uuid,'ouch, there is no way such version could be generated').should == false
@store.include?(@documents.first.uuid,StrokeDB::Util.random_uuid).should == false
end

it "should report document that does not exist as such" do
Expand All @@ -102,7 +102,7 @@
end

it "should not find a versioned document with version that does not exist" do
@store.find(@documents.first.uuid,'absolutely absurd version').should be_nil
@store.find(@documents.first.uuid,StrokeDB::Util.random_uuid).should be_nil
end


Expand Down
23 changes: 19 additions & 4 deletions spec/spec_helper.rb
Expand Up @@ -13,15 +13,15 @@ def setup_default_store(store=nil)
end
@path = TEMP_STORAGES
FileUtils.rm_rf @path

@storage = if ENV['STORAGE'].to_s.downcase == 'file'
StrokeDB::FileStorage.new(:path => @path + '/file_storage')
else
StrokeDB::MemoryStorage.new
end
StrokeDB.stub!(:default_store).and_return(StrokeDB::Store.new(:storage => @storage,:index => @index,
:path => @path))

$store = StrokeDB::Store.new(:storage => @storage,:index => @index, :path => @path)
StrokeDB.stub!(:default_store).and_return($store)
StrokeDB.default_store
end

Expand All @@ -40,4 +40,19 @@ def setup_index(store=nil)
@index.document_store = store
store.index_store = @index
@index
end

Spec::Runner.configure do |config|
config.after(:all) do

if ENV['STORAGE'].to_s.downcase == 'file'
ObjectSpace.each_object do |obj|
obj.stop_autosync! if obj.is_a?(Store)
end

ObjectSpace.each_object do |obj|
obj.close if obj.is_a?(::File) rescue nil
end
end
end
end

0 comments on commit 0c90865

Please sign in to comment.