Class: Innodb::Xdes
- Inherits:
-
Object
- Object
- Innodb::Xdes
- Defined in:
- lib/innodb/xdes.rb
Overview
An InnoDB “extent descriptor entry” or “XDES
”. These structures are used in the XDES
entry array contained in FSP_HDR
and XDES
pages.
Note the distinction between XDES
entries and XDES
pages.
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). { 1 => :free, # The extent is completely empty and unused, and should # be present on the filespace's FREE list. 2 => :free_frag, # Some pages of the extent are used individually, and # the extent should be present on the filespace's # FREE_FRAG list. 3 => :full_frag, # All pages of the extent are used individually, and # the extent should be present on the filespace's # FULL_FRAG list. 4 => :fseg, # 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). }
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).
- #bitmap ⇒ Object
-
#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:.
- #end_page ⇒ Object
-
#free_pages ⇒ Object
Return the count of free pages (free bit is true) on this extent.
- #fseg_id ⇒ Object
-
#initialize(page, cursor) ⇒ Xdes
constructor
A new instance of Xdes.
- #list ⇒ Object
-
#next_address ⇒ Object
Return the address of the next list pointer from the list node contained within the XDES entry.
- #offset ⇒ Object
-
#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. - #start_page ⇒ Object
- #state ⇒ Object
- #this ⇒ Object
-
#used_pages ⇒ Object
Return the count of used pages (free bit is false) on this extent.
-
#xdes ⇒ Object
Return the stored extent descriptor entry.
Constructor Details
#initialize(page, cursor) ⇒ Xdes
Returns a new instance of Xdes.
44 45 46 47 |
# File 'lib/innodb/xdes.rb', line 44 def initialize(page, cursor) @page = page @xdes = read_xdes_entry(page, cursor) end |
Instance Method Details
#==(other) ⇒ Object
Compare one Innodb::Xdes to another.
162 163 164 165 |
# File 'lib/innodb/xdes.rb', line 162 def ==(other) xdes[:this][:page] == other.xdes[:this][:page] && xdes[:this][:offset] == other.xdes[: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).
93 94 95 |
# File 'lib/innodb/xdes.rb', line 93 def allocated_to_fseg? fseg_id != 0 end |
#bitmap ⇒ Object
89 |
# File 'lib/innodb/xdes.rb', line 89 def bitmap; @xdes[:bitmap]; 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).
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/innodb/xdes.rb', line 112 def each_page_status unless block_given? return enum_for(:each_page_status) end bitmap = xdes[:bitmap].enum_for(:each_byte) bitmap.each_with_index do |byte, byte_index| (0..3).each do |page_offset| page_number = xdes[:start_page] + (byte_index * 4) + page_offset page_bits = ((byte >> (page_offset * BITS_PER_PAGE)) & BITMAP_BV_ALL) page_status = { :free => (page_bits & BITMAP_BV_FREE != 0), :clean => (page_bits & BITMAP_BV_CLEAN != 0), } yield page_number, page_status end end nil end |
#end_page ⇒ Object
84 |
# File 'lib/innodb/xdes.rb', line 84 def end_page; @xdes[:end_page]; end |
#free_pages ⇒ Object
Return the count of free pages (free bit is true) on this extent.
135 136 137 138 139 140 |
# File 'lib/innodb/xdes.rb', line 135 def free_pages each_page_status.inject(0) do |sum, (page_number, page_status)| sum += 1 if page_status[:free] sum end end |
#fseg_id ⇒ Object
85 |
# File 'lib/innodb/xdes.rb', line 85 def fseg_id; @xdes[:fseg_id]; end |
#list ⇒ Object
87 |
# File 'lib/innodb/xdes.rb', line 87 def list; @xdes[:list]; 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.
157 158 159 |
# File 'lib/innodb/xdes.rb', line 157 def next_address xdes[:list][:next] end |
#offset ⇒ Object
82 |
# File 'lib/innodb/xdes.rb', line 82 def offset; @xdes[:offset]; end |
#page_status(page_number) ⇒ Object
Return the status for a given page. This is relatively inefficient as implemented and could be done better.
99 100 101 102 |
# File 'lib/innodb/xdes.rb', line 99 def page_status(page_number) page_status_array = each_page_status.to_a page_status_array[page_number - xdes[: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.
150 151 152 |
# File 'lib/innodb/xdes.rb', line 150 def prev_address xdes[:list][:prev] end |
#read_xdes_entry(page, cursor) ⇒ Object
Read an XDES entry from a cursor.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/innodb/xdes.rb', line 60 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| { :offset => c.position, :start_page => start_page, :end_page => start_page + page.space.pages_per_extent - 1, :fseg_id => c.name("fseg_id") { c.get_uint64 }, :this => {:page => page.offset, :offset => c.position}, :list => c.name("list") { Innodb::List.get_node(c) }, :state => c.name("state") { STATES[c.get_uint32] }, :bitmap => c.name("bitmap") { c.get_bytes(size_bitmap) }, } end end |
#size_bitmap ⇒ Object
Size (in bytes) of the bitmap field in the XDES
entry.
50 51 52 |
# File 'lib/innodb/xdes.rb', line 50 def size_bitmap (@page.space.pages_per_extent * BITS_PER_PAGE) / 8 end |
#size_entry ⇒ Object
Size (in bytes) of the an XDES
entry.
55 56 57 |
# File 'lib/innodb/xdes.rb', line 55 def size_entry 8 + Innodb::List::NODE_SIZE + 4 + size_bitmap end |
#start_page ⇒ Object
83 |
# File 'lib/innodb/xdes.rb', line 83 def start_page; @xdes[:start_page]; end |
#state ⇒ Object
88 |
# File 'lib/innodb/xdes.rb', line 88 def state; @xdes[:state]; end |
#this ⇒ Object
86 |
# File 'lib/innodb/xdes.rb', line 86 def this; @xdes[:this]; end |
#used_pages ⇒ Object
Return the count of used pages (free bit is false) on this extent.
143 144 145 |
# File 'lib/innodb/xdes.rb', line 143 def used_pages @page.space.pages_per_extent - free_pages end |
#xdes ⇒ Object
Return the stored extent descriptor entry.
78 79 80 |
# File 'lib/innodb/xdes.rb', line 78 def xdes @xdes end |