Below is the list of changes that have just been committed into a local
5.1 repository of jonas. When jonas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1946 05/10/31 16:12:52 jonas@stripped +6 -0
ndb -
first part of ROWID, cleanup free-list handling on varpage
storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
1.23 05/10/31 16:12:46 jonas@stripped +16 -12
First part of ROWID on varpage, fix free list handling
storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp
1.2 05/10/31 16:04:12 jonas@stripped +38 -18
First part of ROWID on varpage, fix free list handling
storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp
1.2 05/10/31 16:04:12 jonas@stripped +45 -25
First part of ROWID on varpage, fix free list handling
storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp
1.2 05/10/31 16:04:12 jonas@stripped +63 -13
Update unit test to also do shrink/expand (but no chaining...)
storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
1.2 05/10/31 16:04:12 jonas@stripped +0 -227
remove dead code
storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp
1.7 05/10/31 16:04:12 jonas@stripped +4 -10
Fix tupscan of varpage wrt to changes in free list handling
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: jonas
# Host: perch.ndb.mysql.com
# Root: /home/jonas/src/51-rowid
--- 1.1/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp 2005-10-25 14:18:29 +02:00
+++ 1.2/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp 2005-10-31 16:04:12 +01:00
@@ -73,88 +73,6 @@
}
void
-Dbtup::shrink_entry(Fragrecord* const regFragPtr,
- Var_page* const page_ptr,
- Uint32 page_index,
- Uint32 new_size)
-{
-
- page_ptr->shrink_entry(page_index, new_size);
- update_free_page_list(regFragPtr, page_ptr);
-}
-
-void
-Dbtup::check_entry_size(KeyReqStruct* req_struct,
- Operationrec* regOperPtr,
- Fragrecord* const regFragPtr,
- Tablerec* const regTabPtr)
-{
-#if 0
- Uint32 vp_index, no_var_attr, total_var_size, add_size, new_size, entry_len;
- Uint32 vp_offset, tuple_size, var_part_local;
- Uint32 *var_data_part, *var_link;
- PagePtr var_page_ptr;
- Uint32* tuple_ptr= req_struct->m_tuple_ptr;
- Uint32 page_index= regOperPtr->m_tuple_location.m_page_idx;
- tuple_size= regTabPtr->tupheadsize;
- no_var_attr= regTabPtr->no_var_attr;
- var_part_local= get_var_part_local(* (tuple_ptr+1));
- add_size= regTabPtr->var_array_wsize;
- var_link= tuple_ptr+tuple_size;
- if (var_part_local == 1) {
- ljam();
- var_data_part= var_link;
- var_page_ptr.p= req_struct->fix_page_ptr.p;
- add_size+= tuple_size;
- vp_index= regOperPtr->m_tuple_location.m_page_idx;
- } else {
- ljam();
- entry_len= get_entry_len(req_struct->var_page_ptr, page_index);
- if (entry_len > (tuple_size + 1)) {
- ljam();
- shrink_entry(regFragPtr,
- req_struct->fix_page_ptr,
- page_index,
- tuple_size + 1);
- } else {
- ndbassert(entry_len == (tuple_size + 1));
- }
- set_up_var_page(*var_link,
- regFragPtr,
- var_page_ptr,
- vp_index,
- vp_offset);
- var_data_part= &var_page_ptr.p->pageWord[vp_offset];
- }
- total_var_size= calculate_total_var_size((uint16*)var_data_part,
- no_var_attr);
- new_size= total_var_size + add_size;
- entry_len= get_entry_len(var_page_ptr.p, vp_index);
- if (new_size < entry_len) {
- ljam();
- shrink_entry(regFragPtr,
- var_page_ptr.p,
- vp_index,
- new_size);
- } else {
- ndbassert(entry_len == new_size);
- }
-#endif
-}
-
-inline
-void
-Dbtup::grow_entry(Fragrecord* const regFragPtr,
- Var_page* page_header,
- Uint32 page_index,
- Uint32 growth_len)
-{
- page_header->grow_entry(page_index, growth_len);
- update_free_page_list(regFragPtr, page_header);
-}
-
-
-void
Dbtup::setup_varsize_part(KeyReqStruct* req_struct,
Operationrec* const regOperPtr,
Tablerec* const regTabPtr)
@@ -546,151 +464,6 @@
}
return;
}
-
-
-#if 0
-/*
- This method is called whenever the variable part has been updated and
- has grown beyond its original size. This means that more space needs to
- be allocated to the record. If possible this space should be in the
- same page but we might have to allocate more space in a new page.
- In the case of a new page we must still keep the old page and the
- page index since this is the entrance to the record. In this case the
- record might have to be split into a fixed part and a variable part.
-
- This routine uses cinBuffer as temporary copy buffer. This is no longer
- used since it contains the interpreted program to use in the update
- and this has completed when this function is called.
-
- SYNOPSIS
- req_struct The structure for temporary content
- signal The signal object
- regOperPtr The operation record
- regFragPtr The fragment record
- regTabPtr The table record
-
- RETURN VALUES
- bool false if failed due to lack of memory
- */
-bool
-Dbtup::handle_growth_after_update(KeyReqStruct* req_struct,
- Fragrecord* const regFragPtr,
- Tablerec* const regTabPtr,
- Uint32 growth_len)
-{
- Uint32 vp_index, alloc_size, entry_len, curr_var_len;
- Uint32 new_vp_index, new_vp_offset, new_page_ref;
- Uint32 *copy_record= &cinBuffer[0];
- Ptr<Var_page> var_page= req_struct->var_page_ptr;
- Var_page* page_header= var_page.p;
- vp_index= req_struct->vp_index;
- entry_len= var_page.p->get_entry_len(vp_index);
- if (page_header->free_space >= growth_len) {
- /**
- * We will be able to handle the growth without changing the page
- * and page index.
- */
- if (page_header->largest_frag_size() >= entry_len + growth_len) {
- ljam();
- /**
- * In this case we need to copy the entry to the free space area of
- * the page, it is not necessary to reorganise the page.
- */
- MEMCOPY_NO_WORDS(page_header->get_free_space_ptr(),
- page_header->get_ptr(vp_index),
- entry_len);
- page_header->set_entry_offset(vp_index, page_header->insert_pos);
- page_header->insert_pos+= entry_len;
- } else {
- ljam();
- /**
- * In this case we need to reorganise the page to fit. To ensure we
- * don't complicate matters we make a little trick here where we
- * fool the reorg_page to avoid copying the entry at hand and copy
- * that separately at the end. This means we need to copy it out of
- * the page before reorg_page to save the entry contents.
- */
- MEMCOPY_NO_WORDS(copy_record,
- page_header->get_ptr(vp_index),
- entry_len);
- page_header->set_entry_len(vp_index, 0);
- page_header->free_space+= entry_len;
- reorg_page(page_header);
- MEMCOPY_NO_WORDS(page_header->get_free_space_ptr(),
- copy_record,
- entry_len);
- page_header->set_entry_offset(vp_index, page_header->insert_pos);
- growth_len+= entry_len;
- }
- grow_entry(regFragPtr,
- page_header,
- vp_index,
- growth_len);
- return true;
- } else {
- /**
- * It is necessary to allocate a segment from a new page.
- */
- if (req_struct->fix_var_together) {
- ljam();
- alloc_size= (entry_len + growth_len) - regTabPtr->tupheadsize;
- curr_var_len= alloc_size - regTabPtr->var_array_wsize;
- } else {
- ljam();
- curr_var_len= entry_len - regTabPtr->var_array_wsize;
- alloc_size= entry_len + growth_len;
- }
- Uint32* ptr, frag_page_id;
- Local_key key;
- if ((ptr= alloc_var_rec(regFragPtr,
- regTabPtr,
- alloc_size,
- &key, &frag_page_id)) == 0)
- {
- /**
- * No space existed for this growth. We need to abort the update.
- */
- ljam();
- terrorCode= ZMEM_NOMEM_ERROR;
- return false;
- }
-
- /*
- * I need to be careful to copy the var_len_array before freeing it.
- * The data part will be copied by copy_back_var_attr immediately
- * after returning from this method.
- * The updated var part is always in ctemp_var_record since I can
- * never arrive here after a first insert. Thus no danger of the
- * var part written being released.
- */
- MEMCOPY_NO_WORDS(ptr,
- req_struct->var_len_array,
- regTabPtr->var_array_wsize);
- req_struct->var_len_array= (Uint16*)ptr;
- if (! req_struct->fix_var_together) {
- ljam();
- /*
- * We need to deallocate the old variable part. This new one will
- * remain the variable part even if we abort the transaction.
- * We don't keep multiple references to the variable parts.
- * The copy data for abort is still kept in the copy record.
- */
- free_separate_var_part(regFragPtr, regTabPtr, req_struct->m_tuple_ptr);
- } else {
- ljam();
- req_struct->fix_var_together= false;
- }
- page_header= (Var_page*)var_page.p;
- new_page_ref= (key.m_page_no << MAX_TUPLES_BITS) + key.m_page_idx;
- req_struct->m_tuple_ptr->m_data[regTabPtr->var_offset] = new_page_ref;
- Uint32 bits= req_struct->m_tuple_ptr->m_header_bits;
- req_struct->m_tuple_ptr->m_header_bits |= Tuple_header::CHAINED_ROW;
- req_struct->var_page_ptr= var_page;
- req_struct->vp_index= key.m_page_idx;
- }
- return true;
-}
-#endif
/* ------------------------------------------------------------------------ */
--- 1.1/storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp 2005-10-25 14:18:30 +02:00
+++ 1.2/storage/ndb/src/kernel/blocks/dbtup/test_varpage.cpp 2005-10-31 16:04:12 +01:00
@@ -31,7 +31,7 @@
static
void
-do_test(int loops, int dist[3])
+do_test(int loops, int dist[5])
{
int allocated= 0;
Record records[8192];
@@ -51,14 +51,14 @@
loop:
int op;
int rnd= rand() % 100;
- for(op= 0; op<3; op++)
+ for(op= 0; op<5; op++)
if(rnd < dist[op])
break;
if(allocated == 0)
op= 0;
if(page.free_space <= 2 && op == 0) goto loop;
-
+
switch(op){
case 0: // Alloc
{
@@ -83,10 +83,11 @@
Record rec= records[no];
ndbout << "Free no: " << no << " idx: " << rec.idx << endl;
Uint32* ptr= page.get_ptr(rec.idx);
+ assert(page.get_entry_len(rec.idx) == rec.size);
cmp(ptr, rec.data, rec.size);
delete[] rec.data;
page.free_record(rec.idx, 0);
-
+
for (unsigned k = no; k + 1 < allocated; k++)
records[k] = records[k+1];
allocated--;
@@ -98,8 +99,57 @@
page.reorg(&tmp);
break;
case 3:
- ndbout << "Expand" << endl;
-
+ {
+ Uint32 free = page.free_space;
+ if (free <= 2)
+ {
+ goto shrink;
+ }
+ free /= 2;
+ int no = rand() % allocated;
+ Record rec= records[no];
+ ndbout << "Expand no: " << no << " idx: " << rec.idx
+ << " add: " << free << " reorg: "
+ << !page.is_space_behind_entry(rec.idx, free)
+ << endl;
+ if (!page.is_space_behind_entry(rec.idx, free))
+ {
+ Uint32 buffer[8192];
+ Uint32 len = page.get_entry_len(rec.idx);
+ memcpy(buffer, page.get_ptr(rec.idx), 4*len);
+ page.set_entry_len(rec.idx, 0);
+ page.free_space += len;
+ page.reorg(&tmp);
+ memcpy(page.get_free_space_ptr(), buffer, 4*len);
+ page.set_entry_offset(rec.idx, page.insert_pos);
+ free += len;
+ records[no].size = 0;
+ }
+
+ page.grow_entry(rec.idx, free);
+ records[no].size += free;
+ Uint32 *ptr = page.get_ptr(rec.idx);
+ Uint32 *new_data = new Uint32[records[no].size];
+ for(Uint32 i= 0; i<records[no].size; i++)
+ {
+ ptr[i] = new_data[i] = rand();
+ }
+ delete []rec.data;
+ records[no].data = new_data;
+ break;
+ }
+ case 4:
+ {
+ shrink:
+ int no = rand() % allocated;
+ Record rec = records[no];
+ Uint32 sz = rec.size / 2 + 1;
+ ndbout << "Shrink no: " << no << " idx: " << rec.idx << " remove: "
+ << (rec.size - sz) << endl;
+ page.shrink_entry(rec.idx, sz);
+ records[no].size = sz;
+ break;
+ }
}
}
@@ -110,16 +160,16 @@
main(void)
{
ndb_init();
+
+ // alloc, free, reorg, grow, shrink
- int t1[] = { 30, 90, 100 };
- int t2[] = { 45, 90, 100 };
- int t3[] = { 60, 90, 100 };
- int t4[] = { 75, 90, 100 };
+ int t1[] = { 10, 60, 70, 85, 100 };
+ int t2[] = { 30, 60, 70, 85, 100 };
+ int t3[] = { 50, 60, 70, 85, 100 };
do_test(10000, t1);
- do_test(10000, t2);
- do_test(10000, t3);
- do_test(10000, t4);
+ //do_test(10000, t2);
+ //do_test(10000, t3);
}
template class Vector<Record>;
--- 1.1/storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp 2005-10-25 14:18:30 +02:00
+++ 1.2/storage/ndb/src/kernel/blocks/dbtup/tuppage.cpp 2005-10-31 16:04:12 +01:00
@@ -18,6 +18,20 @@
#include "tuppage.hpp"
#include "Dbtup.hpp"
+/**
+ * Fix pages maintain a double linked list of free entries
+ *
+ * Var pages has a directory where each entry is
+ * [ C(1), F(1), L(15), P(15) ]
+ * C is chain bit, (is it a full tuple or just chain)
+ * F is free bit
+ * If true, L is prev free entry (in directory)
+ * P is next free entry (in directory)
+ * else
+ * L is len of entry
+ * P is pos of entry
+ */
+
Uint32
Tup_fixsize_page::alloc_record()
{
@@ -116,7 +130,7 @@
free_space= DATA_WORDS - 1;
high_index= 1;
insert_pos= 0;
- next_free_index= 0xFFFF;
+ next_free_index= END_OF_FREE_LIST;
m_page_header.m_page_type = File_formats::PT_Tup_varsize_page;
}
@@ -138,7 +152,7 @@
assert(largest_size > alloc_size);
Uint32 page_idx;
- if (next_free_index == 0xFFFF) {
+ if (next_free_index == END_OF_FREE_LIST) {
/*
We are out of free index slots. We will extend the array of free
slots
@@ -148,12 +162,13 @@
} else {
// Pick an empty slot among the index entries
page_idx= next_free_index;
- assert((get_index_word(page_idx) & 0xFFFF0000) == 0);
- next_free_index= get_index_word(page_idx);
+ assert((get_index_word(page_idx) & FREE) == FREE);
+ next_free_index= (get_index_word(page_idx) & NEXT_MASK) >> NEXT_SHIFT;
+ assert(next_free_index);
}
assert(chain == 0 || chain == CHAIN);
- * get_index_ptr(page_idx) = insert_pos + ((chain + alloc_size) << 16);
+ * get_index_ptr(page_idx) = insert_pos + chain + (alloc_size << LEN_SHIFT);
insert_pos += alloc_size;
free_space -= alloc_size;
@@ -167,10 +182,10 @@
//ndbout_c("%p->free_record(%d%s)", this, page_idx, (chain ? " CHAIN": ""));
Uint32 *index_ptr= get_index_ptr(page_idx);
Uint32 index_word= * index_ptr;
- Uint32 entry_pos= index_word & 0xFFFF;
- Uint32 entry_len= (index_word >> 16) & ~CHAIN;
+ Uint32 entry_pos= (index_word & POS_MASK) >> POS_SHIFT;
+ Uint32 entry_len= (index_word & LEN_MASK) >> LEN_SHIFT;
assert(chain == 0 || chain == CHAIN);
- assert(!(((index_word >> 16) ^ chain) & 0x8000));
+ assert((index_word & CHAIN) == chain);
#ifdef VM_TRACE
memset(m_data + entry_pos, 0xF2, 4*entry_len);
#endif
@@ -182,9 +197,11 @@
free space accordingly.
*/
rebuild_index(index_ptr);
+ ndbout_c("rebuild");
} else {
- * index_ptr= next_free_index;
+ * index_ptr= FREE | next_free_index;
next_free_index= page_idx;
+ assert(next_free_index);
}
free_space+= entry_len;
@@ -204,7 +221,7 @@
* Scan until you find first non empty index pos
*/
for(index_ptr++; index_ptr < end; index_ptr++)
- if((* index_ptr >> 16) == 0)
+ if(* index_ptr & FREE)
empty++;
else
break;
@@ -214,23 +231,25 @@
// Totally free page
high_index = 1;
free_space += empty;
- next_free_index= 0xFFFF;
+ next_free_index = END_OF_FREE_LIST;
+ assert(next_free_index);
return;
}
-
- Uint32 next= 0xFFFF;
+
+ Uint32 next= END_OF_FREE_LIST;
high_index -= empty;
for(index_ptr++; index_ptr < end; index_ptr++)
{
- if((* index_ptr >> 16) == 0)
+ if(* index_ptr & FREE)
{
- * index_ptr= next;
+ * index_ptr= FREE | next;
next= (end - index_ptr);
}
}
free_space += empty;
next_free_index= next;
+ assert(next_free_index);
}
void
@@ -247,16 +266,17 @@
for (; index_ptr < end_of_page; index_ptr++)
{
Uint32 index_word= * index_ptr;
- Uint32 entry_len= (index_word >> 16) & ~CHAIN;
- if (entry_len != 0) {
+ Uint32 entry_len= (index_word & LEN_MASK) >> LEN_SHIFT;
+ if (!(index_word & FREE) && entry_len)
+ {
/*
We found an index item that needs to be packed.
We will update the index entry and copy the data to the page.
*/
- Uint32 entry_pos= index_word & 0xffff;
+ Uint32 entry_pos= (index_word & POS_MASK) >> POS_SHIFT;
assert(entry_pos + entry_len <= old_insert_pos);
assert(new_insert_pos + entry_len <= old_insert_pos);
- * index_ptr= new_insert_pos + (index_word & 0xFFFF0000);
+ * index_ptr= (new_insert_pos << POS_SHIFT) + (index_word & ~POS_MASK);
memcpy(m_data+new_insert_pos, copy_page->m_data+entry_pos, 4*entry_len);
new_insert_pos += entry_len;
@@ -278,10 +298,10 @@
for(Uint32 i = 1; i<page.high_index; i++, index_ptr--)
{
out << " [ " << i;
- if(*index_ptr >> 16)
- out << " pos: " << ((*index_ptr) & 0xFFFF)
- << " len: " << ((*index_ptr >> 16) & ~page.CHAIN)
- << (((* index_ptr >> 16) & page.CHAIN) ? " CHAIN " : " ")
+ if(! (*index_ptr & page.FREE))
+ out << " pos: " << ((* index_ptr & page.POS_MASK) >> page.POS_SHIFT)
+ << " len: " << ((* index_ptr & page.LEN_MASK) >> page.LEN_SHIFT)
+ << ((* index_ptr & page.CHAIN) ? " CHAIN " : " ")
<< "]" << flush;
else
out << " FREE ]" << flush;
@@ -289,10 +309,10 @@
out << " free list: " << flush;
Uint32 next= page.next_free_index;
- while(next != 0xFFFF)
+ while(next != page.END_OF_FREE_LIST)
{
out << next << " " << flush;
- next= * (page.m_data+page.DATA_WORDS-next);
+ next= ((* (page.m_data+page.DATA_WORDS-next)) & page.NEXT_MASK) >> page.NEXT_SHIFT;
}
out << "]";
return out;
--- 1.1/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp 2005-10-25 14:18:30 +02:00
+++ 1.2/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp 2005-10-31 16:04:12 +01:00
@@ -127,7 +127,18 @@
Uint32 unused_ph[7];
STATIC_CONST( DATA_WORDS = File_formats::NDB_PAGE_SIZE_WORDS - 32 );
- STATIC_CONST( CHAIN = 0x8000 );
+ STATIC_CONST( CHAIN = 0x80000000 );
+ STATIC_CONST( FREE = 0x40000000 );
+ STATIC_CONST( LEN_MASK = 0x3FFF8000 );
+ STATIC_CONST( POS_MASK = 0x00007FFF );
+ STATIC_CONST( LEN_SHIFT = 15 );
+ STATIC_CONST( POS_SHIFT = 0 );
+ STATIC_CONST( END_OF_FREE_LIST = POS_MASK );
+
+ STATIC_CONST( NEXT_MASK = POS_MASK );
+ STATIC_CONST( NEXT_SHIFT = POS_SHIFT );
+ //STATIC_CONST( PREV_MASK = LEN_MASK );
+ //STATIC_CONST( PREV_SHIFT = LEN_SHIFT );
Uint32 m_data[DATA_WORDS];
@@ -170,8 +181,8 @@
*/
bool is_space_behind_entry(Uint32 page_index, Uint32 growth_len) const {
Uint32 idx= get_index_word(page_index);
- Uint32 pos= idx & 0xFFFF;
- Uint32 len= (idx >> 16) & ~CHAIN;
+ Uint32 pos= (idx & POS_MASK) >> POS_SHIFT;
+ Uint32 len= (idx & LEN_MASK) >> LEN_SHIFT;
if ((pos + len == insert_pos) &&
(insert_pos + growth_len < DATA_WORDS - high_index))
return true;
@@ -180,12 +191,14 @@
void grow_entry(Uint32 page_index, Uint32 growth_len) {
assert(free_space >= growth_len);
-
+
Uint32 *pos= get_index_ptr(page_index);
Uint32 idx= *pos;
- Uint32 size= (idx >> 16) + growth_len;
- *pos= (idx & 0xFFFF) + (size << 16);
- assert((idx & 0xFFFF) + ((idx >> 16) & ~CHAIN) == insert_pos);
+ assert(! (idx & FREE));
+ assert((((idx & POS_MASK) >> POS_SHIFT) + ((idx & LEN_MASK) >> LEN_SHIFT))
+ == insert_pos);
+
+ * pos= idx + (growth_len << LEN_SHIFT);
insert_pos+= growth_len;
free_space-= growth_len;
}
@@ -193,35 +206,42 @@
void shrink_entry(Uint32 page_index, Uint32 new_size){
Uint32 *pos= get_index_ptr(page_index);
Uint32 idx= *pos;
- *pos= (idx & (CHAIN << 16 | 0xFFFF)) + (new_size << 16);
- Uint32 old_size= (idx >> 16) & ~CHAIN;
-
+ Uint32 old_pos = (idx & POS_MASK) >> POS_SHIFT;
+ Uint32 old_size = (idx & LEN_MASK) >> LEN_SHIFT;
+
+ assert( ! (idx & FREE));
assert(old_size >= new_size);
+
+ * pos= (idx & ~LEN_MASK) + (new_size << LEN_SHIFT);
Uint32 shrink = old_size - new_size;
#ifdef VM_TRACE
- memset(m_data + (idx & 0xFFFF) + new_size, 0xF1, 4 * shrink);
+ memset(m_data + old_pos + new_size, 0xF1, 4 * shrink);
#endif
free_space+= shrink;
- if(insert_pos == ((idx & 0xFFFF) + old_size))
+ if(insert_pos == (old_pos + old_size))
insert_pos -= shrink;
}
Uint32* get_ptr(Uint32 page_idx) {
- return m_data + (get_index_word(page_idx) & 0xFFFF);
+ return m_data + ((get_index_word(page_idx) & POS_MASK) >> POS_SHIFT);
}
void set_entry_offset(Uint32 page_idx, Uint32 offset){
Uint32 *pos= get_index_ptr(page_idx);
- *pos = (* pos & 0xFFFF0000) + offset;
+ * pos = (* pos & ~POS_MASK) + (offset << POS_SHIFT);
}
+ void set_entry_len(Uint32 page_idx, Uint32 len) {
+ Uint32 *pos= get_index_ptr(page_idx);
+ * pos = (*pos & ~LEN_MASK) + (len << LEN_SHIFT);
+ }
+
Uint32 get_entry_len(Uint32 page_idx) const {
- return get_index_word(page_idx) >> 16;
+ return (get_index_word(page_idx) & LEN_MASK) >> LEN_SHIFT;
}
- void set_entry_len(Uint32 page_idx, Uint32 len) {
- Uint32 *pos= get_index_ptr(page_idx);
- *pos = (len << 16) + (*pos & (CHAIN << 16 | 0xFFFF));
+ Uint32 get_entry_chain(Uint32 page_idx) const {
+ return get_index_word(page_idx) & CHAIN;
}
};
--- 1.22/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2005-10-25 10:09:00 +02:00
+++ 1.23/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp 2005-10-31 16:12:46 +01:00
@@ -2751,14 +2751,15 @@
for(Uint32 i=1; i<page->high_index; i++)
{
- Uint32 len= page->get_entry_len(i);
- if(len && !(len & Var_page::CHAIN))
+ Uint32 idx= page->get_index_word(i);
+ Uint32 len = (idx & Var_page::LEN_MASK) >> Var_page::LEN_SHIFT;
+ if(!(idx & Var_page::FREE) && !(idx & Var_page::CHAIN))
{
Tuple_header *ptr= (Tuple_header*)page->get_ptr(i);
Uint32 *part= ptr->get_var_part_ptr(regTabPtr);
if(ptr->m_header_bits & Tuple_header::CHAINED_ROW)
{
- assert(len == fix_sz + 1);
+ ndbassert(len == fix_sz + 1);
Local_key tmp; tmp= *part;
Ptr<Var_page> tmpPage;
part= get_ptr(&tmpPage, *(Var_part_ref*)part);
@@ -2776,14 +2777,14 @@
c_operation_pool.getPtr(ptr->m_operation_ptr_i);
}
}
- else if(len)
+ else if(!(idx & Var_page::FREE))
{
/**
* Chain
*/
Uint32 *part= page->get_ptr(i);
Uint32 sz= ((mm_vars + 1) << 1) + (((Uint16*)part)[mm_vars]);
- ndbassert((len & ~Var_page::CHAIN) >= ((sz + 3) >> 2));
+ ndbassert(len >= ((sz + 3) >> 2));
}
else
{
@@ -2837,8 +2838,8 @@
if(! (bits & Tuple_header::CHAINED_ROW))
{
idx= regOperPtr->m_tuple_location.m_page_idx;
- alloc= pageP->get_entry_len(idx) & ~Var_page::CHAIN;
- ndbassert(!(pageP->get_entry_len(idx) & Var_page::CHAIN));
+ alloc= pageP->get_entry_len(idx);
+ ndbassert(!(pageP->get_entry_chain(idx)));
needed= sizes[2+MM];
}
else
@@ -2846,10 +2847,12 @@
Local_key tmp;
tmp= *org->get_var_part_ptr(regTabPtr);
idx= tmp.m_page_idx;
- alloc= pageP->get_entry_len(idx) & ~Var_page::CHAIN;
- if(!(pageP->get_entry_len(idx) & Var_page::CHAIN))
+ alloc= pageP->get_entry_len(idx);
+#ifdef VM_TRACE
+ if(!pageP->get_entry_chain(idx))
ndbout << *pageP << endl;
- ndbassert(pageP->get_entry_len(idx) & Var_page::CHAIN);
+#endif
+ ndbassert(pageP->get_entry_chain(idx));
needed= sizes[2+MM] - fix_sz;
}
@@ -2886,8 +2889,9 @@
add += alloc;
}
pageP->grow_entry(idx, add);
- ndbassert((pageP->get_entry_len(idx) & Var_page::CHAIN) ==
- (bits & Tuple_header::CHAINED_ROW ? Var_page::CHAIN : 0));
+ ndbassert(pageP->get_entry_chain(idx) ?
+ (bits & Tuple_header::CHAINED_ROW) :
+ !(bits & Tuple_header::CHAINED_ROW));
update_free_page_list(regFragPtr, pageP);
}
else
--- 1.6/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp 2005-10-13 10:52:15 +02:00
+++ 1.7/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp 2005-10-31 16:04:12 +01:00
@@ -310,22 +310,16 @@
continue;
}
- Uint32 len= page_ptr->get_entry_len(key.m_page_idx);
- if (len == 0)
+ Uint32 idx = page_ptr->get_index_word(key.m_page_idx);
+ if (idx & (Var_page::CHAIN | Var_page::FREE))
{
- // skip empty slot or
+ // skip empty slot or chain
jam();
continue;
}
- if(len & Var_page::CHAIN)
- {
- // skip varpart chain
- jam();
- continue;
- }
th = (Tuple_header*)page_ptr->get_ptr(key.m_page_idx);
}
-
+
if(bits & ScanOp::SCAN_LCP &&
th->m_header_bits & Tuple_header::LCP_SKIP)
{
| Thread |
|---|
| • bk commit into 5.1 tree (jonas:1.1946) | jonas | 31 Oct |