lib/perobs/FlatFile.rb in perobs-2.4.1 vs lib/perobs/FlatFile.rb in perobs-2.4.2
- old
+ new
@@ -79,20 +79,24 @@
end
rescue IOError => e
PEROBS.log.fatal "Cannot open flat file database #{file_name}: " +
e.message
end
+ unless @f.flock(File::LOCK_NB | File::LOCK_EX)
+ PEROBS.log.fatal 'Database is locked by another process'
+ end
@index.open
@space_list.open
end
# Close the flat file. This method must be called to ensure that all data
# is really written into the filesystem.
def close
@space_list.close
@index.close
@f.flush
+ @f.flock(File::LOCK_UN)
@f.close
@f = nil
end
# Force outstanding data to be written to the filesystem.
@@ -285,11 +289,12 @@
total_blob_count = 0
marked_blob_count = 0
each_blob_header do |pos, mark, length, blob_id, crc|
total_blob_count += 1
- if (mark & 1 == 1)
+ if (mark & 3 == 3)
+ # Clear all valid and marked blocks.
marked_blob_count += 1
begin
@f.seek(pos)
@f.write([ mark & 0b11111101 ].pack('C'))
@f.flush
@@ -305,18 +310,21 @@
# Eliminate all the holes in the file. This is an in-place
# implementation. No additional space will be needed on the file system.
def defragmentize
distance = 0
+ deleted_blobs = 0
+ valid_blobs = 0
t = Time.now
- PEROBS.log.debug "Defragmenting FlatFile"
+ PEROBS.log.info "Defragmenting FlatFile"
# Iterate over all entries.
each_blob_header do |pos, mark, length, blob_id, crc|
# Total size of the current entry
entry_bytes = BLOB_HEADER_LENGTH + length
if (mark & 1 == 1)
# We have found a valid entry.
+ valid_blobs += 1
if distance > 0
begin
# Read current entry into a buffer
@f.seek(pos)
buf = @f.read(entry_bytes)
@@ -334,14 +342,16 @@
PEROBS.log.fatal "Error while moving blob for ID #{blob_id}: " +
e.message
end
end
else
+ deleted_blobs += 1
distance += entry_bytes
end
end
- PEROBS.log.debug "FlatFile defragmented in #{Time.now - t} seconds"
- PEROBS.log.debug "#{distance} bytes or " +
+ PEROBS.log.info "FlatFile defragmented in #{Time.now - t} seconds"
+ PEROBS.log.info "#{distance / 1000} KiB/#{deleted_blobs} blobs of " +
+ "#{@f.size / 1000} KiB/#{valid_blobs} blobs or " +
"#{'%.1f' % (distance.to_f / @f.size * 100.0)}% reclaimed"
@f.flush
@f.truncate(@f.size - distance)
@f.flush