Class: Innodb::Inode

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/innodb/inode.rb

Defined Under Namespace

Classes: Header

Constant Summary collapse

FRAG_ARRAY_N_SLOTS =

The number of “slots” (each representing one page) in the fragment array within each Inode entry.

32
FRAG_SLOT_SIZE =

The size (in bytes) of each slot in the fragment array.

4
MAGIC_N_VALUE =

A magic number which helps determine if an Inode structure is in use and populated with valid data.

97_937_874
SIZE =

The size (in bytes) of an Inode entry.

(16 + (3 * Innodb::List::BASE_NODE_SIZE) +
(FRAG_ARRAY_N_SLOTS * FRAG_SLOT_SIZE))
LISTS =
%i[
  free
  not_full
  full
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(space, header) ⇒ Inode

Returns a new instance of Inode.



72
73
74
75
# File 'lib/innodb/inode.rb', line 72

def initialize(space, header)
  @space = space
  @header = header
end

Instance Attribute Details

#headerObject

Returns the value of attribute header.



70
71
72
# File 'lib/innodb/inode.rb', line 70

def header
  @header
end

#spaceObject

Returns the value of attribute space.



69
70
71
# File 'lib/innodb/inode.rb', line 69

def space
  @space
end

Class Method Details

.new_from_cursor(space, cursor) ⇒ Object

Construct a new Inode by reading an FSEG header from a cursor.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/innodb/inode.rb', line 53

def self.new_from_cursor(space, cursor)
  Innodb::Inode.new(
    space,
    Header.new(
      offset: cursor.position,
      fseg_id: cursor.name("fseg_id") { cursor.read_uint64 },
      not_full_n_used: cursor.name("not_full_n_used") { cursor.read_uint32 },
      free: cursor.name("list[free]") { Innodb::List::Xdes.new(space, Innodb::List.get_base_node(cursor)) },
      not_full: cursor.name("list[not_full]") { Innodb::List::Xdes.new(space, Innodb::List.get_base_node(cursor)) },
      full: cursor.name("list[full]") { Innodb::List::Xdes.new(space, Innodb::List.get_base_node(cursor)) },
      magic_n: cursor.name("magic_n") { cursor.read_uint32 },
      frag_array: cursor.name("frag_array") { page_number_array(FRAG_ARRAY_N_SLOTS, cursor) }
    )
  )
end

.page_number_array(size, cursor) ⇒ Object

Read an array of page numbers (32-bit integers, which may be nil) from the provided cursor.



44
45
46
47
48
49
50
# File 'lib/innodb/inode.rb', line 44

def self.page_number_array(size, cursor)
  size.times.map do |n|
    cursor.name("page[#{n}]") do |c|
      Innodb::Page.maybe_undefined(c.read_uint32)
    end
  end
end

Instance Method Details

#==(other) ⇒ Object

Compare one Innodb::Inode to another.



177
178
179
# File 'lib/innodb/inode.rb', line 177

def ==(other)
  fseg_id == other.fseg_id if other
end

#allocated?Boolean

Helper method to determine if an Inode is in use. Inodes that are not in use have an fseg_id of 0.

Returns:

  • (Boolean)


96
97
98
# File 'lib/innodb/inode.rb', line 96

def allocated?
  fseg_id != 0
end

#dumpObject

Dump a summary of this object for debugging purposes.



182
183
184
# File 'lib/innodb/inode.rb', line 182

def dump
  pp header
end

#each_listObject

Iterate through all lists, yielding the list name and the list itself.



137
138
139
140
141
142
143
144
145
# File 'lib/innodb/inode.rb', line 137

def each_list
  return enum_for(:each_list) unless block_given?

  LISTS.each do |name|
    yield name, list(name)
  end

  nil
end

#each_pageObject

Iterate through the page as associated with this inode using the each_page_number method, and yield the page number and page.



166
167
168
169
170
171
172
173
174
# File 'lib/innodb/inode.rb', line 166

def each_page
  return enum_for(:each_page) unless block_given?

  each_page_number do |page_number|
    yield page_number, space.page(page_number)
  end

  nil
end

#each_page_number(&block) ⇒ Object

Iterate through the fragment array followed by all lists, yielding the page number. This allows a convenient way to identify all pages that are part of this inode.



150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/innodb/inode.rb', line 150

def each_page_number(&block)
  return enum_for(:each_page_number) unless block_given?

  frag_array_pages.each(&block)

  each_list do |_fseg_name, fseg_list|
    fseg_list.each do |xdes|
      xdes.each_page_status(&block)
    end
  end

  nil
end

#fill_factorObject

Calculate the fill factor of this fseg, in percent.



125
126
127
# File 'lib/innodb/inode.rb', line 125

def fill_factor
  total_pages.positive? ? 100.0 * (used_pages.to_f / total_pages) : 0.0
end

#frag_array_n_usedObject

Helper method to count non-nil fragment pages.



106
107
108
# File 'lib/innodb/inode.rb', line 106

def frag_array_n_used
  frag_array_pages.count
end

#frag_array_pagesObject

Helper method to return an array of only non-nil fragment pages.



101
102
103
# File 'lib/innodb/inode.rb', line 101

def frag_array_pages
  frag_array.compact
end

#inspectObject



86
87
88
89
90
91
92
# File 'lib/innodb/inode.rb', line 86

def inspect
  "<%s space=%s, fseg=%i>" % [
    self.class.name,
    space.inspect,
    fseg_id,
  ]
end

#list(name) ⇒ Object

Return a list from the fseg, given its name as a symbol.



130
131
132
133
134
# File 'lib/innodb/inode.rb', line 130

def list(name)
  return unless LISTS.include?(name)

  header[name]
end

#total_pagesObject

Calculate the total number of pages within this fseg.



117
118
119
120
121
122
# File 'lib/innodb/inode.rb', line 117

def total_pages
  frag_array_n_used +
    (free.length * @space.pages_per_extent) +
    (not_full.length * @space.pages_per_extent) +
    (full.length * @space.pages_per_extent)
end

#used_pagesObject

Calculate the total number of pages in use (not free) within this fseg.



111
112
113
114
# File 'lib/innodb/inode.rb', line 111

def used_pages
  frag_array_n_used + not_full_n_used +
    (full.length * @space.pages_per_extent)
end