class PEROBS::StackFile

This class implements a file based stack. All entries must have the same size.

Public Class Methods

new(dir, name, entry_bytes) click to toggle source

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

clear() click to toggle source

Remove all entries from the stack.

# File lib/perobs/StackFile.rb, line 117
def clear
  @f.truncate(0)
  @f.flush
end
close() click to toggle source

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
each() { |read| ... } click to toggle source

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() click to toggle source

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() click to toggle source

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(bytes) click to toggle source

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
sync() click to toggle source

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
to_ary() click to toggle source

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