class MappedStream

Read from a stream. Write data to a temporary file, which is mmap. Read more data from stream on a need basis, when some index operation fail.

Constants

DEFAULTS

Attributes

fd[R]
more[R]
ptr[R]

Public Class Methods

new(fd, args = {}) { |self| ... } click to toggle source
# File lib/cless/data.rb, line 51
  def initialize(fd, args = {})
    @fd = fd
    flags = fd.fcntl(Fcntl::F_GETFL)
    fd.fcntl(Fcntl::F_SETFL, flags | Fcntl::O_NONBLOCK)
    @more = true
    @buf = ""
    @lines = nil

    DEFAULTS.each { |k, v|
      instance_variable_set("@#{k}", args[k] || v)
    }
    if false
#    if $have_mmap
      @tfd = Tempfile.new(Process.pid.to_s, @tmp_dir)
      @ptr = Mmap.new(@tfd.path, "w")
      @ptr.extend(10 * @buf_size)
    else
      @ptr = ""
    end

    if block_given?
      begin
        yield(self)
      ensure
        munmap
      end
    end
  end

Public Instance Methods

[](*args) click to toggle source
# File lib/cless/data.rb, line 124
def [](*args); @ptr[*args]; end
each_line() { |ptr| ... } click to toggle source
# File lib/cless/data.rb, line 145
def each_line
  off = 0
  loop do
    r = @ptr.index("\n", off)
    if r
      yield(@ptr[off..r])
      off = r + 1
    else
      read_block or break
    end
  end
end
file_path() click to toggle source
# File lib/cless/data.rb, line 80
def file_path; @tfd ? @tfd.path : nil; end
index(substr, off = 0) click to toggle source
# File lib/cless/data.rb, line 102
def index(substr, off = 0)
  loop do
    r = @ptr.index(substr, off) and return r
    return nil unless @more
    off = (@ptr.rindex("\n", @ptr.size) || -1) + 1
    read_block or return nil
  end
end
lines(line_stop = nil, offset_stop = nil) click to toggle source

Get the total number of lines Stop if line_stop or offset_stop limits are crossed.

# File lib/cless/data.rb, line 128
def lines(line_stop = nil, offset_stop = nil)
  return @lines unless @more || @lines.nil?
  lines = @ptr.count("\n")
  while @more
    unless read_block
      select_or_cancel(@fd) or break
      next
    end
    lines += @buf.count("\n")
    return lines if line_stop && lines >= line_stop
    return @ptr.size if offset_stop && @ptr.size >= offset_stop
  end
  @lines = lines
  @lines += 1 if @ptr[-1] != ?\n
  return @lines
end
more_fd() click to toggle source
# File lib/cless/data.rb, line 120
def more_fd
  @more ? @fd : nil
end
munmap() click to toggle source
# File lib/cless/data.rb, line 82
def munmap
  @ptr.munmap rescue nil
  @tfd.close! rescue nil
end
read_block() click to toggle source
# File lib/cless/data.rb, line 90
def read_block
  @fd.read_nonblock(@buf_size, @buf)
  @ptr << @buf
  true
rescue Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EINTR => e
  false
rescue EOFError
  @more = false
  false
end
rindex(*args) click to toggle source
# File lib/cless/data.rb, line 88
def rindex(*args); @ptr.rindex(*args); end
search_index(substr, off = 0) click to toggle source
# File lib/cless/data.rb, line 112
def search_index(substr, off = 0)
  loop do
    r = @ptr.index(substr, off) and return r
    off = (@ptr.rindex("\n", @ptr.size) || -1) + 1
    select_or_cancel(@fd) or return nil
    read_block or return nil
  end
end
search_rindex(*args) click to toggle source
# File lib/cless/data.rb, line 111
def search_rindex(*args); rindex(*args); end
size() click to toggle source
# File lib/cless/data.rb, line 87
def size; @ptr.size; end