MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tuppage.hpp
1 /*
2  Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef __NDB_TUP_PAGE_HPP
19 #define __NDB_TUP_PAGE_HPP
20 
21 #include <ndb_types.h>
22 #include "../diskpage.hpp"
23 
24 struct Tup_page
25 {
26  Tup_page() {}
27  struct File_formats::Page_header m_page_header;
28  Uint32 m_restart_seq;
29  Uint32 page_state;
30  union {
31  Uint32 next_page;
32  Uint32 nextList;
33  };
34  union {
35  Uint32 prev_page;
36  Uint32 prevList;
37  };
38  Uint32 first_cluster_page;
39  Uint32 last_cluster_page;
40  Uint32 next_cluster_page;
41  Uint32 prev_cluster_page;
42  Uint32 frag_page_id;
43  Uint32 physical_page_id;
44  Uint32 free_space;
45  Uint32 next_free_index;
46  Uint32 list_index; // free space in page bits/list, 0x8000 means not in free
47  Uint32 uncommitted_used_space;
48  Uint32 m_page_no;
49  Uint32 m_file_no;
50  Uint32 m_table_id;
51  Uint32 m_fragment_id;
52  Uint32 m_extent_no;
53  Uint32 m_extent_info_ptr;
54  Uint32 unused_ph[9];
55 
56  STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
57 
58  Uint32 m_data[DATA_WORDS];
59 };
60 
62 {
63  struct File_formats::Page_header m_page_header;
64  Uint32 m_restart_seq;
65  Uint32 page_state;
66  Uint32 next_page;
67  Uint32 prev_page;
68  Uint32 first_cluster_page;
69  Uint32 last_cluster_page;
70  Uint32 next_cluster_page;
71  Uint32 prev_cluster_page;
72  Uint32 frag_page_id;
73  Uint32 physical_page_id;
74  Uint32 free_space;
75  Uint32 next_free_index;
76  Uint32 list_index;
77  Uint32 uncommitted_used_space;
78  Uint32 m_page_no;
79  Uint32 m_file_no;
80  Uint32 m_table_id;
81  Uint32 m_fragment_id;
82  Uint32 m_extent_no;
83  Uint32 m_extent_info_ptr;
84  Uint32 unused_ph[9];
85 
86  STATIC_CONST( FREE_RECORD = ~(Uint32)0 );
87  STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
88 
89  Uint32 m_data[DATA_WORDS];
90 
91  Uint32* get_ptr(Uint32 page_idx, Uint32 rec_size){
92  assert(page_idx + rec_size <= DATA_WORDS);
93  return m_data + page_idx;
94  }
95 
101  Uint32 alloc_record();
102  Uint32 alloc_record(Uint32 page_idx);
103  Uint32 free_record(Uint32 page_idx);
104 };
105 
107 {
108  struct File_formats::Page_header m_page_header;
109  Uint32 m_restart_seq;
110  Uint32 page_state;
111  Uint32 next_page;
112  Uint32 prev_page;
113  Uint32 first_cluster_page;
114  Uint32 last_cluster_page;
115  Uint32 next_cluster_page;
116  Uint32 prev_cluster_page;
117  Uint32 frag_page_id;
118  Uint32 physical_page_id;
119  Uint32 free_space;
120  Uint32 next_free_index;
121  Uint32 list_index;
122  Uint32 uncommitted_used_space;
123  Uint32 m_page_no;
124  Uint32 m_file_no;
125  Uint32 m_table_id;
126  Uint32 m_fragment_id;
127  Uint32 m_extent_no;
128  Uint32 m_extent_info_ptr;
129  Uint32 high_index; // size of index + 1
130  Uint32 insert_pos;
131  Uint32 unused_ph[7];
132 
133  STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
134  STATIC_CONST( CHAIN = 0x80000000 );
135  STATIC_CONST( FREE = 0x40000000 );
136  STATIC_CONST( LEN_MASK = 0x3FFF8000 );
137  STATIC_CONST( POS_MASK = 0x00007FFF );
138  STATIC_CONST( LEN_SHIFT = 15 );
139  STATIC_CONST( POS_SHIFT = 0 );
140  STATIC_CONST( END_OF_FREE_LIST = POS_MASK );
141 
142  STATIC_CONST( NEXT_MASK = POS_MASK );
143  STATIC_CONST( NEXT_SHIFT = POS_SHIFT );
144  STATIC_CONST( PREV_MASK = LEN_MASK );
145  STATIC_CONST( PREV_SHIFT = LEN_SHIFT );
146 
147  Uint32 m_data[DATA_WORDS];
148 
149  Tup_varsize_page() {}
150  void init();
151 
152  Uint32* get_free_space_ptr() {
153  return m_data+insert_pos;
154  }
155 
156  Uint32 largest_frag_size() const {
157  return DATA_WORDS - (high_index + insert_pos);
158  }
159 
160  Uint32 *get_index_ptr(Uint32 page_idx) {
161  assert(page_idx < high_index);
162  return (m_data + (DATA_WORDS - page_idx));
163  }
164 
165  Uint32 get_index_word(Uint32 page_idx) const {
166  assert(page_idx < high_index);
167  return * (m_data + (DATA_WORDS - page_idx));
168  }
169 
174  Uint32 alloc_record(Uint32 size, Tup_varsize_page* temp, Uint32 chain);
175 
180  Uint32 alloc_record(Uint32 page_idx, Uint32 size, Tup_varsize_page* temp);
181 
185  Uint32 free_record(Uint32 page_idx, Uint32 chain);
186 
187  void reorg(Tup_varsize_page* temp);
188  void rebuild_index(Uint32* ptr);
189 
193  bool is_space_behind_entry(Uint32 page_index, Uint32 growth_len) const {
194  Uint32 idx= get_index_word(page_index);
195  Uint32 pos= (idx & POS_MASK) >> POS_SHIFT;
196  Uint32 len= (idx & LEN_MASK) >> LEN_SHIFT;
197  if ((pos + len == insert_pos) &&
198  (insert_pos + growth_len < DATA_WORDS - high_index))
199  return true;
200  return false;
201  }
202 
203  void grow_entry(Uint32 page_index, Uint32 growth_len) {
204  assert(free_space >= growth_len);
205 
206  Uint32 *pos= get_index_ptr(page_index);
207  Uint32 idx= *pos;
208  assert(! (idx & FREE));
209  assert((((idx & POS_MASK) >> POS_SHIFT) + ((idx & LEN_MASK) >> LEN_SHIFT))
210  == insert_pos);
211 
212  * pos= idx + (growth_len << LEN_SHIFT);
213  insert_pos+= growth_len;
214  free_space-= growth_len;
215  }
216 
217  void shrink_entry(Uint32 page_index, Uint32 new_size){
218  Uint32 *pos= get_index_ptr(page_index);
219  Uint32 idx= *pos;
220  Uint32 old_pos = (idx & POS_MASK) >> POS_SHIFT;
221  Uint32 old_size = (idx & LEN_MASK) >> LEN_SHIFT;
222 
223  assert( ! (idx & FREE));
224  assert(old_size >= new_size);
225 
226  * pos= (idx & ~LEN_MASK) + (new_size << LEN_SHIFT);
227  Uint32 shrink = old_size - new_size;
228 #ifdef VM_TRACE
229  memset(m_data + old_pos + new_size, 0xF1, 4 * shrink);
230 #endif
231  free_space+= shrink;
232  if(insert_pos == (old_pos + old_size))
233  insert_pos -= shrink;
234  }
235 
236  Uint32* get_ptr(Uint32 page_idx) {
237  return m_data + ((get_index_word(page_idx) & POS_MASK) >> POS_SHIFT);
238  }
239 
240  void set_entry_offset(Uint32 page_idx, Uint32 offset){
241  Uint32 *pos= get_index_ptr(page_idx);
242  * pos = (* pos & ~POS_MASK) + (offset << POS_SHIFT);
243  }
244 
245  void set_entry_len(Uint32 page_idx, Uint32 len) {
246  Uint32 *pos= get_index_ptr(page_idx);
247  * pos = (*pos & ~LEN_MASK) + (len << LEN_SHIFT);
248  }
249 
250  Uint32 get_entry_len(Uint32 page_idx) const {
251  return (get_index_word(page_idx) & LEN_MASK) >> LEN_SHIFT;
252  }
253 
254  Uint32 get_entry_chain(Uint32 page_idx) const {
255  return get_index_word(page_idx) & CHAIN;
256  }
257 
258  bool is_free(Uint32 page_idx) const
259  {
260  return ((get_index_word(page_idx) & FREE) != 0) ? true : false;
261  }
262 };
263 
264 NdbOut& operator<< (NdbOut& out, const Tup_varsize_page& page);
265 NdbOut& operator<< (NdbOut& out, const Tup_fixsize_page& page);
266 
267 #endif