summaryrefslogtreecommitdiff
path: root/storage/maria/ma_write.c
diff options
context:
space:
mode:
authorMichael Widenius <monty@mysql.com>2008-09-01 20:31:40 +0300
committerMichael Widenius <monty@mysql.com>2008-09-01 20:31:40 +0300
commitd6bdf03375977d89bf66c64b5ce72b67ec35c36d (patch)
tree274ac5a763b422cba57c20a8bfd15e256183ab7c /storage/maria/ma_write.c
parentdd406c1e7ebeede6506c3f8c1bc62c671ea880a1 (diff)
downloadmariadb-git-d6bdf03375977d89bf66c64b5ce72b67ec35c36d.tar.gz
Added MARIA_PAGE structure to keep all information about a maria key page.
This allowed me to remove a lot of parameters to functions, local variables, duplicate code and identical constructs. It should also make the code easier to read. Changed all marking of page as changed to use offset instead of pointers; This removed one theoretical problem where dynamic_array may have been moved between two calls. In addition I changed some functions from return my_bool include/maria.h: Changes to use MARIA_PAGE storage/maria/ma_check.c: Changes to use MARIA_PAGE Folded lines longer > 79 characters storage/maria/ma_delete.c: Changes to use MARIA_PAGE Changed _ma_ck_delete(), ma_log_delete(), ma_write_undo_key_delete() and _ma_ck_real_delete() to return type my_bool Removed some calls to maria_print_error() as the caller (maria_delete() and maria_write()) also prints the error storage/maria/ma_ft_update.c: Fix needed as _ma_ck_delete() now returns my_bool New parameter for ma_write_keypage. storage/maria/ma_key_recover.c: Changes to use MARIA_PAGE storage/maria/ma_key_recover.h: Updated function prototypes storage/maria/ma_page.c: Changes to use MARIA_PAGE Added _ma_page_setup() for old functions that doesn't (yet) use MARIA_PAGE natively storage/maria/ma_range.c: Changes to use MARIA_PAGE storage/maria/ma_rt_index.c: Changes to use MARIA_PAGE Changed maria_rtree_delete() and maria_rtree_real_delete() to return type my_bool Removed one 'if (node_flag) as this was always true Changed lable 'err1' to 'err' as there was no other error lables Moved allocation of page_buff outside of loop for fewer alloc/free calls Changed n_pages and m_pages to uint as 65000 pages is more than enough storage/maria/ma_rt_index.h: Updated function prototypes storage/maria/ma_rt_key.c: Changes to use MARIA_PAGE storage/maria/ma_rt_key.h: Updated function prototypes storage/maria/ma_rt_mbr.c: Changes to use MARIA_PAGE storage/maria/ma_rt_mbr.h: Updated function prototypes storage/maria/ma_rt_split.c: Changes to use MARIA_PAGE storage/maria/ma_search.c: Changes to use MARIA_PAGE storage/maria/ma_write.c: Changes to use MARIA_PAGE Changed _ma_ck_write_btree_with_log(), _ma_ck_real_write_btree(), ma_enlarge_root() to use return type my_bool Don't set *root to HA_OFFSET_ERROR in case of error Removed maria_print_error() calls as caller will do this Simplified logic in balance_page by introducing pointers to left and right pages storage/maria/maria_chk.c: Changes to use MARIA_PAGE storage/maria/maria_def.h: Changes to use MARIA_PAGE Removed some not used macros Added macros for MARIA_PAGE handling
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);