class Innodb::LSN

Constants

LOG_BLOCK_DATA_SIZE
LOG_BLOCK_FRAME_SIZE
LOG_BLOCK_HEADER_SIZE
LOG_BLOCK_SIZE

Short aliases for the sizes of the subparts of a log block.

LOG_BLOCK_TRAILER_SIZE
LOG_HEADER_SIZE

Short alias for the size of a log file header.

Attributes

lsn_no[R]

The Log Sequence Number.

no[R]

The Log Sequence Number.

Public Class Methods

new(lsn, offset) click to toggle source

Initialize coordinates.

# File lib/innodb/lsn.rb, line 13
def initialize(lsn, offset)
  @lsn_no = lsn
  @lsn_offset = offset
end

Public Instance Methods

advance(count_lsn_no, group) click to toggle source

Advance by a given LSN amount.

# File lib/innodb/lsn.rb, line 28
def advance(count_lsn_no, group)
  new_lsn_no = @lsn_no + count_lsn_no
  reposition(new_lsn_no, group)
end
delta(length) click to toggle source

Returns the LSN delta for the given amount of data.

# File lib/innodb/lsn.rb, line 39
def delta(length)
  fragment = (@lsn_no % LOG_BLOCK_SIZE) - LOG_BLOCK_HEADER_SIZE
  raise "Invalid fragment #{fragment} for LSN #{@lsn_no}" unless fragment.between?(0, LOG_BLOCK_DATA_SIZE - 1)

  length + ((fragment + length) / LOG_BLOCK_DATA_SIZE * LOG_BLOCK_FRAME_SIZE)
end
location(group) click to toggle source

Returns the location coordinates of this LSN.

# File lib/innodb/lsn.rb, line 34
def location(group)
  location_of(@lsn_offset, group)
end
record?(group) click to toggle source

Whether LSN might point to log record data.

# File lib/innodb/lsn.rb, line 47
def record?(group)
  data_offset?(@lsn_offset, group)
end
reposition(new_lsn_no, group) click to toggle source

Place LSN in a new position.

# File lib/innodb/lsn.rb, line 19
def reposition(new_lsn_no, group)
  new_offset = offset_of(@lsn_no, @lsn_offset, new_lsn_no, group)
  @lsn_no = new_lsn_no
  @lsn_offset = new_offset

  [@lsn_no, @lsn_offset]
end

Private Instance Methods

data_offset?(offset, group) click to toggle source

Whether offset points to the data area of an existing log block.

# File lib/innodb/lsn.rb, line 94
def data_offset?(offset, group)
  log_offset = offset % group.size
  log_no, block_no, block_offset = location_of(offset, group)

  status ||= log_no > group.logs
  status ||= log_offset <= LOG_HEADER_SIZE
  status ||= block_no.negative?
  status ||= block_no >= group.log(log_no).blocks
  status ||= block_offset < Innodb::LogBlock::DATA_OFFSET
  status ||= block_offset >= Innodb::LogBlock::TRAILER_OFFSET

  !status
end
location_of(offset, group) click to toggle source

Returns the coordinates of the given offset.

# File lib/innodb/lsn.rb, line 64
def location_of(offset, group)
  log_no, log_offset = offset.divmod(group.size)
  block_no, block_offset = (log_offset - LOG_HEADER_SIZE).divmod(LOG_BLOCK_SIZE)
  [log_no, block_no, block_offset]
end
offset_of(lsn, offset, new_lsn, group) click to toggle source

Returns the offset of the given LSN within a log group.

# File lib/innodb/lsn.rb, line 71
def offset_of(lsn, offset, new_lsn, group)
  log_size = group.log_size
  group_capacity = group.capacity

  # Calculate the offset in LSN.
  if new_lsn >= lsn
    lsn_offset = new_lsn - lsn
  else
    lsn_offset = lsn - new_lsn
    lsn_offset %= group_capacity
    lsn_offset = group_capacity - lsn_offset
  end

  # Transpose group size offset to a group capacity offset.
  group_offset = offset - (LOG_HEADER_SIZE * (1 + (offset / log_size)))

  offset = (lsn_offset + group_offset) % group_capacity

  # Transpose group capacity offset to a group size offset.
  offset + (LOG_HEADER_SIZE * (1 + (offset / (log_size - LOG_HEADER_SIZE))))
end