class Cdb::Reader

Provides read-only access to a cdb.

Public Class Methods

new(file) click to toggle source
# File lib/cdb/reader.rb, line 4
def initialize(file)
  @file = file.binmode
end

Public Instance Methods

[](key) click to toggle source

Fetches the value associated with the given key.

Returns nil if the key doesn't exist in the cdb.

# File lib/cdb/reader.rb, line 11
def [](key)
  hash = Cdb.hash(key)
  table = tables[hash % Cdb::NUM_HASHTABLES]
  return nil if table.empty?
  key_from_table(table, key, hash)
end

Private Instance Methods

key_from_table(table, key, hash) click to toggle source
# File lib/cdb/reader.rb, line 20
def key_from_table(table, key, hash)
  initial = (hash / Cdb::NUM_HASHTABLES) % table.length
  (0...table.length).each do |n|
    entry_hash, offset = table[(initial + n) % table.length]
    return nil if offset.zero?
    value = maybe_read_value(offset, key) if entry_hash == hash
    return value unless value.nil?
  end
  nil
end
load_table(offset, cap) click to toggle source
# File lib/cdb/reader.rb, line 48
def load_table(offset, cap)
  read_at(offset, cap * 8).unpack('V*').each_slice(2).to_a
end
load_tables() click to toggle source
# File lib/cdb/reader.rb, line 41
def load_tables
  read_at(0, Cdb::NUM_HASHTABLES * 8)
    .unpack('V*')
    .each_slice(2)
    .map { |offset, capacity| load_table(offset, capacity) }
end
maybe_read_value(offset, key) click to toggle source
# File lib/cdb/reader.rb, line 31
def maybe_read_value(offset, key)
  @file.seek(offset)
  key_length, value_length = @file.read(8).unpack('VV')
  @file.read(key_length) == key && @file.read(value_length) || nil
end
read_at(offset, len) click to toggle source
# File lib/cdb/reader.rb, line 52
def read_at(offset, len)
  @file.seek(offset)
  @file.read(len)
end
tables() click to toggle source
# File lib/cdb/reader.rb, line 37
def tables
  @tables ||= load_tables
end