class PEROBS::StackFile
This class implements a file based stack. All entries must have the same size.
Public Class Methods
Create a new stack file in the given directory with the given file name. @param dir [String] Directory @param name [String] File name @param entry_bytes [Integer] Number of bytes each entry must have
# File lib/perobs/StackFile.rb, line 40 def initialize(dir, name, entry_bytes) @file_name = File.join(dir, name + '.stack') @entry_bytes = entry_bytes @f = nil end
Public Instance Methods
Remove all entries from the stack.
# File lib/perobs/StackFile.rb, line 117 def clear @f.truncate(0) @f.flush end
Close the stack file. This method must be called before the program is terminated to avoid data loss.
# File lib/perobs/StackFile.rb, line 64 def close begin @f.flush @f.flock(File::LOCK_UN) @f.close rescue IOError => e PEROBS.log.fatal "Cannot close stack file #{@file_name}: #{e.message}" end end
Iterate over all entries in the stack and call the given block for the bytes.
# File lib/perobs/StackFile.rb, line 124 def each @f.seek(0) while !@f.eof yield(@f.read(@entry_bytes)) end end
Open the stack file.
# File lib/perobs/StackFile.rb, line 47 def open begin if File.exist?(@file_name) @f = File.open(@file_name, 'rb+') else @f = File.open(@file_name, 'wb+') end rescue => e PEROBS.log.fatal "Cannot open stack file #{@file_name}: #{e.message}" end unless @f.flock(File::LOCK_NB | File::LOCK_EX) PEROBS.log.fatal 'Database stack file is locked by another process' end end
Pop the last entry from the stack file. @return [String or nil] Popped entry or nil if stack is already empty.
# File lib/perobs/StackFile.rb, line 100 def pop begin return nil if @f.size == 0 @f.seek(-@entry_bytes, IO::SEEK_END) bytes = @f.read(@entry_bytes) @f.truncate(@f.size - @entry_bytes) @f.flush rescue => e PEROBS.log.fatal "Cannot pop from stack file #{@file_name}: " + e.message end bytes end
Push the given bytes onto the stack file. @param bytes [String] Bytes to write.
# File lib/perobs/StackFile.rb, line 85 def push(bytes) if bytes.length != @entry_bytes PEROBS.log.fatal "All stack entries must be #{@entry_bytes} " + "long. This entry is #{bytes.length} bytes long." end begin @f.seek(0, IO::SEEK_END) @f.write(bytes) rescue => e PEROBS.log.fatal "Cannot push to stack file #{@file_name}: #{e.message}" end end
Flush out unwritten data to file.
# File lib/perobs/StackFile.rb, line 75 def sync begin @f.flush rescue IOError => e PEROBS.log.fatal "Cannot sync stack file #{@file_name}: #{e.message}" end end
Return the content of the stack as an Array
. @return [Array]
# File lib/perobs/StackFile.rb, line 133 def to_ary a = [] each { |bytes| a << bytes } a end