summaryrefslogtreecommitdiff
path: root/storage/maria/ma_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/maria/ma_write.c')
-rw-r--r--storage/maria/ma_write.c611
1 files changed, 320 insertions, 291 deletions
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 3d599267b3e..df99b910421 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -25,36 +25,32 @@
/* Functions declared in this file */
-static int w_search(register MARIA_HA *info, uint32 comp_flag,
+static int w_search(MARIA_HA *info, uint32 comp_flag,
MARIA_KEY *key, my_off_t page,
- my_off_t father_page, uchar *father_buff,
- MARIA_PINNED_PAGE *father_page_link, uchar *father_keypos,
+ MARIA_PAGE *father_page, uchar *father_keypos,
my_bool insert_last);
-static int _ma_balance_page(MARIA_HA *info,MARIA_KEYDEF *keyinfo,
- MARIA_KEY *key, uchar *curr_buff, my_off_t page,
- my_off_t father_page, uchar *father_buff,
- uchar *father_keypos,
- MARIA_KEY_PARAM *s_temp);
-static uchar *_ma_find_last_pos(MARIA_HA *info, MARIA_KEY *int_key,
- uchar *page, uchar **after_key);
+static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ MARIA_KEY *key, MARIA_PAGE *curr_page,
+ MARIA_PAGE *father_page,
+ uchar *father_key_pos, MARIA_KEY_PARAM *s_temp);
+static uchar *_ma_find_last_pos(MARIA_KEY *int_key,
+ MARIA_PAGE *page, uchar **after_key);
static my_bool _ma_ck_write_tree(register MARIA_HA *info, MARIA_KEY *key);
static my_bool _ma_ck_write_btree(register MARIA_HA *info, MARIA_KEY *key);
-static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEY *key,
+static my_bool _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEY *key,
my_off_t *root, uint32 comp_flag);
-static my_bool _ma_log_split(MARIA_HA *info, my_off_t page, const uchar *buff,
- uint org_length, uint new_length,
+static my_bool _ma_log_split(MARIA_PAGE *page, uint org_length,
+ uint new_length,
const uchar *key_pos,
uint key_length, int move_length,
enum en_key_op prefix_or_suffix,
const uchar *data, uint data_length,
uint changed_length);
-static my_bool _ma_log_del_prefix(MARIA_HA *info, my_off_t page,
- const uchar *buff,
+static my_bool _ma_log_del_prefix(MARIA_PAGE *page,
uint org_length, uint new_length,
const uchar *key_pos, uint key_length,
int move_length);
-static my_bool _ma_log_key_middle(MARIA_HA *info, my_off_t page,
- const uchar *buff,
+static my_bool _ma_log_key_middle(MARIA_PAGE *page,
uint new_length,
uint data_added_first,
uint data_changed_first,
@@ -381,12 +377,12 @@ static my_bool _ma_ck_write_btree(MARIA_HA *info, MARIA_KEY *key)
/**
@brief Write a key to the b-tree
- @retval -1 error
+ @retval 1 error
@retval 0 ok
*/
-static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEY *key,
- my_off_t *root, uint32 comp_flag)
+static my_bool _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEY *key,
+ my_off_t *root, uint32 comp_flag)
{
MARIA_SHARE *share= info->s;
LSN lsn= LSN_IMPOSSIBLE;
@@ -419,18 +415,18 @@ static int _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEY *key,
}
_ma_unpin_all_pages_and_finalize_row(info, lsn);
- DBUG_RETURN(error);
+ DBUG_RETURN(error != 0);
} /* _ma_ck_write_btree_with_log */
/**
@brief Write a key to the b-tree
- @retval -1 error
+ @retval 1 error
@retval 0 ok
*/
-int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEY *key, my_off_t *root,
+my_bool _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEY *key, my_off_t *root,
uint32 comp_flag)
{
int error;
@@ -438,68 +434,74 @@ int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEY *key, my_off_t *root,
/* key_length parameter is used only if comp_flag is SEARCH_FIND */
if (*root == HA_OFFSET_ERROR ||
- (error= w_search(info, comp_flag, key, *root, (my_off_t) 0, (uchar*) 0,
- (MARIA_PINNED_PAGE *) 0, (uchar*) 0, 1)) > 0)
+ (error= w_search(info, comp_flag, key, *root, (MARIA_PAGE *) 0,
+ (uchar*) 0, 1)) > 0)
error= _ma_enlarge_root(info, key, root);
- DBUG_RETURN(error);
+ DBUG_RETURN(error != 0);
} /* _ma_ck_real_write_btree */
/**
@brief Make a new root with key as only pointer
- @retval -1 error
+ @retval 1 error
@retval 0 ok
*/
-int _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key, my_off_t *root)
+my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key, my_off_t *root)
{
- uint t_length, page_flag, nod_flag, page_length;
+ uint t_length, nod_flag;
MARIA_KEY_PARAM s_temp;
MARIA_SHARE *share= info->s;
MARIA_PINNED_PAGE tmp_page_link, *page_link= &tmp_page_link;
MARIA_KEYDEF *keyinfo= key->keyinfo;
- int res= 0;
+ MARIA_PAGE page;
+ my_bool res= 0;
DBUG_ENTER("_ma_enlarge_root");
+ page.info= info;
+ page.keyinfo= keyinfo;
+ page.buff= info->buff;
+ page.flag= 0;
+
nod_flag= (*root != HA_OFFSET_ERROR) ? share->base.key_reflength : 0;
/* Store pointer to prev page if nod */
- _ma_kpointer(info, info->buff + share->keypage_header, *root);
+ _ma_kpointer(info, page.buff + share->keypage_header, *root);
t_length= (*keyinfo->pack_key)(key, nod_flag, (uchar*) 0,
(uchar*) 0, (uchar*) 0, &s_temp);
- page_length= share->keypage_header + t_length + nod_flag;
+ page.size= share->keypage_header + t_length + nod_flag;
- bzero(info->buff, share->keypage_header);
- _ma_store_keynr(share, info->buff, keyinfo->key_nr);
- _ma_store_page_used(share, info->buff, page_length);
- page_flag= 0;
+ bzero(page.buff, share->keypage_header);
+ _ma_store_keynr(share, page.buff, keyinfo->key_nr);
if (nod_flag)
- page_flag|= KEYPAGE_FLAG_ISNOD;
+ page.flag|= KEYPAGE_FLAG_ISNOD;
if (key->flag & (SEARCH_USER_KEY_HAS_TRANSID | SEARCH_PAGE_KEY_HAS_TRANSID))
- page_flag|= KEYPAGE_FLAG_HAS_TRANSID;
- _ma_store_keypage_flag(share, info->buff, page_flag);
- (*keyinfo->store_key)(keyinfo, info->buff + share->keypage_header +
+ page.flag|= KEYPAGE_FLAG_HAS_TRANSID;
+ (*keyinfo->store_key)(keyinfo, page.buff + share->keypage_header +
nod_flag, &s_temp);
/* Mark that info->buff was used */
info->keyread_buff_used= info->page_changed= 1;
- if ((*root= _ma_new(info, PAGECACHE_PRIORITY_HIGH, &page_link)) ==
+ if ((page.pos= _ma_new(info, PAGECACHE_PRIORITY_HIGH, &page_link)) ==
HA_OFFSET_ERROR)
- DBUG_RETURN(-1);
+ DBUG_RETURN(1);
+ *root= page.pos;
+
+ page_store_info(share, &page);
/*
Clear unitialized part of page to avoid valgrind/purify warnings
and to get a clean page that is easier to compress and compare with
pages generated with redo
*/
- bzero(info->buff + page_length, share->block_size - page_length);
+ bzero(page.buff + page.size, share->block_size - page.size);
- if (share->now_transactional &&
- _ma_log_new(info, *root, info->buff, page_length, keyinfo->key_nr, 1))
- res= -1;
- if (_ma_write_keypage(info, keyinfo, *root, page_link->write_lock,
- PAGECACHE_PRIORITY_HIGH, info->buff))
- res= -1;
+ if (share->now_transactional && _ma_log_new(&page, 1))
+ res= 1;
+
+ if (_ma_write_keypage(&page, page_link->write_lock,
+ PAGECACHE_PRIORITY_HIGH))
+ res= 1;
DBUG_RETURN(res);
} /* _ma_enlarge_root */
@@ -515,33 +517,30 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key, my_off_t *root)
*/
static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key,
- my_off_t page, my_off_t father_page, uchar *father_buff,
- MARIA_PINNED_PAGE *father_page_link, uchar *father_keypos,
+ my_off_t page_pos,
+ MARIA_PAGE *father_page, uchar *father_keypos,
my_bool insert_last)
{
int error,flag;
- uint page_flag, nod_flag;
uchar *temp_buff,*keypos;
uchar keybuff[MARIA_MAX_KEY_BUFF];
my_bool was_last_key;
my_off_t next_page, dup_key_pos;
- MARIA_PINNED_PAGE *page_link;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ MARIA_PAGE page;
DBUG_ENTER("w_search");
- DBUG_PRINT("enter",("page: %ld", (long) page));
+ DBUG_PRINT("enter",("page: %ld", (long) page_pos));
if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MARIA_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
- if (!_ma_fetch_keypage(info, keyinfo, page, PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, temp_buff, 0, &page_link))
+ if (_ma_fetch_keypage(&page, info, keyinfo, page_pos, PAGECACHE_LOCK_WRITE,
+ DFLT_INIT_HITS, temp_buff, 0))
goto err;
- flag= (*keyinfo->bin_search)(key, temp_buff, comp_flag, &keypos,
+ flag= (*keyinfo->bin_search)(key, &page, comp_flag, &keypos,
keybuff, &was_last_key);
- page_flag= _ma_get_keypage_flag(share, temp_buff);
- nod_flag= _ma_test_if_nod(share, temp_buff);
if (flag == 0)
{
MARIA_KEY tmp_key;
@@ -550,7 +549,7 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key,
tmp_key.keyinfo= keyinfo;
tmp_key.data= keybuff;
- if ((*keyinfo->get_key)(&tmp_key, page_flag, nod_flag, &keypos))
+ if ((*keyinfo->get_key)(&tmp_key, page.flag, page.node, &keypos))
dup_key_pos= _ma_row_pos_from_key(&tmp_key);
else
dup_key_pos= HA_OFFSET_ERROR;
@@ -566,7 +565,7 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key,
if (subkeys >= 0)
{
/* normal word, one-level tree structure */
- flag=(*keyinfo->bin_search)(key, temp_buff, comp_flag,
+ flag=(*keyinfo->bin_search)(key, &page, comp_flag,
&keypos, keybuff, &was_last_key);
}
else
@@ -577,7 +576,7 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key,
get_key_full_length_rdonly(off, key);
key+=off;
/* we'll modify key entry 'in vivo' */
- keypos-= keyinfo->keylength + nod_flag;
+ keypos-= keyinfo->keylength + page.node;
error= _ma_ck_real_write_btree(info, key, &root, comp_flag);
_ma_dpointer(share, keypos+HA_FT_WLEN, root);
subkeys--; /* should there be underflow protection ? */
@@ -585,12 +584,12 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key,
ft_intXstore(keypos, subkeys);
if (!error)
{
- page_link->changed= 1;
- error= _ma_write_keypage(info, keyinfo, page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, temp_buff);
+ page_mark_changed(info, &page);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ goto err;
}
- my_afree((uchar*) temp_buff);
+ my_afree(temp_buff);
DBUG_RETURN(error);
}
}
@@ -598,34 +597,32 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key,
{
DBUG_PRINT("warning", ("Duplicate key"));
info->dup_key_pos= dup_key_pos;
- my_afree((uchar*) temp_buff);
my_errno=HA_ERR_FOUND_DUPP_KEY;
- DBUG_RETURN(-1);
+ goto err;
}
}
if (flag == MARIA_FOUND_WRONG_KEY)
- DBUG_RETURN(-1);
+ goto err;
if (!was_last_key)
insert_last=0;
- next_page= _ma_kpos(nod_flag,keypos);
+ next_page= _ma_kpos(page.node, keypos);
if (next_page == HA_OFFSET_ERROR ||
(error= w_search(info, comp_flag, key, next_page,
- page, temp_buff, page_link, keypos, insert_last)) > 0)
+ &page, keypos, insert_last)) > 0)
{
- error= _ma_insert(info, key, temp_buff, keypos, page, keybuff,
- father_page, father_buff, father_page_link,
- father_keypos, insert_last);
- page_link->changed= 1;
- if (_ma_write_keypage(info, keyinfo, page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS,temp_buff))
+ error= _ma_insert(info, key, &page, keypos, keybuff,
+ father_page, father_keypos, insert_last);
+ page_mark_changed(info, &page);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
goto err;
}
- my_afree((uchar*) temp_buff);
+ my_afree(temp_buff);
DBUG_RETURN(error);
err:
- my_afree((uchar*) temp_buff);
+ my_afree(temp_buff);
DBUG_PRINT("exit",("Error: %d",my_errno));
- DBUG_RETURN (-1);
+ DBUG_RETURN(-1);
} /* w_search */
@@ -637,13 +634,10 @@ err:
info Open table information.
keyinfo Key definition information.
key New key
- anc_buff Key page (beginning).
+ anc_page Key page (beginning)
key_pos Position in key page where to insert.
- anc_page Page number for anc_buff
key_buff Copy of previous key if keys where packed.
father_page position of parent key page in file.
- father_buff parent key page for balancing.
- father_page_link Link to father page for marking page changed
father_key_pos position in parent key page for balancing.
insert_last If to append at end of page.
@@ -661,15 +655,14 @@ err:
2 If key contains key to upper level (from split space)
*/
-int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, uchar *anc_buff,
- uchar *key_pos, my_off_t anc_page, uchar *key_buff,
- my_off_t father_page, uchar *father_buff,
- MARIA_PINNED_PAGE *father_page_link,
- uchar *father_key_pos, my_bool insert_last)
+int _ma_insert(register MARIA_HA *info, MARIA_KEY *key,
+ MARIA_PAGE *anc_page, uchar *key_pos, uchar *key_buff,
+ MARIA_PAGE *father_page, uchar *father_key_pos,
+ my_bool insert_last)
{
uint a_length, nod_flag, org_anc_length;
int t_length;
- uchar *endpos, *prev_key;
+ uchar *endpos, *prev_key, *anc_buff;
MARIA_KEY_PARAM s_temp;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
@@ -677,8 +670,10 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, uchar *anc_buff,
DBUG_PRINT("enter",("key_pos: 0x%lx", (ulong) key_pos));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, key););
- _ma_get_used_and_nod(share, anc_buff, a_length, nod_flag);
- org_anc_length= a_length;
+ org_anc_length= a_length= anc_page->size;
+ nod_flag= anc_page->node;
+
+ anc_buff= anc_page->buff;
endpos= anc_buff+ a_length;
prev_key= (key_pos == anc_buff + share->keypage_header + nod_flag ?
(uchar*) 0 : key_buff);
@@ -702,7 +697,6 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, uchar *anc_buff,
{
if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
{
- maria_print_error(share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(-1);
}
@@ -713,7 +707,6 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, uchar *anc_buff,
{
if (-t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
{
- maria_print_error(share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(-1);
}
@@ -723,8 +716,11 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, uchar *anc_buff,
a_length+=t_length;
if (key->flag & (SEARCH_USER_KEY_HAS_TRANSID | SEARCH_PAGE_KEY_HAS_TRANSID))
- _ma_mark_page_with_transid(share, anc_buff);
- _ma_store_page_used(share, anc_buff, a_length);
+ {
+ _ma_mark_page_with_transid(share, anc_page);
+ }
+ anc_page->size= a_length;
+ page_store_size(share, anc_page);
/*
Check if the new key fits totally into the the page
@@ -784,8 +780,8 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
insert_dynamic(info->ft1_to_ft2, b);
/* fixing the page's length - it contains only one key now */
- _ma_store_page_used(share, anc_buff, share->keypage_header + blen +
- ft2len + 2);
+ anc_page->size= share->keypage_header + blen + ft2len + 2;
+ page_store_size(share, anc_page);
}
/* the rest will be done when we're back from recursion */
}
@@ -793,7 +789,7 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
else
{
if (share->now_transactional &&
- _ma_log_add(info, anc_page, anc_buff, (uint) (endpos - anc_buff),
+ _ma_log_add(anc_page, org_anc_length,
key_pos, s_temp.changed_length, t_length, 0))
DBUG_RETURN(-1);
}
@@ -809,17 +805,16 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
_ma_balance_page_ can't handle variable length keys.
*/
if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)) &&
- father_buff && !insert_last && !info->quick_mode &&
+ father_page && !insert_last && !info->quick_mode &&
!info->s->base.born_transactional)
{
s_temp.key_pos= key_pos;
- father_page_link->changed= 1;
- DBUG_RETURN(_ma_balance_page(info, keyinfo, key, anc_buff, anc_page,
- father_page, father_buff, father_key_pos,
+ page_mark_changed(info, father_page);
+ DBUG_RETURN(_ma_balance_page(info, keyinfo, key, anc_page,
+ father_page, father_key_pos,
&s_temp));
}
- DBUG_RETURN(_ma_split_page(info, key, anc_page,
- anc_buff, org_anc_length,
+ DBUG_RETURN(_ma_split_page(info, key, anc_page, org_anc_length,
key_pos, s_temp.changed_length, t_length,
key_buff, insert_last));
} /* _ma_insert */
@@ -832,9 +827,8 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
info Maria handler
keyinfo Key handler
key Buffer for middle key
- split_page Address on disk for split_buff
- split_buff Page buffer for page that should be split
- org_split_length Original length of split_buff before key was inserted
+ split_page Page that should be split
+ org_split_length Original length of split_page before key was inserted
inserted_key_pos Address in buffer where key was inserted
changed_length Number of bytes changed at 'inserted_key_pos'
move_length Number of bytes buffer was moved when key was inserted
@@ -849,8 +843,7 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
@retval -1 error
*/
-int _ma_split_page(MARIA_HA *info, MARIA_KEY *key, my_off_t split_page,
- uchar *split_buff,
+int _ma_split_page(MARIA_HA *info, MARIA_KEY *key, MARIA_PAGE *split_page,
uint org_split_length,
uchar *inserted_key_pos, uint changed_length,
int move_length,
@@ -858,57 +851,60 @@ int _ma_split_page(MARIA_HA *info, MARIA_KEY *key, my_off_t split_page,
{
uint length,a_length,key_ref_length,t_length,nod_flag,key_length;
uint page_length, split_length, page_flag;
- uchar *key_pos,*pos, *after_key, *new_buff;
- my_off_t new_pos;
+ uchar *key_pos,*pos, *after_key;
MARIA_KEY_PARAM s_temp;
MARIA_PINNED_PAGE tmp_page_link, *page_link= &tmp_page_link;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_KEY tmp_key;
+ MARIA_PAGE new_page;
int res;
DBUG_ENTER("_ma_split_page");
LINT_INIT(after_key);
- DBUG_DUMP("buff", split_buff, _ma_get_page_used(share, split_buff));
+ DBUG_DUMP("buff", split_page->buff, split_page->size);
info->page_changed=1; /* Info->buff is used */
info->keyread_buff_used=1;
- new_buff= info->buff;
- page_flag= _ma_get_keypage_flag(share, split_buff);
- nod_flag= _ma_test_if_nod(share, split_buff);
+ page_flag= split_page->flag;
+ nod_flag= split_page->node;
key_ref_length= share->keypage_header + nod_flag;
+ new_page.info= info;
+ new_page.buff= info->buff;
+ new_page.keyinfo= keyinfo;
+
tmp_key.data= key_buff;
tmp_key.keyinfo= keyinfo;
if (insert_last_key)
- key_pos= _ma_find_last_pos(info, &tmp_key, split_buff, &after_key);
+ key_pos= _ma_find_last_pos(&tmp_key, split_page, &after_key);
else
- key_pos= _ma_find_half_pos(info, &tmp_key, nod_flag, split_buff,
- &after_key);
+ key_pos= _ma_find_half_pos(&tmp_key, split_page, &after_key);
if (!key_pos)
DBUG_RETURN(-1);
key_length= tmp_key.data_length + tmp_key.ref_length;
- split_length= (uint) (key_pos - split_buff);
- a_length= _ma_get_page_used(share, split_buff);
- _ma_store_page_used(share, split_buff, split_length);
+ split_length= (uint) (key_pos - split_page->buff);
+ a_length= split_page->size;
+ split_page->size= split_length;
+ page_store_size(share, split_page);
key_pos=after_key;
if (nod_flag)
{
DBUG_PRINT("test",("Splitting nod"));
pos=key_pos-nod_flag;
- memcpy((uchar*) new_buff + share->keypage_header, (uchar*) pos,
+ memcpy((uchar*) new_page.buff + share->keypage_header, (uchar*) pos,
(size_t) nod_flag);
}
/* Move middle item to key and pointer to new page */
- if ((new_pos= _ma_new(info, PAGECACHE_PRIORITY_HIGH, &page_link)) ==
+ if ((new_page.pos= _ma_new(info, PAGECACHE_PRIORITY_HIGH, &page_link)) ==
HA_OFFSET_ERROR)
DBUG_RETURN(-1);
_ma_copy_key(key, &tmp_key);
- _ma_kpointer(info, key->data + key_length, new_pos);
+ _ma_kpointer(info, key->data + key_length, new_page.pos);
/* Store new page */
if (!(*keyinfo->get_key)(&tmp_key, page_flag, nod_flag, &key_pos))
@@ -916,36 +912,42 @@ int _ma_split_page(MARIA_HA *info, MARIA_KEY *key, my_off_t split_page,
t_length=(*keyinfo->pack_key)(&tmp_key, nod_flag, (uchar *) 0,
(uchar*) 0, (uchar*) 0, &s_temp);
- length=(uint) ((split_buff + a_length) - key_pos);
- memcpy((uchar*) new_buff+key_ref_length+t_length,(uchar*) key_pos,
+ length=(uint) ((split_page->buff + a_length) - key_pos);
+ memcpy((uchar*) new_page.buff+key_ref_length+t_length,(uchar*) key_pos,
(size_t) length);
- (*keyinfo->store_key)(keyinfo,new_buff+key_ref_length,&s_temp);
+ (*keyinfo->store_key)(keyinfo,new_page.buff+key_ref_length,&s_temp);
page_length= length + t_length + key_ref_length;
- bzero(new_buff, share->keypage_header);
+ bzero(new_page.buff, share->keypage_header);
/* Copy KEYFLAG_FLAG_ISNODE and KEYPAGE_FLAG_HAS_TRANSID from parent page */
- _ma_store_keypage_flag(share, new_buff, page_flag);
- _ma_store_page_used(share, new_buff, page_length);
+ new_page.flag= page_flag;
+ new_page.size= page_length;
+ page_store_info(share, &new_page);
+
/* Copy key number */
- new_buff[share->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
- KEYPAGE_FLAG_SIZE]=
- split_buff[share->keypage_header - KEYPAGE_USED_SIZE -
- KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE];
+ new_page.buff[share->keypage_header - KEYPAGE_USED_SIZE -
+ KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE]=
+ split_page->buff[share->keypage_header - KEYPAGE_USED_SIZE -
+ KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE];
res= 2; /* Middle key up */
- if (share->now_transactional &&
- _ma_log_new(info, new_pos, new_buff, page_length, keyinfo->key_nr, 0))
+ if (share->now_transactional && _ma_log_new(&new_page, 0))
res= -1;
- bzero(new_buff + page_length, share->block_size - page_length);
- if (_ma_write_keypage(info, keyinfo, new_pos, page_link->write_lock,
- DFLT_INIT_HITS, new_buff))
+ /*
+ Clear unitialized part of page to avoid valgrind/purify warnings
+ and to get a clean page that is easier to compress and compare with
+ pages generated with redo
+ */
+ bzero(new_page.buff + page_length, share->block_size - page_length);
+
+ if (_ma_write_keypage(&new_page, page_link->write_lock,
+ DFLT_INIT_HITS))
res= -1;
/* Save changes to split pages */
if (share->now_transactional &&
- _ma_log_split(info, split_page, split_buff, org_split_length,
- split_length,
+ _ma_log_split(split_page, org_split_length, split_length,
inserted_key_pos, changed_length, move_length,
KEY_OP_NONE, (uchar*) 0, 0, 0))
res= -1;
@@ -964,19 +966,22 @@ int _ma_split_page(MARIA_HA *info, MARIA_KEY *key, my_off_t split_page,
after_key will contain the position to where the next key starts
*/
-uchar *_ma_find_half_pos(MARIA_HA *info, MARIA_KEY *key, uint nod_flag,
- uchar *page, uchar **after_key)
+uchar *_ma_find_half_pos(MARIA_KEY *key, MARIA_PAGE *ma_page,
+ uchar **after_key)
{
- uint keys, length, key_ref_length, page_flag;
- uchar *end,*lastpos;
+ uint keys, length, key_ref_length, page_flag, nod_flag;
+ uchar *page, *end, *lastpos;
+ MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
DBUG_ENTER("_ma_find_half_pos");
+ nod_flag= ma_page->node;
key_ref_length= share->keypage_header + nod_flag;
- page_flag= _ma_get_keypage_flag(share, page);
- length= _ma_get_page_used(share, page) - key_ref_length;
- page+= key_ref_length; /* Point to first key */
+ page_flag= ma_page->flag;
+ length= ma_page->size - key_ref_length;
+ page= ma_page->buff+ key_ref_length; /* Point to first key */
+
if (!(keyinfo->flag &
(HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY |
HA_BINARY_PACK_KEY)) && !(page_flag & KEYPAGE_FLAG_HAS_TRANSID))
@@ -1023,21 +1028,23 @@ uchar *_ma_find_half_pos(MARIA_HA *info, MARIA_KEY *key, uint nod_flag,
@retval int_key will contain the last key
*/
-static uchar *_ma_find_last_pos(MARIA_HA *info, MARIA_KEY *int_key,
- uchar *page, uchar **after_key)
+static uchar *_ma_find_last_pos(MARIA_KEY *int_key, MARIA_PAGE *ma_page,
+ uchar **after_key)
{
uint keys, length, key_ref_length, page_flag;
- uchar *end, *lastpos, *prevpos;
+ uchar *page, *end, *lastpos, *prevpos;
uchar key_buff[MARIA_MAX_KEY_BUFF];
+ MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= int_key->keyinfo;
MARIA_KEY tmp_key;
DBUG_ENTER("_ma_find_last_pos");
key_ref_length= share->keypage_header;
- page_flag= _ma_get_keypage_flag(share, page);
- length= _ma_get_page_used(share, page) - key_ref_length;
- page+=key_ref_length;
+ page_flag= ma_page->flag;
+ length= ma_page->size - key_ref_length;
+ page= ma_page->buff + key_ref_length;
+
if (!(keyinfo->flag &
(HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY |
HA_BINARY_PACK_KEY)) && !(page_flag & KEYPAGE_FLAG_HAS_TRANSID))
@@ -1063,7 +1070,6 @@ static uchar *_ma_find_last_pos(MARIA_HA *info, MARIA_KEY *int_key,
if (!(length=(*keyinfo->get_key)(&tmp_key, page_flag, 0, &page)))
{
- maria_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
@@ -1077,7 +1083,6 @@ static uchar *_ma_find_last_pos(MARIA_HA *info, MARIA_KEY *int_key,
memcpy(int_key->data, key_buff, length); /* previous key */
if (!(length=(*keyinfo->get_key)(&tmp_key, page_flag, 0, &page)))
{
- maria_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
@@ -1105,62 +1110,61 @@ static uchar *_ma_find_last_pos(MARIA_HA *info, MARIA_KEY *int_key,
@retval -1 Error
*/
-static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- MARIA_KEY *key, uchar *curr_buff,
- my_off_t curr_page,
- my_off_t father_page, uchar *father_buff,
+static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ MARIA_KEY *key, MARIA_PAGE *curr_page,
+ MARIA_PAGE *father_page,
uchar *father_key_pos, MARIA_KEY_PARAM *s_temp)
{
- MARIA_PINNED_PAGE *next_page_link;
MARIA_PINNED_PAGE tmp_page_link, *new_page_link= &tmp_page_link;
MARIA_SHARE *share= info->s;
my_bool right;
uint k_length,father_length,father_keylength,nod_flag,curr_keylength;
uint right_length,left_length,new_right_length,new_left_length,extra_length;
uint keys, tmp_length, extra_buff_length;
- uchar *pos,*buff,*extra_buff, *parting_key;
- my_off_t next_page,new_pos;
+ uchar *pos, *extra_buff, *parting_key;
uchar tmp_part_key[MARIA_MAX_KEY_BUFF];
+ MARIA_PAGE next_page, extra_page, *left_page, *right_page;
DBUG_ENTER("_ma_balance_page");
- k_length=keyinfo->keylength;
- father_length= _ma_get_page_used(share, father_buff);
+ k_length= keyinfo->keylength;
+ father_length= father_page->size;
father_keylength= k_length + share->base.key_reflength;
- nod_flag= _ma_test_if_nod(share, curr_buff);
- curr_keylength=k_length+nod_flag;
+ nod_flag= curr_page->node;
+ curr_keylength= k_length+nod_flag;
info->page_changed=1;
- if ((father_key_pos != father_buff+father_length &&
+ if ((father_key_pos != father_page->buff+father_length &&
(info->state->records & 1)) ||
- father_key_pos == father_buff+ share->keypage_header +
+ father_key_pos == father_page->buff+ share->keypage_header +
share->base.key_reflength)
{
right=1;
- next_page= _ma_kpos(share->base.key_reflength,
- father_key_pos+father_keylength);
- buff=info->buff;
- DBUG_PRINT("info", ("use right page: %lu", (ulong) next_page));
+ next_page.pos= _ma_kpos(share->base.key_reflength,
+ father_key_pos+father_keylength);
+ left_page= curr_page;
+ right_page= &next_page;
+ DBUG_PRINT("info", ("use right page: %lu", (ulong) next_page.pos));
}
else
{
right=0;
father_key_pos-=father_keylength;
- next_page= _ma_kpos(share->base.key_reflength,father_key_pos);
- /* Move curr_buff so that it's on the left */
- buff= curr_buff;
- curr_buff= info->buff;
- DBUG_PRINT("info", ("use left page: %lu", (ulong) next_page));
+ next_page.pos= _ma_kpos(share->base.key_reflength,father_key_pos);
+ left_page= &next_page;
+ right_page= curr_page;
+ DBUG_PRINT("info", ("use left page: %lu", (ulong) next_page.pos));
} /* father_key_pos ptr to parting key */
- if (!_ma_fetch_keypage(info,keyinfo, next_page, PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, info->buff, 0, &next_page_link))
+ if (_ma_fetch_keypage(&next_page, info, keyinfo, next_page.pos,
+ PAGECACHE_LOCK_WRITE,
+ DFLT_INIT_HITS, info->buff, 0))
goto err;
- next_page_link->changed= 1;
- DBUG_DUMP("next", info->buff, _ma_get_page_used(share, info->buff));
+ page_mark_changed(info, &next_page);
+ DBUG_DUMP("next", next_page.buff, next_page.size);
/* Test if there is room to share keys */
- left_length= _ma_get_page_used(share, curr_buff);
- right_length= _ma_get_page_used(share, buff);
+ left_length= left_page->size;
+ right_length= right_page->size;
keys= ((left_length+right_length-share->keypage_header*2-nod_flag*2)/
curr_keylength);
@@ -1171,8 +1175,10 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
new_left_length= share->keypage_header+nod_flag+(keys/2)*curr_keylength;
new_right_length=share->keypage_header+nod_flag+(((keys+1)/2)*
curr_keylength);
- _ma_store_page_used(share, curr_buff, new_left_length);
- _ma_store_page_used(share, buff, new_right_length);
+ left_page->size= new_left_length;
+ page_store_size(share, left_page);
+ right_page->size= new_right_length;
+ page_store_size(share, right_page);
DBUG_PRINT("info", ("left_length: %u -> %u right_length: %u -> %u",
left_length, new_left_length,
@@ -1182,14 +1188,15 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
uint length;
DBUG_PRINT("info", ("move keys to end of buff"));
- /* Move keys buff -> curr_buff */
- pos=curr_buff+left_length;
+ /* Move keys right_page -> left_page */
+ pos= left_page->buff+left_length;
memcpy(pos,father_key_pos, (size_t) k_length);
- memcpy(pos+k_length, buff + share->keypage_header,
+ memcpy(pos+k_length, right_page->buff + share->keypage_header,
(size_t) (length=new_left_length - left_length - k_length));
- pos= buff + share->keypage_header + length;
+ pos= right_page->buff + share->keypage_header + length;
memcpy(father_key_pos, pos, (size_t) k_length);
- bmove(buff + share->keypage_header, pos + k_length, new_right_length);
+ bmove(right_page->buff + share->keypage_header,
+ pos + k_length, new_right_length);
if (share->now_transactional)
{
@@ -1197,17 +1204,17 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
{
/*
Log changes to page on left
- The original page is on the left and stored in curr_buff
+ The original page is on the left and stored in left_page->buff
We have on the page the newly inserted key and data
from buff added last on the page
*/
- if (_ma_log_split(info, curr_page, curr_buff,
+ if (_ma_log_split(curr_page,
left_length - s_temp->move_length,
new_left_length,
s_temp->key_pos, s_temp->changed_length,
s_temp->move_length,
KEY_OP_ADD_SUFFIX,
- curr_buff + left_length,
+ curr_page->buff + left_length,
new_left_length - left_length,
new_left_length - left_length+ k_length))
goto err;
@@ -1216,7 +1223,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
This contains the original data with some keys deleted from
start of page
*/
- if (_ma_log_prefix(info, next_page, buff, 0,
+ if (_ma_log_prefix(&next_page, 0,
((int) new_right_length - (int) right_length)))
goto err;
}
@@ -1227,7 +1234,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
Data is removed from start of page
The inserted key may be in buff or moved to curr_buff
*/
- if (_ma_log_del_prefix(info, curr_page, buff,
+ if (_ma_log_del_prefix(curr_page,
right_length - s_temp->changed_length,
new_right_length,
s_temp->key_pos, s_temp->changed_length,
@@ -1236,8 +1243,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/*
Log changes to page on left, which has new data added last
*/
- if (_ma_log_suffix(info, next_page, curr_buff,
- left_length, new_left_length))
+ if (_ma_log_suffix(&next_page, left_length, new_left_length))
goto err;
}
}
@@ -1245,16 +1251,18 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
else
{
uint length;
- DBUG_PRINT("info", ("move keys to start of buff"));
+ DBUG_PRINT("info", ("move keys to start of right_page"));
- bmove_upp(buff + new_right_length, buff + right_length,
+ bmove_upp(right_page->buff + new_right_length,
+ right_page->buff + right_length,
right_length - share->keypage_header);
length= new_right_length -right_length - k_length;
- memcpy(buff + share->keypage_header + length, father_key_pos,
+ memcpy(right_page->buff + share->keypage_header + length, father_key_pos,
(size_t) k_length);
- pos=curr_buff+new_left_length;
+ pos= left_page->buff + new_left_length;
memcpy(father_key_pos, pos, (size_t) k_length);
- memcpy(buff + share->keypage_header, pos+k_length, (size_t) length);
+ memcpy(right_page->buff + share->keypage_header, pos+k_length,
+ (size_t) length);
if (share->now_transactional)
{
@@ -1265,7 +1273,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
The original page is on the left and stored in curr_buff
The page is shortened from end and the key may be on the page
*/
- if (_ma_log_split(info, curr_page, curr_buff,
+ if (_ma_log_split(curr_page,
left_length - s_temp->move_length,
new_left_length,
s_temp->key_pos, s_temp->changed_length,
@@ -1277,7 +1285,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
This contains the original data, with some data from cur_buff
added first
*/
- if (_ma_log_prefix(info, next_page, buff,
+ if (_ma_log_prefix(&next_page,
(uint) (new_right_length - right_length),
(int) (new_right_length - right_length)))
goto err;
@@ -1290,21 +1298,20 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
from buff added first on the page
*/
uint diff_length= new_right_length - right_length;
- if (_ma_log_split(info, curr_page, buff,
+ if (_ma_log_split(curr_page,
left_length - s_temp->move_length,
new_right_length,
s_temp->key_pos + diff_length,
s_temp->changed_length,
s_temp->move_length,
KEY_OP_ADD_PREFIX,
- buff + share->keypage_header,
+ curr_page->buff + share->keypage_header,
diff_length, diff_length + k_length))
goto err;
/*
Log changes to page on left, which is shortened from end
*/
- if (_ma_log_suffix(info, next_page, curr_buff,
- left_length, new_left_length))
+ if (_ma_log_suffix(&next_page, left_length, new_left_length))
goto err;
}
}
@@ -1313,29 +1320,31 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/* Log changes to father (one level up) page */
if (share->now_transactional &&
- _ma_log_change(info, father_page, father_buff, father_key_pos,
- k_length))
+ _ma_log_change(father_page, father_key_pos, k_length))
goto err;
/*
next_page_link->changed is marked as true above and fathers
page_link->changed is marked as true in caller
*/
- if (_ma_write_keypage(info, keyinfo, next_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, info->buff) ||
- _ma_write_keypage(info, keyinfo, father_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS,
- father_buff))
+ if (_ma_write_keypage(&next_page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS) ||
+ _ma_write_keypage(father_page,
+ PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS))
goto err;
DBUG_RETURN(0);
}
- /* curr_buff[] and buff[] are full, lets split and make new nod */
+ /* left_page and right_page are full, lets split and make new nod */
extra_buff= info->buff+share->base.max_key_block_length;
new_left_length= new_right_length= (share->keypage_header + nod_flag +
(keys+1) / 3 * curr_keylength);
+ extra_page.info= info;
+ extra_page.keyinfo= keyinfo;
+ extra_page.buff= extra_buff;
+ extra_page.flag= 0;
+
/*
5 is the minum number of keys we can have here. This comes from
the fact that each full page can store at least 2 keys and in this case
@@ -1350,21 +1359,23 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
left_length, right_length,
new_left_length, new_right_length,
extra_length));
- _ma_store_page_used(share, curr_buff, new_left_length);
- _ma_store_page_used(share, buff, new_right_length);
+
+ left_page->size= new_left_length;
+ page_store_size(share, left_page);
+ right_page->size= new_right_length;
+ page_store_size(share, right_page);
bzero(extra_buff, share->keypage_header);
- if (nod_flag)
- _ma_store_keypage_flag(share, extra_buff, KEYPAGE_FLAG_ISNOD);
+ extra_page.flag= nod_flag ? KEYPAGE_FLAG_ISNOD : 0;
+ extra_page.size= extra_buff_length;
+
/* Copy key number */
extra_buff[share->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
- KEYPAGE_FLAG_SIZE]=
- buff[share->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
- KEYPAGE_FLAG_SIZE];
- _ma_store_page_used(share, extra_buff, extra_buff_length);
+ KEYPAGE_FLAG_SIZE]= keyinfo->key_nr;
+ page_store_info(share, &extra_page);
/* move first largest keys to new page */
- pos=buff+right_length-extra_length;
+ pos= right_page->buff + right_length-extra_length;
memcpy(extra_buff + share->keypage_header, pos, extra_length);
/* Zero old data from buffer */
bzero(extra_buff + extra_buff_length,
@@ -1373,43 +1384,52 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/* Save new parting key between buff and extra_buff */
memcpy(tmp_part_key, pos-k_length,k_length);
/* Make place for new keys */
- bmove_upp(buff+ new_right_length, pos - k_length,
+ bmove_upp(right_page->buff + new_right_length, pos - k_length,
right_length - extra_length - k_length - share->keypage_header);
/* Copy keys from left page */
- pos= curr_buff+new_left_length;
- memcpy(buff + share->keypage_header, pos + k_length,
+ pos= left_page->buff + new_left_length;
+ memcpy(right_page->buff + share->keypage_header, pos + k_length,
(size_t) (tmp_length= left_length - new_left_length - k_length));
/* Copy old parting key */
- parting_key= buff + share->keypage_header + tmp_length;
+ parting_key= right_page->buff + share->keypage_header + tmp_length;
memcpy(parting_key, father_key_pos, (size_t) k_length);
/* Move new parting keys up to caller */
memcpy((right ? key->data : father_key_pos),pos,(size_t) k_length);
memcpy((right ? father_key_pos : key->data),tmp_part_key, k_length);
- if ((new_pos= _ma_new(info, DFLT_INIT_HITS, &new_page_link))
+ if ((extra_page.pos= _ma_new(info, DFLT_INIT_HITS, &new_page_link))
== HA_OFFSET_ERROR)
goto err;
- _ma_kpointer(info,key->data+k_length,new_pos);
+ _ma_kpointer(info,key->data+k_length, extra_page.pos);
/* This is safe as long we are using not keys with transid */
key->data_length= k_length - info->s->rec_reflength;
key->ref_length= info->s->rec_reflength;
+ if (right)
+ {
+ /*
+ Page order according to key values:
+ orignal_page (curr_page = left_page), next_page (buff), extra_buff
+
+ Move page positions so that we store data in extra_page where
+ next_page was and next_page will be stored at the new position
+ */
+ swap_variables(my_off_t, extra_page.pos, next_page.pos);
+ }
+
if (share->now_transactional)
{
if (right)
{
/*
- Page order according to key values:
- orignal_page (curr_buff), next_page (buff), extra_buff
+ left_page is shortened,
+ right_page is getting new keys at start and shortened from end.
+ extra_page is new page
- cur_buff is shortened,
- buff is getting new keys at start and shortened from end.
- extra_buff is new page
-
- Note that extra_buff (largest key parts) will be stored at the
- place of the original 'right' page (next_page) and right page (buff)
- will be stored at new_pos.
+ Note that extra_page (largest key parts) will be stored at the
+ place of the original 'right' page (next_page) and right page
+ will be stored at the new page position
This makes the log entries smaller as right_page contains all
data to generate the data extra_buff
@@ -1418,7 +1438,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/*
Log changes to page on left (page shortened page at end)
*/
- if (_ma_log_split(info, curr_page, curr_buff,
+ if (_ma_log_split(curr_page,
left_length - s_temp->move_length, new_left_length,
s_temp->key_pos, s_temp->changed_length,
s_temp->move_length,
@@ -1428,7 +1448,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
Log changes to right page (stored at next page)
This contains the last 'extra_buff' from 'buff'
*/
- if (_ma_log_prefix(info, next_page, extra_buff,
+ if (_ma_log_prefix(&extra_page,
0, (int) (extra_buff_length - right_length)))
goto err;
@@ -1436,8 +1456,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
Log changes to middle page, which is stored at the new page
position
*/
- if (_ma_log_new(info, new_pos, buff, new_right_length,
- keyinfo->key_nr, 0))
+ if (_ma_log_new(&next_page, 0))
goto err;
}
else
@@ -1448,7 +1467,7 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
added first and shortened at end
*/
int data_added_first= left_length - new_left_length;
- if (_ma_log_key_middle(info, curr_page, buff,
+ if (_ma_log_key_middle(right_page,
new_right_length,
data_added_first,
data_added_first,
@@ -1459,31 +1478,28 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
goto err;
/* Log changes to page on left, which is shortened from end */
- if (_ma_log_suffix(info, next_page, curr_buff,
- left_length, new_left_length))
+ if (_ma_log_suffix(left_page, left_length, new_left_length))
goto err;
/* Log change to rightmost (new) page */
- if (_ma_log_new(info, new_pos, extra_buff,
- extra_buff_length, keyinfo->key_nr, 0))
+ if (_ma_log_new(&extra_page, 0))
goto err;
}
/* Log changes to father (one level up) page */
if (share->now_transactional &&
- _ma_log_change(info, father_page, father_buff, father_key_pos,
- k_length))
+ _ma_log_change(father_page, father_key_pos, k_length))
goto err;
}
- if (_ma_write_keypage(info, keyinfo, (right ? new_pos : next_page),
+ if (_ma_write_keypage(&next_page,
(right ? new_page_link->write_lock :
PAGECACHE_LOCK_LEFT_WRITELOCKED),
- DFLT_INIT_HITS, info->buff) ||
- _ma_write_keypage(info, keyinfo, (right ? next_page : new_pos),
+ DFLT_INIT_HITS) ||
+ _ma_write_keypage(&extra_page,
(!right ? new_page_link->write_lock :
PAGECACHE_LOCK_LEFT_WRITELOCKED),
- DFLT_INIT_HITS, extra_buff))
+ DFLT_INIT_HITS))
goto err;
DBUG_RETURN(1); /* Middle key up */
@@ -1739,21 +1755,23 @@ int _ma_write_undo_key_insert(MARIA_HA *info, const MARIA_KEY *key,
@retval 0 ok
*/
-my_bool _ma_log_new(MARIA_HA *info, my_off_t page, const uchar *buff,
- uint page_length, uint key_nr, my_bool root_page)
+my_bool _ma_log_new(MARIA_PAGE *ma_page, my_bool root_page)
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE * 2 + KEY_NR_STORE_SIZE
+1];
+ uint page_length;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
+ MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
+ my_off_t page;
DBUG_ENTER("_ma_log_new");
- DBUG_PRINT("enter", ("page: %lu", (ulong) page));
+ DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos));
DBUG_ASSERT(share->now_transactional);
/* Store address of new root page */
- page/= share->block_size;
+ page= ma_page->pos / share->block_size;
page_store(log_data + FILEID_STORE_SIZE, page);
/* Store link to next unused page */
@@ -1764,20 +1782,22 @@ my_bool _ma_log_new(MARIA_HA *info, my_off_t page, const uchar *buff,
share->key_del_current / share->block_size);
page_store(log_data + FILEID_STORE_SIZE + PAGE_STORE_SIZE, page);
- key_nr_store(log_data + FILEID_STORE_SIZE + PAGE_STORE_SIZE*2, key_nr);
+ key_nr_store(log_data + FILEID_STORE_SIZE + PAGE_STORE_SIZE*2,
+ ma_page->keyinfo->key_nr);
log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE*2 + KEY_NR_STORE_SIZE]=
(uchar) root_page;
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
- page_length-= LSN_STORE_SIZE;
- log_array[TRANSLOG_INTERNAL_PARTS + 1].str= buff + LSN_STORE_SIZE;
+ page_length= ma_page->size - LSN_STORE_SIZE;
+ log_array[TRANSLOG_INTERNAL_PARTS + 1].str= ma_page->buff + LSN_STORE_SIZE;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= page_length;
if (translog_write_record(&lsn, LOGREC_REDO_INDEX_NEW_PAGE,
info->trn, info,
- (translog_size_t) (sizeof(log_data) + page_length),
+ (translog_size_t)
+ (sizeof(log_data) + page_length),
TRANSLOG_INTERNAL_PARTS + 2, log_array,
log_data, NULL))
DBUG_RETURN(1);
@@ -1790,20 +1810,23 @@ my_bool _ma_log_new(MARIA_HA *info, my_off_t page, const uchar *buff,
Log when some part of the key page changes
*/
-my_bool _ma_log_change(MARIA_HA *info, my_off_t page, const uchar *buff,
+my_bool _ma_log_change(MARIA_PAGE *ma_page,
const uchar *key_pos, uint length)
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 6 + 7], *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
- uint offset= (uint) (key_pos - buff), translog_parts, extra_length= 0;
+ uint offset= (uint) (key_pos - ma_page->buff), translog_parts;
+ uint extra_length= 0;
+ my_off_t page;
+ MARIA_HA *info= ma_page->info;
DBUG_ENTER("_ma_log_change");
- DBUG_PRINT("enter", ("page: %lu length: %u", (ulong) page, length));
+ DBUG_PRINT("enter", ("page: %lu length: %u", (ulong) ma_page->pos, length));
DBUG_ASSERT(info->s->now_transactional);
/* Store address of new root page */
- page/= info->s->block_size;
+ page= ma_page->pos / info->s->block_size;
page_store(log_data + FILEID_STORE_SIZE, page);
log_pos= log_data+ FILEID_STORE_SIZE + PAGE_STORE_SIZE;
log_pos[0]= KEY_OP_OFFSET;
@@ -1819,9 +1842,10 @@ my_bool _ma_log_change(MARIA_HA *info, my_off_t page, const uchar *buff,
#ifdef EXTRA_DEBUG_KEY_CHANGES
{
- int page_length= _ma_get_page_used(info->s, buff);
+ int page_length= ma_page->size;
ha_checksum crc;
- crc= my_checksum(0, buff + LSN_STORE_SIZE, page_length - LSN_STORE_SIZE);
+ crc= my_checksum(0, ma_page->buff + LSN_STORE_SIZE,
+ page_length - LSN_STORE_SIZE);
log_pos+= 6;
log_pos[0]= KEY_OP_CHECK;
int2store(log_pos+1, page_length);
@@ -1860,7 +1884,7 @@ my_bool _ma_log_change(MARIA_HA *info, my_off_t page, const uchar *buff,
*/
-static my_bool _ma_log_split(MARIA_HA *info, my_off_t page, const uchar *buff,
+static my_bool _ma_log_split(MARIA_PAGE *ma_page,
uint org_length, uint new_length,
const uchar *key_pos, uint key_length,
int move_length, enum en_key_op prefix_or_suffix,
@@ -1871,14 +1895,16 @@ static my_bool _ma_log_split(MARIA_HA *info, my_off_t page, const uchar *buff,
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3+3+3+3+3+2];
uchar *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
- uint offset= (uint) (key_pos - buff);
+ uint offset= (uint) (key_pos - ma_page->buff);
uint translog_parts, extra_length;
+ MARIA_HA *info= ma_page->info;
+ my_off_t page;
DBUG_ENTER("_ma_log_split");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
- (ulong) page, org_length, new_length));
+ (ulong) ma_page->pos, org_length, new_length));
log_pos= log_data + FILEID_STORE_SIZE;
- page/= info->s->block_size;
+ page= ma_page->pos / info->s->block_size;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
@@ -1995,8 +2021,7 @@ static my_bool _ma_log_split(MARIA_HA *info, my_off_t page, const uchar *buff,
@retval 1 error
*/
-static my_bool _ma_log_del_prefix(MARIA_HA *info, my_off_t page,
- const uchar *buff,
+static my_bool _ma_log_del_prefix(MARIA_PAGE *ma_page,
uint org_length, uint new_length,
const uchar *key_pos, uint key_length,
int move_length)
@@ -2004,17 +2029,19 @@ static my_bool _ma_log_del_prefix(MARIA_HA *info, my_off_t page,
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 12], *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
- uint offset= (uint) (key_pos - buff);
+ uint offset= (uint) (key_pos - ma_page->buff);
uint diff_length= org_length + move_length - new_length;
uint translog_parts, extra_length;
+ MARIA_HA *info= ma_page->info;
+ my_off_t page;
DBUG_ENTER("_ma_log_del_prefix");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
- (ulong) page, org_length, new_length));
+ (ulong) ma_page->pos, org_length, new_length));
DBUG_ASSERT((int) diff_length > 0);
log_pos= log_data + FILEID_STORE_SIZE;
- page/= info->s->block_size;
+ page= ma_page->pos / info->s->block_size;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
@@ -2084,8 +2111,7 @@ static my_bool _ma_log_del_prefix(MARIA_HA *info, my_off_t page,
data deleted last. Old changed key may be part of page
*/
-static my_bool _ma_log_key_middle(MARIA_HA *info, my_off_t page,
- const uchar *buff,
+static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
uint new_length,
uint data_added_first,
uint data_changed_first,
@@ -2099,12 +2125,14 @@ static my_bool _ma_log_key_middle(MARIA_HA *info, my_off_t page,
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
uint key_offset;
uint translog_parts, extra_length;
+ my_off_t page;
+ MARIA_HA *info= ma_page->info;
DBUG_ENTER("_ma_log_key_middle");
- DBUG_PRINT("enter", ("page: %lu", (ulong) page));
+ DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos));
/* new place of key after changes */
key_pos+= data_added_first;
- key_offset= (uint) (key_pos - buff);
+ key_offset= (uint) (key_pos - ma_page->buff);
if (key_offset < new_length)
{
/* key is on page; Calculate how much of the key is there */
@@ -2122,7 +2150,7 @@ static my_bool _ma_log_key_middle(MARIA_HA *info, my_off_t page,
data_deleted_last+= move_length;
}
- page/= info->s->block_size;
+ page= ma_page->pos / info->s->block_size;
/* First log changes to page */
log_pos= log_data + FILEID_STORE_SIZE;
@@ -2141,7 +2169,7 @@ static my_bool _ma_log_key_middle(MARIA_HA *info, my_off_t page,
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos -
log_data);
- log_array[TRANSLOG_INTERNAL_PARTS + 1].str= (buff +
+ log_array[TRANSLOG_INTERNAL_PARTS + 1].str= (ma_page->buff +
info->s->keypage_header);
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= data_changed_first;
translog_parts= 2;
@@ -2195,18 +2223,19 @@ static my_bool _ma_log_key_middle(MARIA_HA *info, my_off_t page,
data deleted last
*/
-static my_bool _ma_log_middle(MARIA_HA *info, my_off_t page,
- const uchar *buff,
+static my_bool _ma_log_middle(MARIA_PAGE *ma_page,
uint data_added_first, uint data_changed_first,
uint data_deleted_last)
{
LSN lsn;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 5], *log_pos;
+ MARIA_HA *info= ma_page->info;
+ my_off_t page;
DBUG_ENTER("_ma_log_middle");
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
- page/= info->s->block_size;
+ page= ma_page->page / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);