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