00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #ifndef __NDB_TUP_PAGE_HPP 00018 #define __NDB_TUP_PAGE_HPP 00019 00020 #include <ndb_types.h> 00021 #include "../diskpage.hpp" 00022 00023 struct Tup_page 00024 { 00025 struct File_formats::Page_header m_page_header; 00026 Uint32 m_restart_seq; 00027 Uint32 page_state; 00028 union { 00029 Uint32 next_page; 00030 Uint32 nextList; 00031 }; 00032 union { 00033 Uint32 prev_page; 00034 Uint32 prevList; 00035 }; 00036 Uint32 first_cluster_page; 00037 Uint32 last_cluster_page; 00038 Uint32 next_cluster_page; 00039 Uint32 prev_cluster_page; 00040 Uint32 frag_page_id; 00041 Uint32 physical_page_id; 00042 Uint32 free_space; 00043 Uint32 next_free_index; 00044 Uint32 list_index; // free space in page bits/list, 0x8000 means not in free 00045 Uint32 uncommitted_used_space; 00046 Uint32 m_page_no; 00047 Uint32 m_file_no; 00048 Uint32 m_table_id; 00049 Uint32 m_fragment_id; 00050 Uint32 m_extent_no; 00051 Uint32 m_extent_info_ptr; 00052 Uint32 unused_ph[9]; 00053 00054 STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 ); 00055 00056 Uint32 m_data[DATA_WORDS]; 00057 }; 00058 00059 struct Tup_fixsize_page 00060 { 00061 struct File_formats::Page_header m_page_header; 00062 Uint32 m_restart_seq; 00063 Uint32 page_state; 00064 Uint32 next_page; 00065 Uint32 prev_page; 00066 Uint32 first_cluster_page; 00067 Uint32 last_cluster_page; 00068 Uint32 next_cluster_page; 00069 Uint32 prev_cluster_page; 00070 Uint32 frag_page_id; 00071 Uint32 physical_page_id; 00072 Uint32 free_space; 00073 Uint32 next_free_index; 00074 Uint32 list_index; 00075 Uint32 uncommitted_used_space; 00076 Uint32 m_page_no; 00077 Uint32 m_file_no; 00078 Uint32 m_table_id; 00079 Uint32 m_fragment_id; 00080 Uint32 m_extent_no; 00081 Uint32 m_extent_info_ptr; 00082 Uint32 unused_ph[9]; 00083 00084 STATIC_CONST( FREE_RECORD = ~(Uint32)0 ); 00085 STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 ); 00086 00087 Uint32 m_data[DATA_WORDS]; 00088 00089 Uint32* get_ptr(Uint32 page_idx, Uint32 rec_size){ 00090 assert(page_idx + rec_size <= DATA_WORDS); 00091 return m_data + page_idx; 00092 } 00093 00098 Uint32 alloc_record(); 00099 Uint32 alloc_record(Uint32 page_idx); 00100 Uint32 free_record(Uint32 page_idx); 00101 }; 00102 00103 struct Tup_varsize_page 00104 { 00105 struct File_formats::Page_header m_page_header; 00106 Uint32 m_restart_seq; 00107 Uint32 page_state; 00108 Uint32 next_page; 00109 Uint32 prev_page; 00110 union { 00111 Uint32 first_cluster_page; 00112 Uint32 chunk_size; 00113 }; 00114 union { 00115 Uint32 last_cluster_page; 00116 Uint32 next_chunk; 00117 }; 00118 Uint32 next_cluster_page; 00119 Uint32 prev_cluster_page; 00120 Uint32 frag_page_id; 00121 Uint32 physical_page_id; 00122 Uint32 free_space; 00123 Uint32 next_free_index; 00124 Uint32 list_index; 00125 Uint32 uncommitted_used_space; 00126 Uint32 m_page_no; 00127 Uint32 m_file_no; 00128 Uint32 m_table_id; 00129 Uint32 m_fragment_id; 00130 Uint32 m_extent_no; 00131 Uint32 m_extent_info_ptr; 00132 Uint32 high_index; // size of index + 1 00133 Uint32 insert_pos; 00134 Uint32 unused_ph[7]; 00135 00136 STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 ); 00137 STATIC_CONST( CHAIN = 0x80000000 ); 00138 STATIC_CONST( FREE = 0x40000000 ); 00139 STATIC_CONST( LEN_MASK = 0x3FFF8000 ); 00140 STATIC_CONST( POS_MASK = 0x00007FFF ); 00141 STATIC_CONST( LEN_SHIFT = 15 ); 00142 STATIC_CONST( POS_SHIFT = 0 ); 00143 STATIC_CONST( END_OF_FREE_LIST = POS_MASK ); 00144 00145 STATIC_CONST( NEXT_MASK = POS_MASK ); 00146 STATIC_CONST( NEXT_SHIFT = POS_SHIFT ); 00147 STATIC_CONST( PREV_MASK = LEN_MASK ); 00148 STATIC_CONST( PREV_SHIFT = LEN_SHIFT ); 00149 00150 Uint32 m_data[DATA_WORDS]; 00151 00152 void init(); 00153 00154 Uint32* get_free_space_ptr() { 00155 return m_data+insert_pos; 00156 } 00157 00158 Uint32 largest_frag_size() const { 00159 return DATA_WORDS - (high_index + insert_pos); 00160 } 00161 00162 Uint32 *get_index_ptr(Uint32 page_idx) { 00163 assert(page_idx < high_index); 00164 return (m_data + (DATA_WORDS - page_idx)); 00165 } 00166 00167 Uint32 get_index_word(Uint32 page_idx) const { 00168 assert(page_idx < high_index); 00169 return * (m_data + (DATA_WORDS - page_idx)); 00170 } 00171 00176 Uint32 alloc_record(Uint32 size, Tup_varsize_page* temp, Uint32 chain); 00177 00182 Uint32 alloc_record(Uint32 page_idx, Uint32 size, Tup_varsize_page* temp); 00183 00187 Uint32 free_record(Uint32 page_idx, Uint32 chain); 00188 00189 void reorg(Tup_varsize_page* temp); 00190 void rebuild_index(Uint32* ptr); 00191 00195 bool is_space_behind_entry(Uint32 page_index, Uint32 growth_len) const { 00196 Uint32 idx= get_index_word(page_index); 00197 Uint32 pos= (idx & POS_MASK) >> POS_SHIFT; 00198 Uint32 len= (idx & LEN_MASK) >> LEN_SHIFT; 00199 if ((pos + len == insert_pos) && 00200 (insert_pos + growth_len < DATA_WORDS - high_index)) 00201 return true; 00202 return false; 00203 } 00204 00205 void grow_entry(Uint32 page_index, Uint32 growth_len) { 00206 assert(free_space >= growth_len); 00207 00208 Uint32 *pos= get_index_ptr(page_index); 00209 Uint32 idx= *pos; 00210 assert(! (idx & FREE)); 00211 assert((((idx & POS_MASK) >> POS_SHIFT) + ((idx & LEN_MASK) >> LEN_SHIFT)) 00212 == insert_pos); 00213 00214 * pos= idx + (growth_len << LEN_SHIFT); 00215 insert_pos+= growth_len; 00216 free_space-= growth_len; 00217 } 00218 00219 void shrink_entry(Uint32 page_index, Uint32 new_size){ 00220 Uint32 *pos= get_index_ptr(page_index); 00221 Uint32 idx= *pos; 00222 Uint32 old_pos = (idx & POS_MASK) >> POS_SHIFT; 00223 Uint32 old_size = (idx & LEN_MASK) >> LEN_SHIFT; 00224 00225 assert( ! (idx & FREE)); 00226 assert(old_size >= new_size); 00227 00228 * pos= (idx & ~LEN_MASK) + (new_size << LEN_SHIFT); 00229 Uint32 shrink = old_size - new_size; 00230 #ifdef VM_TRACE 00231 memset(m_data + old_pos + new_size, 0xF1, 4 * shrink); 00232 #endif 00233 free_space+= shrink; 00234 if(insert_pos == (old_pos + old_size)) 00235 insert_pos -= shrink; 00236 } 00237 00238 Uint32* get_ptr(Uint32 page_idx) { 00239 return m_data + ((get_index_word(page_idx) & POS_MASK) >> POS_SHIFT); 00240 } 00241 00242 void set_entry_offset(Uint32 page_idx, Uint32 offset){ 00243 Uint32 *pos= get_index_ptr(page_idx); 00244 * pos = (* pos & ~POS_MASK) + (offset << POS_SHIFT); 00245 } 00246 00247 void set_entry_len(Uint32 page_idx, Uint32 len) { 00248 Uint32 *pos= get_index_ptr(page_idx); 00249 * pos = (*pos & ~LEN_MASK) + (len << LEN_SHIFT); 00250 } 00251 00252 Uint32 get_entry_len(Uint32 page_idx) const { 00253 return (get_index_word(page_idx) & LEN_MASK) >> LEN_SHIFT; 00254 } 00255 00256 Uint32 get_entry_chain(Uint32 page_idx) const { 00257 return get_index_word(page_idx) & CHAIN; 00258 } 00259 }; 00260 00261 NdbOut& operator<< (NdbOut& out, const Tup_varsize_page& page); 00262 NdbOut& operator<< (NdbOut& out, const Tup_fixsize_page& page); 00263 00264 #endif
1.4.7

