18 #include <ndb_global.h>
19 #include "tuppage.hpp"
39 Uint32 page_idx = next_free_index;
40 assert(page_idx + 1 < DATA_WORDS);
42 Uint32 prev = m_data[page_idx] >> 16;
43 Uint32 next = m_data[page_idx] & 0xFFFF;
45 assert(prev == 0xFFFF);
46 assert(m_data[page_idx + 1] == FREE_RECORD);
48 m_data[page_idx + 1] = 0;
51 assert(free_space > 1);
52 Uint32 nextP = m_data[next];
53 assert((nextP >> 16) == page_idx);
54 m_data[next] = 0xFFFF0000 | (nextP & 0xFFFF);
58 assert(free_space == 1);
61 next_free_index = next;
69 assert(page_idx + 1 < DATA_WORDS);
70 if (likely(free_space && m_data[page_idx + 1] == FREE_RECORD))
72 Uint32 prev = m_data[page_idx] >> 16;
73 Uint32 next = m_data[page_idx] & 0xFFFF;
75 assert(prev != 0xFFFF || (next_free_index == page_idx));
78 next_free_index = next;
82 Uint32 prevP = m_data[prev];
83 m_data[prev] = (prevP & 0xFFFF0000) | next;
88 Uint32 nextP = m_data[next];
89 m_data[next] = (prev << 16) | (nextP & 0xFFFF);
92 m_data[page_idx + 1] = 0;
99 Tup_fixsize_page::free_record(Uint32 page_idx)
101 Uint32 next = next_free_index;
103 assert(page_idx + 1 < DATA_WORDS);
104 assert(m_data[page_idx + 1] != FREE_RECORD);
108 assert(free_space == 0);
113 assert(next + 1 < DATA_WORDS);
114 Uint32 nextP = m_data[next];
115 assert((nextP >> 16) == 0xFFFF);
116 m_data[next] = (page_idx << 16) | (nextP & 0xFFFF);
117 assert(m_data[next + 1] == FREE_RECORD);
120 next_free_index = page_idx;
121 m_data[page_idx] = 0xFFFF0000 | next;
122 m_data[page_idx + 1] = FREE_RECORD;
128 Tup_varsize_page::init()
130 free_space= DATA_WORDS - 1;
133 next_free_index= END_OF_FREE_LIST;
134 m_page_header.m_page_type = File_formats::PT_Tup_varsize_page;
142 Uint32 free = free_space;
143 Uint32 largest_size= DATA_WORDS - (insert_pos + high_index);
144 Uint32 free_list = next_free_index;
146 if (page_idx < high_index)
148 Uint32 *ptr = get_index_ptr(page_idx);
151 if (unlikely((free < alloc_size) || ! (word & FREE)))
156 if (alloc_size >= largest_size)
166 Uint32 next = (word & NEXT_MASK) >> NEXT_SHIFT;
167 Uint32 prev = (word & PREV_MASK) >> PREV_SHIFT;
169 if (next != END_OF_FREE_LIST)
171 Uint32 * next_ptr = get_index_ptr(next);
172 Uint32 next_word = * next_ptr;
173 * next_ptr = (next_word & ~PREV_MASK) | (prev << PREV_SHIFT);
176 if (prev != END_OF_FREE_LIST)
178 Uint32 * prev_ptr = get_index_ptr(prev);
179 Uint32 prev_word = * prev_ptr;
180 * prev_ptr = (prev_word & ~NEXT_MASK) | (next << NEXT_SHIFT);
184 assert(next_free_index == page_idx);
185 next_free_index = next;
188 * ptr = insert_pos + (alloc_size << LEN_SHIFT);
196 Uint32 hi = high_index;
197 Uint32 expand = (page_idx + 1 - hi);
198 Uint32
size = alloc_size + expand;
199 if (unlikely(size > free))
204 if (size >= largest_size)
214 Uint32 *ptr = m_data + DATA_WORDS - hi;
217 * ptr = insert_pos + (alloc_size << LEN_SHIFT);
221 if (free_list != END_OF_FREE_LIST)
223 Uint32 * prev_ptr = get_index_ptr(free_list);
224 Uint32 prev_word = * prev_ptr;
225 * prev_ptr = (prev_word & ~PREV_MASK) | (hi << PREV_SHIFT);
228 for (; hi < page_idx;)
230 * ptr-- = FREE | (free_list << NEXT_SHIFT) | ((hi+1) << PREV_SHIFT);
234 * ptr++ = insert_pos + (alloc_size << LEN_SHIFT);
235 * ptr = ((* ptr) & ~PREV_MASK) | (END_OF_FREE_LIST << PREV_SHIFT);
237 next_free_index = hi - 1;
244 insert_pos += alloc_size;
253 assert(free_space >= alloc_size);
254 Uint32 largest_size= DATA_WORDS - (insert_pos + high_index);
255 if (alloc_size >= largest_size) {
262 largest_size= DATA_WORDS - (insert_pos + high_index);
264 assert(largest_size > alloc_size);
267 if (next_free_index == END_OF_FREE_LIST) {
272 page_idx= high_index++;
276 page_idx= next_free_index;
277 assert((get_index_word(page_idx) & FREE) == FREE);
278 assert(((get_index_word(page_idx) & PREV_MASK) >> PREV_SHIFT) ==
280 next_free_index= (get_index_word(page_idx) & NEXT_MASK) >> NEXT_SHIFT;
281 assert(next_free_index);
282 if (next_free_index != END_OF_FREE_LIST)
284 Uint32 *ptr = get_index_ptr(next_free_index);
286 * ptr = (word & ~PREV_MASK) | (END_OF_FREE_LIST << PREV_SHIFT);
290 assert(chain == 0 || chain == CHAIN);
291 * get_index_ptr(page_idx) = insert_pos + chain + (alloc_size << LEN_SHIFT);
293 insert_pos += alloc_size;
294 free_space -= alloc_size;
303 Uint32 *index_ptr= get_index_ptr(page_idx);
304 Uint32 index_word= * index_ptr;
305 Uint32 entry_pos= (index_word & POS_MASK) >> POS_SHIFT;
306 Uint32 entry_len= (index_word & LEN_MASK) >> LEN_SHIFT;
307 assert(chain == 0 || chain == CHAIN);
308 assert((index_word & CHAIN) == chain);
310 memset(m_data + entry_pos, 0xF2, 4*entry_len);
312 if (page_idx + 1 == high_index) {
321 if (next_free_index != END_OF_FREE_LIST)
323 Uint32 *ptr = get_index_ptr(next_free_index);
325 assert(((word & PREV_MASK) >> PREV_SHIFT) == END_OF_FREE_LIST);
326 * ptr = (word & ~PREV_MASK) | (page_idx << PREV_SHIFT);
328 * index_ptr= FREE | next_free_index | (END_OF_FREE_LIST << PREV_SHIFT);
329 next_free_index= page_idx;
330 assert(next_free_index);
333 free_space+= entry_len;
335 insert_pos -= (entry_pos + entry_len == insert_pos ? entry_len : 0);
344 Uint32 *end= m_data + DATA_WORDS;
349 for(index_ptr++; index_ptr < end; index_ptr++)
350 if((* index_ptr) & FREE)
360 next_free_index = END_OF_FREE_LIST;
364 Uint32 next= END_OF_FREE_LIST;
366 Uint32 *prev_ptr = &dummy;
367 for(index_ptr++; index_ptr < end; index_ptr++)
369 if ((* index_ptr) & FREE)
371 * index_ptr= FREE | next;
372 next= Uint32(end - index_ptr);
373 * prev_ptr |= (next << PREV_SHIFT);
374 prev_ptr = index_ptr;
378 * prev_ptr |= (END_OF_FREE_LIST << PREV_SHIFT);
382 next_free_index= next;
383 assert(next_free_index);
389 Uint32 new_insert_pos= 0;
390 Uint32 old_insert_pos= insert_pos;
393 memcpy(copy_page->m_data, m_data, 4*old_insert_pos);
394 assert(high_index > 0);
395 Uint32* index_ptr= get_index_ptr(high_index-1);
396 Uint32 *end_of_page= m_data + DATA_WORDS;
397 for (; index_ptr < end_of_page; index_ptr++)
399 Uint32 index_word= * index_ptr;
400 Uint32 entry_len= (index_word & LEN_MASK) >> LEN_SHIFT;
401 if (!(index_word & FREE) && entry_len)
407 Uint32 entry_pos= (index_word & POS_MASK) >> POS_SHIFT;
408 assert(entry_pos + entry_len <= old_insert_pos);
409 assert(new_insert_pos + entry_len <= old_insert_pos);
410 * index_ptr= (new_insert_pos << POS_SHIFT) + (index_word & ~POS_MASK);
411 memcpy(m_data+new_insert_pos, copy_page->m_data+entry_pos, 4*entry_len);
413 new_insert_pos += entry_len;
416 insert_pos= new_insert_pos;
422 out <<
"[ Varpage " << &page <<
": free: " << page.free_space
423 <<
" (" << (page.DATA_WORDS - (page.insert_pos + page.high_index + 1)) <<
")"
424 <<
" insert_pos: " << page.insert_pos
425 <<
" high_index: " << page.high_index
426 <<
" index: " << flush;
428 const Uint32 *index_ptr= page.m_data+page.DATA_WORDS-1;
429 for(Uint32
i = 1;
i<page.high_index;
i++, index_ptr--)
432 if(! (*index_ptr & page.FREE))
433 out <<
" pos: " << ((* index_ptr & page.POS_MASK) >> page.POS_SHIFT)
434 <<
" len: " << ((* index_ptr & page.LEN_MASK) >> page.LEN_SHIFT)
435 << ((* index_ptr & page.CHAIN) ?
" CHAIN " :
" ")
438 out <<
" FREE ]" << flush;
441 out <<
" free list: " << flush;
442 Uint32 next= page.next_free_index;
443 while(next != page.END_OF_FREE_LIST)
445 out << next <<
" " << flush;
446 next= ((* (page.m_data+page.DATA_WORDS-next)) & page.NEXT_MASK) >> page.NEXT_SHIFT;
455 out <<
"[ Fixpage " << &page
456 <<
": frag_page: " << page.frag_page_id
457 <<
" page_no: " << page.m_page_no
458 <<
" file_no: " << page.m_file_no
459 <<
" table: " << page.m_table_id
460 <<
" fragment: " << page.m_fragment_id
461 <<
" uncommitted_used_space: " << page.uncommitted_used_space
462 <<
" free: " << page.free_space;
464 out <<
" free list: " << hex << page.next_free_index <<
" " << flush;
466 Uint32 startTuple = page.next_free_index >> 16;
468 Uint32 next= startTuple;
469 while((next & 0xFFFF) != 0xFFFF)
472 out << dec <<
"(" << (next & 0xFFFF) <<
" " << hex << next <<
") " << flush;
473 assert(page.m_data[(next & 0xFFFF) + 1] == Dbtup::Tuple_header::FREE);
474 next= * (page.m_data + ( next & 0xFFFF ));
476 assert(cnt == page.free_space);