Sha256: d7aa941210cfcaa6b6473cc31ace6d91545dad781d30676a00acc846fd47f7ec
Contents?: true
Size: 1.91 KB
Versions: 1
Compression:
Stored size: 1.91 KB
Contents
module Daybreak # Records define how data is serialized and read from disk. module Record # Thrown when either key or data is missing class UnnacceptableDataError < Exception; end # Thrown when there is a CRC mismatch between the data from the disk # and what was written to disk previously. class CorruptDataError < Exception; end extend self extend Locking # The mask a record uses to check for deletion. DELETION_MASK = 1 << 31 # Read a record from an open io source, check the CRC, and set <tt>@key</tt> # and <tt>@data</tt>. # @param [#read] io an IO instance to read from # The serialized representation of the key value pair plus the CRC. # @return [String] def serialize(record) raise UnnacceptableDataError, 'key and data must be defined' unless record[0] && record[1] s = key_data_string(record) s << crc_string(s) end # Create a new record to read from IO. # @param [#read] io an IO instance to read from def read(io) lock io do record = [] masked = read32(io) # Read the record's key bytes record << io.read(masked & (DELETION_MASK - 1)) << # Read the record's value bytes io.read(read32(io)) << # Set the deletion flag ((masked & DELETION_MASK) != 0) crc = io.read(4) raise CorruptDataError, 'CRC mismatch' unless crc == crc_string(key_data_string(record)) record end end private # Return the deletion flag plus two length prefixed cells def key_data_string(record) part(record[0], record[0].bytesize + (record[2] ? DELETION_MASK : 0)) << part(record[1], record[1].bytesize) end def crc_string(s) [Zlib.crc32(s, 0)].pack('N') end def part(data, length) [length].pack('N') << data end def read32(io) raw = io.read(4) raw.unpack('N')[0] end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
daybreak-0.1.2 | lib/daybreak/record.rb |