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
XDESentry bitmap field. CurrentlyXDESentries 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
:statefield 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.
-
#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
XDESentry. -
#size_entry ⇒ Object
Size (in bytes) of the an
XDESentry. - #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.
160 161 162 163 |
# File 'lib/innodb/xdes.rb', line 160 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).
91 92 93 |
# File 'lib/innodb/xdes.rb', line 91 def allocated_to_fseg? fseg_id != 0 end |
#bitmap ⇒ Object
87 |
# File 'lib/innodb/xdes.rb', line 87 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).
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/innodb/xdes.rb', line 110 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_with_index do |page, page_index| page_number = xdes[:start_page] + (byte_index * 4) + page_index page_bits = ((byte >> (page * 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
82 |
# File 'lib/innodb/xdes.rb', line 82 def end_page; @xdes[:end_page]; end |
#free_pages ⇒ Object
Return the count of free pages (free bit is true) on this extent.
133 134 135 136 137 138 |
# File 'lib/innodb/xdes.rb', line 133 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
83 |
# File 'lib/innodb/xdes.rb', line 83 def fseg_id; @xdes[:fseg_id]; end |
#list ⇒ Object
85 |
# File 'lib/innodb/xdes.rb', line 85 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.
155 156 157 |
# File 'lib/innodb/xdes.rb', line 155 def next_address xdes[: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.
97 98 99 100 |
# File 'lib/innodb/xdes.rb', line 97 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.
148 149 150 |
# File 'lib/innodb/xdes.rb', line 148 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 |
# 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| { :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
81 |
# File 'lib/innodb/xdes.rb', line 81 def start_page; @xdes[:start_page]; end |
#state ⇒ Object
86 |
# File 'lib/innodb/xdes.rb', line 86 def state; @xdes[:state]; end |
#this ⇒ Object
84 |
# File 'lib/innodb/xdes.rb', line 84 def this; @xdes[:this]; end |
#used_pages ⇒ Object
Return the count of used pages (free bit is false) on this extent.
141 142 143 |
# File 'lib/innodb/xdes.rb', line 141 def used_pages @page.space.pages_per_extent - free_pages end |
#xdes ⇒ Object
Return the stored extent descriptor entry.
77 78 79 |
# File 'lib/innodb/xdes.rb', line 77 def xdes @xdes end |