Class: Rubcask::DataFile

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/rubcask/data_file.rb

Overview

DataFile is a file where the key and values are actually stored

Defined Under Namespace

Classes: AppendResult

Constant Summary collapse

HEADER_FORMAT =
"NQ>nN"
HEADER_WITHOUT_CRC_FORMAT =
"Q>nN"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file, file_size) ⇒ DataFile

Returns a new instance of DataFile.

Parameters:

  • file (File)

    File with the data

  • file_size (Integer)

    Current size of ‘file` in bytes



20
21
22
23
# File 'lib/rubcask/data_file.rb', line 20

def initialize(file, file_size)
  @file = file
  @write_pos = file_size
end

Instance Attribute Details

#write_posObject (readonly)

Returns the value of attribute write_pos.



13
14
15
# File 'lib/rubcask/data_file.rb', line 13

def write_pos
  @write_pos
end

Instance Method Details

#[](offset, size = nil) ⇒ DataEntry?

Note:

Calling this method might change ‘pos` of the `file`

Fetch entry at given offset. With optional size parameter we can do less I/O operations.

Parameters:

  • offset (Integer)

    File offset in bytes

  • size (Integer, nil) (defaults to: nil)

    Entry size in bytes

Returns:

  • (DataEntry)
  • (nil)

    if at the end of file

Raises:



42
43
44
45
46
47
48
# File 'lib/rubcask/data_file.rb', line 42

def [](offset, size = nil)
  if size.nil?
    seek(offset)
    return read
  end
  pread(offset, size)
end

#append(entry) ⇒ AppendResult

Note:

Calling this method will not change ‘pos` of the `file`

Append an entry at the end of the file

Parameters:

  • entry (DataEntry)

    Entry to write to the file

Returns:

  • (AppendResult)

    struct containing position and size of the entry



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/rubcask/data_file.rb', line 90

def append(entry)
  current_pos = @write_pos

  key_size = entry.key.bytesize
  value_size = entry.value.bytesize

  crc = Zlib.crc32([
    entry.expire_timestamp,
    key_size,
    value_size
  ].pack(HEADER_WITHOUT_CRC_FORMAT) + entry.key + entry.value)
  @write_pos += @file.write(
    [crc, entry.expire_timestamp, key_size, value_size].pack(HEADER_FORMAT),
    entry.key,
    entry.value
  )
  @file.flush
  AppendResult.new(current_pos, @write_pos - current_pos)
end

#each {|data_entry| ... } ⇒ Enumerator

Note:

Calling this method might change ‘pos` of the `file`

yields each entry in the file

Yield Parameters:

  • data_entry (DataEntry)

    Entry from the file

Returns:

  • (Enumerator)

    if no block given



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rubcask/data_file.rb', line 54

def each
  return to_enum(__method__) unless block_given?

  seek(0)

  loop do
    val = read
    break unless val
    yield val
  end
end

#pread(offset, size) ⇒ DataEntry?

Note:

Calling this method will not change ‘pos` of the `file`

Fetch an entry at given offset and with provided size

Parameters:

  • offset (Integer)

    File offset in bytes

  • size (Integer)

    Entry size in bytes

Returns:

  • (DataEntry)
  • (nil)

    if at the end of file

Raises:



81
82
83
# File 'lib/rubcask/data_file.rb', line 81

def pread(offset, size)
  read_from_io(StringIO.new(@file.pread(size, offset)))
end

#read(size = nil) ⇒ DataEntry?

Note:

Calling this method might change ‘pos` of the `file`

Read an entry at the current file position

Parameters:

  • size (Integer, nil) (defaults to: nil)

    Entry size in bytes

Returns:

  • (DataEntry)
  • (nil)

    if at the end of file

Raises:



70
71
72
73
74
# File 'lib/rubcask/data_file.rb', line 70

def read(size = nil)
  read_from_io(
    size ? StringIO.new(@file.read(size)) : @file
  )
end