Class: Innodb::Xdes
- Inherits:
-
Object
- Object
- Innodb::Xdes
- Extended by:
- Forwardable
- Defined in:
- lib/innodb/xdes.rb
Defined Under Namespace
Classes: Entry, PageStatus
Constant Summary collapse
- BITS_PER_PAGE =
Number of bits per page in the
XDES
entry bitmap field. CurrentlyXDES
entries store two bits per page, with the following meanings:-
1 = free (the page is free, or not in use)
-
2 = clean (currently unused, always 1 when initialized)
-
2
- BITMAP_BV_FREE =
The bit value for a free page.
1
- BITMAP_BV_CLEAN =
The bit value for a clean page (currently unused in InnoDB).
2
- BITMAP_BV_ALL =
The bitwise-OR of all bitmap bit values.
(BITMAP_BV_FREE | BITMAP_BV_CLEAN)
- STATES =
The values used in the
:state
field indicating what the extent is used for (or what list it is on). { # The extent is completely empty and unused, and should be present on the filespace's FREE list. 1 => :free, # Some pages of the extent are used individually, and the extent should be present on the filespace's # FREE_FRAG list. 2 => :free_frag, # All pages of the extent are used individually, and the extent should be present on the filespace's # FULL_FRAG list. 3 => :full_frag, # The extent is wholly allocated to a file segment. Additional information about the state of this extent can # be derived from the its presence on particular file segment lists (FULL, NOT_FULL, or FREE). 4 => :fseg, }.freeze
Instance Attribute Summary collapse
-
#xdes ⇒ Object
readonly
Returns the value of attribute xdes.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Compare one Innodb::Xdes to another.
-
#allocated_to_fseg? ⇒ Boolean
Return whether this XDES entry is allocated to an fseg (the whole extent then belongs to the fseg).
-
#each_page_status ⇒ Object
Iterate through all pages represented by this extent descriptor, yielding a page status hash for each page, containing the following fields:.
-
#free_pages ⇒ Object
Return the count of free pages (free bit is true) on this extent.
-
#initialize(page, cursor) ⇒ Xdes
constructor
A new instance of Xdes.
-
#next_address ⇒ Object
Return the address of the next list pointer from the list node contained within the XDES entry.
-
#page_status(page_number) ⇒ Object
Return the status for a given page.
-
#prev_address ⇒ Object
Return the address of the previous list pointer from the list node contained within the XDES entry.
-
#read_xdes_entry(page, cursor) ⇒ Object
Read an XDES entry from a cursor.
-
#size_bitmap ⇒ Object
Size (in bytes) of the bitmap field in the
XDES
entry. -
#size_entry ⇒ Object
Size (in bytes) of the an
XDES
entry. -
#used_pages ⇒ Object
Return the count of used pages (free bit is false) on this extent.
Constructor Details
#initialize(page, cursor) ⇒ Xdes
Returns a new instance of Xdes.
64 65 66 67 |
# File 'lib/innodb/xdes.rb', line 64 def initialize(page, cursor) @page = page @xdes = read_xdes_entry(page, cursor) end |
Instance Attribute Details
#xdes ⇒ Object (readonly)
Returns the value of attribute xdes.
51 52 53 |
# File 'lib/innodb/xdes.rb', line 51 def xdes @xdes end |
Instance Method Details
#==(other) ⇒ Object
Compare one Innodb::Xdes to another.
164 165 166 |
# File 'lib/innodb/xdes.rb', line 164 def ==(other) this.page == other.this.page && this.offset == other.this.offset end |
#allocated_to_fseg? ⇒ Boolean
Return whether this XDES entry is allocated to an fseg (the whole extent then belongs to the fseg).
99 100 101 |
# File 'lib/innodb/xdes.rb', line 99 def allocated_to_fseg? fseg_id != 0 end |
#each_page_status ⇒ Object
Iterate through all pages represented by this extent descriptor, yielding a page status hash for each page, containing the following fields:
:page The page number.
:free Boolean indicating whether the page is free.
:clean Boolean indicating whether the page is clean (currently
this bit is unused by InnoDB, and always set true).
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/innodb/xdes.rb', line 118 def each_page_status return enum_for(:each_page_status) unless block_given? bitmap.each_byte.with_index do |byte, byte_index| (0..3).each do |page_offset| page_number = start_page + (byte_index * 4) + page_offset page_bits = ((byte >> (page_offset * BITS_PER_PAGE)) & BITMAP_BV_ALL) page_status = PageStatus.new( free: (page_bits & BITMAP_BV_FREE != 0), clean: (page_bits & BITMAP_BV_CLEAN != 0) ) yield page_number, page_status end end nil end |
#free_pages ⇒ Object
Return the count of free pages (free bit is true) on this extent.
137 138 139 140 141 142 |
# File 'lib/innodb/xdes.rb', line 137 def free_pages each_page_status.inject(0) do |sum, (_page_number, page_status)| sum += 1 if page_status.free sum end end |
#next_address ⇒ Object
Return the address of the next list pointer from the list node contained within the XDES entry. This is used by Innodb::List::Xdes
to iterate through XDES entries in a list.
159 160 161 |
# File 'lib/innodb/xdes.rb', line 159 def next_address list.next end |
#page_status(page_number) ⇒ Object
Return the status for a given page. This is relatively inefficient as implemented and could be done better.
105 106 107 108 |
# File 'lib/innodb/xdes.rb', line 105 def page_status(page_number) page_status_array = each_page_status.to_a page_status_array[page_number - start_page][1] end |
#prev_address ⇒ Object
Return the address of the previous list pointer from the list node contained within the XDES entry. This is used by Innodb::List::Xdes
to iterate through XDES entries in a list.
152 153 154 |
# File 'lib/innodb/xdes.rb', line 152 def prev_address list.prev end |
#read_xdes_entry(page, cursor) ⇒ Object
Read an XDES entry from a cursor.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/innodb/xdes.rb', line 80 def read_xdes_entry(page, cursor) extent_number = (cursor.position - page.pos_xdes_array) / size_entry start_page = page.offset + (extent_number * page.space.pages_per_extent) cursor.name("xdes[#{extent_number}]") do |c| Entry.new( offset: c.position, start_page: start_page, end_page: start_page + page.space.pages_per_extent - 1, fseg_id: c.name("fseg_id") { c.read_uint64 }, this: Innodb::Page::Address.new(page: page.offset, offset: c.position), list: c.name("list") { Innodb::List.get_node(c) }, state: c.name("state") { STATES[c.read_uint32] }, bitmap: c.name("bitmap") { c.read_bytes(size_bitmap) } ) end end |
#size_bitmap ⇒ Object
Size (in bytes) of the bitmap field in the XDES
entry.
70 71 72 |
# File 'lib/innodb/xdes.rb', line 70 def size_bitmap (@page.space.pages_per_extent * BITS_PER_PAGE) / 8 end |
#size_entry ⇒ Object
Size (in bytes) of the an XDES
entry.
75 76 77 |
# File 'lib/innodb/xdes.rb', line 75 def size_entry 8 + Innodb::List::NODE_SIZE + 4 + size_bitmap end |
#used_pages ⇒ Object
Return the count of used pages (free bit is false) on this extent.
145 146 147 |
# File 'lib/innodb/xdes.rb', line 145 def used_pages @page.space.pages_per_extent - free_pages end |