Class: Garcon::Stash::Format

Inherits:
Object
  • Object
show all
Defined in:
lib/garcon/stash/format.rb

Overview

Database format serializer and deserializer. You can create your own implementation of this class and define your own database format!

Instance Method Summary collapse

Instance Method Details

#dump(rec) ⇒ String

Serialize record and return string.

Parameters:

  • rec (Array)

    an array with [key, value] or [key] if the record is deleted

Returns:

  • (String)

    serialized record



55
56
57
58
59
60
61
62
# File 'lib/garcon/stash/format.rb', line 55

def dump(rec)
  data = if rec.size == 1
    [rec[0].bytesize, DELETE].pack('NN') << rec[0]
  else
    [rec[0].bytesize, rec[1].bytesize].pack('NN') << rec[0] << rec[1]
  end
  data << crc32(data)
end

#headerString

Return database header as string

Returns:

  • (String)

    database file header



44
45
46
# File 'lib/garcon/stash/format.rb', line 44

def header
  MAGIC + [VERSION].pack('n')
end

#parse(buf) {|Array| ... } ⇒ Fixnum

Deserialize records from buffer, and yield them.

Parameters:

  • buf (String)

    the buffer to read from

Yields:

  • (Array)

    block deserialized record [key, value] or [key] if the record is deleted

Returns:

  • (Fixnum)

    number of records



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/garcon/stash/format.rb', line 74

def parse(buf)
  n, count = 0, 0
  while n < buf.size
    key_size, value_size = buf[n, 8].unpack('NN')
    data_size = key_size + 8
    data_size += value_size if value_size != DELETE
    data = buf[n, data_size]
    n += data_size
    unless buf[n, 4] == crc32(data)
      raise 'CRC mismatch: your stash might be corrupted!'
    end
    n += 4
    yield(value_size == DELETE ? [data[8, key_size]] : [data[8, key_size], data[8 + key_size, value_size]])
    count += 1
  end
  count
end

#read_header(input) ⇒ Object

Read database header from input stream

Parameters:

  • input (#read)

    the input stream

Returns:

  • void



34
35
36
37
38
# File 'lib/garcon/stash/format.rb', line 34

def read_header(input)
  raise 'Not a stash' if input.read(MAGIC.bytesize) != MAGIC
  ver = input.read(2).unpack('n').first
  raise "Expected stash version #{VERSION}, got #{ver}" if ver != VERSION
end