summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/maria.h5
-rw-r--r--storage/maria/ma_check.c271
-rw-r--r--storage/maria/ma_delete.c550
-rw-r--r--storage/maria/ma_ft_update.c14
-rw-r--r--storage/maria/ma_key_recover.c78
-rw-r--r--storage/maria/ma_key_recover.h25
-rw-r--r--storage/maria/ma_page.c161
-rw-r--r--storage/maria/ma_range.c57
-rw-r--r--storage/maria/ma_rt_index.c482
-rw-r--r--storage/maria/ma_rt_index.h23
-rw-r--r--storage/maria/ma_rt_key.c55
-rw-r--r--storage/maria/ma_rt_key.h7
-rw-r--r--storage/maria/ma_rt_mbr.c11
-rw-r--r--storage/maria/ma_rt_mbr.h5
-rw-r--r--storage/maria/ma_rt_split.c82
-rw-r--r--storage/maria/ma_search.c233
-rw-r--r--storage/maria/ma_write.c611
-rw-r--r--storage/maria/maria_chk.c51
-rw-r--r--storage/maria/maria_def.h107
19 files changed, 1483 insertions, 1345 deletions
diff --git a/include/maria.h b/include/maria.h
index 92f363e673e..0f70e9ce28d 100644
--- a/include/maria.h
+++ b/include/maria.h
@@ -161,6 +161,7 @@ struct st_maria_handler; /* For referense */
typedef struct st_maria_handler MARIA_HA;
struct st_maria_s_param;
struct st_maria_keydef;
+struct st_maria_page;
typedef struct st_maria_key /* Internal info about a key */
{
@@ -194,7 +195,7 @@ typedef struct st_maria_keydef /* Key definition with open & info */
HA_KEYSEG *seg, *end;
struct st_mysql_ftparser *parser; /* Fulltext [pre]parser */
- int (*bin_search)(const MARIA_KEY *key, uchar *page,
+ int (*bin_search)(const MARIA_KEY *key, const struct st_maria_page *page,
uint32 comp_flag, uchar **ret_pos, uchar *buff,
my_bool *was_last_key);
uint (*get_key)(MARIA_KEY *key, uint page_flag, uint nod_flag,
@@ -207,7 +208,7 @@ typedef struct st_maria_keydef /* Key definition with open & info */
void (*store_key)(struct st_maria_keydef *keyinfo, uchar *key_pos,
struct st_maria_s_param *s_temp);
my_bool (*ck_insert)(MARIA_HA *inf, MARIA_KEY *key);
- int (*ck_delete)(MARIA_HA *inf, MARIA_KEY *klen);
+ my_bool (*ck_delete)(MARIA_HA *inf, MARIA_KEY *klen);
MARIA_KEY *(*make_key)(MARIA_HA *info, MARIA_KEY *int_key, uint keynr,
uchar *key, const uchar *record,
MARIA_RECORD_POS filepos, ulonglong trid);
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index c64c879992c..8db8cdd8cb7 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -58,8 +58,8 @@
/* Functions defined in this file */
static int check_k_link(HA_CHECK *param, MARIA_HA *info, my_off_t next_link);
-static int chk_index(HA_CHECK *param, MARIA_HA *info,MARIA_KEYDEF *keyinfo,
- my_off_t page, uchar *buff, ha_rows *keys,
+static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ MARIA_PAGE *page, ha_rows *keys,
ha_checksum *key_checksum, uint level);
static uint isam_key_length(MARIA_HA *info,MARIA_KEYDEF *keyinfo);
static ha_checksum calc_checksum(ha_rows count);
@@ -468,6 +468,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo;
char buff[22],buff2[22];
+ MARIA_PAGE page;
DBUG_ENTER("maria_chk_key");
if (!(param->testflag & T_SILENT))
@@ -522,9 +523,9 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
_ma_check_print_error(param, "Key tree %u is empty", key + 1);
goto do_stat;
}
- if (!_ma_fetch_keypage(info, keyinfo, share->state.key_root[key],
- PAGECACHE_LOCK_LEFT_UNLOCKED, DFLT_INIT_HITS,
- info->buff, 0, 0))
+ if (_ma_fetch_keypage(&page, info, keyinfo, share->state.key_root[key],
+ PAGECACHE_LOCK_LEFT_UNLOCKED, DFLT_INIT_HITS,
+ info->buff, 0))
{
report_keypage_fault(param, info, share->state.key_root[key]);
if (!(param->testflag & T_INFO))
@@ -537,8 +538,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
param->keydata=param->totaldata=0;
param->key_blocks=0;
param->max_level=0;
- if (chk_index(param,info,keyinfo,share->state.key_root[key],info->buff,
- &keys, param->key_crc+key,1))
+ if (chk_index(param, info,keyinfo, &page, &keys, param->key_crc+key,1))
DBUG_RETURN(-1);
if (!(keyinfo->flag & (HA_FULLTEXT | HA_SPATIAL | HA_RTREE_INDEX)))
{
@@ -659,6 +659,7 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info,
{
char llbuff[22],llbuff2[22];
MARIA_SHARE *share= info->s;
+ MARIA_PAGE ma_page;
DBUG_ENTER("chk_index_down");
/* Key blocks must lay within the key file length entirely. */
@@ -692,14 +693,15 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info,
/* purecov: end */
}
- if (!_ma_fetch_keypage(info, keyinfo, page, PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, buff, 0, 0))
+ if (_ma_fetch_keypage(&ma_page, info, keyinfo, page,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, buff, 0))
{
report_keypage_fault(param, info, page);
goto err;
}
param->key_file_blocks+=keyinfo->block_length;
- if (chk_index(param,info,keyinfo,page,buff,keys,key_checksum,level))
+ if (chk_index(param, info, keyinfo, &ma_page, keys, key_checksum,level))
goto err;
DBUG_RETURN(0);
@@ -804,11 +806,11 @@ int maria_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull,
/* Check if index is ok */
static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t page, uchar *buff, ha_rows *keys,
+ MARIA_PAGE *anc_page, ha_rows *keys,
ha_checksum *key_checksum, uint level)
{
int flag;
- uint used_length,comp_flag,page_flag,nod_flag;
+ uint comp_flag, page_flag, nod_flag;
uchar *temp_buff, *keypos, *old_keypos, *endpos;
my_off_t next_page,record;
MARIA_SHARE *share= info->s;
@@ -817,7 +819,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
uchar tmp_key_buff[MARIA_MAX_KEY_BUFF];
MARIA_KEY tmp_key;
DBUG_ENTER("chk_index");
- DBUG_DUMP("buff", buff, _ma_get_page_used(share, buff));
+ DBUG_DUMP("buff", anc_page->buff, anc_page->size);
/* TODO: implement appropriate check for RTree keys */
if (keyinfo->flag & (HA_SPATIAL | HA_RTREE_INDEX))
@@ -837,22 +839,22 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
else
comp_flag=SEARCH_SAME; /* Keys in positionorder */
- page_flag= _ma_get_keypage_flag(share, buff);
- _ma_get_used_and_nod_with_flag(share, page_flag, buff, used_length,
- nod_flag);
- old_keypos= buff + share->keypage_header;
- keypos= old_keypos+ nod_flag;
- endpos= buff + used_length;
+ page_flag= anc_page->flag;
+ nod_flag= anc_page->node;
+ old_keypos= anc_page->buff + share->keypage_header;
+ keypos= old_keypos + nod_flag;
+ endpos= anc_page->buff + anc_page->size;
- param->keydata+= used_length;
+ param->keydata+= anc_page->size;
param->totaldata+= keyinfo->block_length; /* INFO */
param->key_blocks++;
if (level > param->max_level)
param->max_level=level;
- if (_ma_get_keynr(share, buff) != (uint) (keyinfo - share->keyinfo))
+ if (_ma_get_keynr(share, anc_page->buff) !=
+ (uint) (keyinfo - share->keyinfo))
_ma_check_print_error(param, "Page at %s is not marked for index %u",
- llstr(page, llbuff),
+ llstr(anc_page->pos, llbuff),
(uint) (keyinfo - share->keyinfo));
if ((page_flag & KEYPAGE_FLAG_HAS_TRANSID) &&
!share->base.born_transactional)
@@ -860,13 +862,14 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_check_print_error(param,
"Page at %s is marked with HAS_TRANSID even if "
"table is not transactional",
- llstr(page, llbuff));
+ llstr(anc_page->pos, llbuff));
}
- if (used_length > (uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
+ if (anc_page->size > (uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
{
- _ma_check_print_error(param,"Page at %s has impossible (too big) pagelength",
- llstr(page,llbuff));
+ _ma_check_print_error(param,
+ "Page at %s has impossible (too big) pagelength",
+ llstr(anc_page->pos, llbuff));
goto err;
}
@@ -895,7 +898,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_check_print_error(param,
"Page length and length of keys don't match at "
"page: %s",
- llstr(page,llbuff));
+ llstr(anc_page->pos,llbuff));
goto err;
}
if (share->data_file_type == BLOCK_RECORD &&
@@ -906,7 +909,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_check_print_error(param,
"Found key marked for transid on page that is not "
"marked for transid at: %s",
- llstr(page,llbuff));
+ llstr(anc_page->pos,llbuff));
goto err;
}
@@ -922,10 +925,10 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if ((comp_flag & SEARCH_FIND) && flag == 0)
_ma_check_print_error(param,"Found duplicated key at page %s",
- llstr(page,llbuff));
+ llstr(anc_page->pos,llbuff));
else
_ma_check_print_error(param,"Key in wrong position at page %s",
- llstr(page,llbuff));
+ llstr(anc_page->pos,llbuff));
goto err;
}
@@ -976,7 +979,8 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
"Number of words in the 2nd level tree "
"does not match the number in the header. "
"Parent word in on the page %s, offset %u",
- llstr(page,llbuff), (uint) (old_keypos-buff));
+ llstr(anc_page->pos,llbuff),
+ (uint) (old_keypos - anc_page->buff));
goto err;
}
(*keys)+=tmp_keys-1;
@@ -993,9 +997,12 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
#ifndef DBUG_OFF
char llbuff2[22], llbuff3[22];
#endif
- _ma_check_print_error(param,"Found key at page %s that points to record outside datafile",llstr(page,llbuff));
+ _ma_check_print_error(param,
+ "Found key at page %s that points to record "
+ "outside datafile",
+ llstr(anc_page->pos,llbuff));
DBUG_PRINT("test",("page: %s record: %s filelength: %s",
- llstr(page,llbuff),llstr(record,llbuff2),
+ llstr(anc_page->pos,llbuff),llstr(record,llbuff2),
llstr(share->state.state.data_file_length,llbuff3)));
DBUG_DUMP_KEY("key", &tmp_key);
DBUG_DUMP("new_in_page", old_keypos, (uint) (keypos-old_keypos));
@@ -1008,8 +1015,8 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_check_print_error(param,
"Keyblock size at page %s is not correct. "
"Block length: %u key length: %u",
- llstr(page, llbuff), used_length,
- (uint) (keypos - buff));
+ llstr(anc_page->pos, llbuff), anc_page->size,
+ (uint) (keypos - anc_page->buff));
goto err;
}
my_afree((uchar*) temp_buff);
@@ -1180,7 +1187,8 @@ static int check_static_record(HA_CHECK *param, MARIA_HA *info, int extend,
share->base.pack_reclength))
{
_ma_check_print_error(param,
- "got error: %d when reading datafile at position: %s",
+ "got error: %d when reading datafile at position: "
+ "%s",
my_errno, llstr(pos, llbuff));
return 1;
}
@@ -1269,7 +1277,8 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend,
if (block_info.block_len < share->base.min_block_length)
{
_ma_check_print_error(param,
- "Deleted block with impossible length %lu at %s",
+ "Deleted block with impossible length %lu "
+ "at %s",
block_info.block_len,llstr(pos,llbuff));
DBUG_RETURN(1);
}
@@ -1278,7 +1287,8 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend,
(block_info.prev_filepos != HA_OFFSET_ERROR &&
block_info.prev_filepos >= share->state.state.data_file_length))
{
- _ma_check_print_error(param,"Delete link points outside datafile at %s",
+ _ma_check_print_error(param,"Delete link points outside datafile "
+ "at %s",
llstr(pos,llbuff));
DBUG_RETURN(1);
}
@@ -1347,7 +1357,9 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend,
flag == 1 ? READING_NEXT : 0))
{
_ma_check_print_error(param,
- "got error: %d when reading datafile at position: %s", my_errno, llstr(block_info.filepos, llbuff));
+ "got error: %d when reading datafile at "
+ "position: %s", my_errno,
+ llstr(block_info.filepos, llbuff));
DBUG_RETURN(1);
}
@@ -1371,7 +1383,8 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend,
if (share->state.state.data_file_length < block_info.next_filepos)
{
_ma_check_print_error(param,
- "Found next-recordlink that points outside datafile at %s",
+ "Found next-recordlink that points outside "
+ "datafile at %s",
llstr(block_info.filepos,llbuff));
got_error=1;
break;
@@ -1446,7 +1459,8 @@ static int check_compressed_record(HA_CHECK *param, MARIA_HA *info, int extend,
share->pack.ref_length, READING_NEXT))
{
_ma_check_print_error(param,
- "got error: %d when reading datafile at position: %s",
+ "got error: %d when reading datafile at position: "
+ "%s",
my_errno, llstr(pos, llbuff));
DBUG_RETURN(1);
}
@@ -1470,7 +1484,8 @@ static int check_compressed_record(HA_CHECK *param, MARIA_HA *info, int extend,
block_info.filepos, block_info.rec_len, READING_NEXT))
{
_ma_check_print_error(param,
- "got error: %d when reading datafile at position: %s",
+ "got error: %d when reading datafile at position: "
+ "%s",
my_errno, llstr(block_info.filepos, llbuff));
DBUG_RETURN(1);
}
@@ -1615,7 +1630,8 @@ static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
if (empty != head_empty)
{
_ma_check_print_error(param,
- "Page %9s: Wrong empty size. Stored: %5u Actual: %5u",
+ "Page %9s: Wrong empty size. Stored: %5u "
+ "Actual: %5u",
llstr(page_pos, llbuff), head_empty, empty);
param->err_count++;
}
@@ -1738,7 +1754,9 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, uchar *record,
&bitmap_pattern))
{
_ma_check_print_error(param,
- "Page %9s: Row: %3d has an extent with wrong information in bitmap: Page %9s Page_type: %d Bitmap: %d",
+ "Page %9s: Row: %3d has an extent with "
+ "wrong information in bitmap: "
+ "Page %9s Page_type: %d Bitmap: %d",
llstr(page, llbuff), row,
llstr(extent_page, llbuff2),
page_type, bitmap_pattern);
@@ -1908,7 +1926,8 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
llstr(page, llbuff));
else
_ma_check_print_error(param,
- "Page %9s: Wrong data in bitmap. Page_type: %d empty_space: %u Bitmap-bits: %d",
+ "Page %9s: Wrong data in bitmap. Page_type: "
+ "%d empty_space: %u Bitmap-bits: %d",
llstr(page, llbuff), page_type,
empty_space, bitmap_pattern);
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
@@ -1958,11 +1977,13 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
_ma_scan_end_block_record(info);
if (full_page_count != param->full_page_count)
- _ma_check_print_error(param, "Full page count read through records was %s but we found %s pages while scanning table",
+ _ma_check_print_error(param, "Full page count read through records was %s "
+ "but we found %s pages while scanning table",
llstr(param->full_page_count, llbuff),
llstr(full_page_count, llbuff2));
if (tail_count != param->tail_count)
- _ma_check_print_error(param, "Tail count read through records was %s but we found %s tails while scanning table",
+ _ma_check_print_error(param, "Tail count read through records was %s but "
+ "we found %s tails while scanning table",
llstr(param->tail_count, llbuff),
llstr(tail_count, llbuff2));
@@ -2051,7 +2072,8 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
(HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
{
_ma_check_print_warning(param,
- "Record checksum is not the same as checksum stored in the index file");
+ "Record checksum is not the same as checksum "
+ "stored in the index file");
error=1;
}
else if (!extend)
@@ -2063,7 +2085,8 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
!(share->keyinfo[key].flag &
(HA_FULLTEXT | HA_SPATIAL | HA_RTREE_INDEX)))
{
- _ma_check_print_error(param,"Checksum for key: %2d doesn't match checksum for records",
+ _ma_check_print_error(param,"Checksum for key: %2d doesn't match "
+ "checksum for records",
key+1);
error=1;
}
@@ -2084,7 +2107,8 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
share->state.state.data_file_length)
{
_ma_check_print_warning(param,
- "Found %s record data and %s unused data and %s deleted data",
+ "Found %s record data and %s unused data and %s "
+ "deleted data",
llstr(param->used, llbuff),
llstr(param->empty,llbuff2),
llstr(param->del_length,llbuff3));
@@ -2092,7 +2116,8 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
"Total %s Should be: %s",
llstr((param->used+param->empty +
param->del_length), llbuff),
- llstr(share->state.state.data_file_length,llbuff2));
+ llstr(share->state.state.data_file_length,
+ llbuff2));
}
if (param->del_blocks != share->state.state.del)
{
@@ -2104,7 +2129,8 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
if (param->splits != share->state.split)
{
_ma_check_print_warning(param,
- "Found %10s parts Should be: %s parts",
+ "Found %10s parts Should be: "
+ "%s parts",
llstr(param->splits, llbuff),
llstr(share->state.split,llbuff2));
}
@@ -2126,9 +2152,11 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
my_off_t2double(param->used))/
ulonglong2double((ulonglong) share->base.reclength *
param->records)*100.0));
- printf("Recordspace used:%9.0f%% Empty space:%12d%% Blocks/Record: %6.2f\n",
+ printf("Recordspace used:%9.0f%% Empty space:%12d%% "
+ "Blocks/Record: %6.2f\n",
(ulonglong2double(param->used - param->link_used)/
- ulonglong2double(param->used-param->link_used+param->empty)*100.0),
+ ulonglong2double(param->used-param->link_used+param->empty) *
+ 100.0),
(!param->records ? 100 :
(int) (ulonglong2double(param->del_length+param->empty)/
my_off_t2double(param->used)*100.0)),
@@ -2569,7 +2597,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
DBUG_DUMP("record", (uchar*) sort_param.record,
share->base.default_rec_buff_size);
_ma_check_print_warning(param,
- "Duplicate key %2d for record at %10s against new record at %10s",
+ "Duplicate key %2d for record at %10s against "
+ "new record at %10s",
info->errkey+1,
llstr(sort_param.current_filepos, llbuff),
llstr(info->dup_key_pos,llbuff2));
@@ -2629,7 +2658,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (rep_quick && del+sort_info.dupp != share->state.state.del)
{
- _ma_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
+ _ma_check_print_error(param,"Couldn't fix table with quick recovery: "
+ "Found wrong number of deleted records");
_ma_check_print_error(param,"Run recovery again without -q");
param->retry_repair=1;
param->testflag|=T_RETRY_WITHOUT_QUICK;
@@ -2833,6 +2863,7 @@ int maria_movepoint(register MARIA_HA *info, uchar *record,
uint i;
uchar *key_buff;
MARIA_SHARE *share= info->s;
+ MARIA_PAGE page;
DBUG_ENTER("maria_movepoint");
key_buff= info->lastkey_buff + share->base.max_key_length;
@@ -2845,18 +2876,19 @@ int maria_movepoint(register MARIA_HA *info, uchar *record,
0);
if (key.keyinfo->flag & HA_NOSAME)
{ /* Change pointer direct */
- uint nod_flag;
MARIA_KEYDEF *keyinfo;
keyinfo=share->keyinfo+i;
if (_ma_search(info, &key, (uint32) (SEARCH_SAME | SEARCH_SAVE_BUFF),
share->state.key_root[i]))
DBUG_RETURN(-1);
- nod_flag= _ma_test_if_nod(share, info->buff);
- _ma_dpointer(share, info->int_keypos - nod_flag -
+ _ma_page_setup(&page, info, keyinfo, info->last_keypage,
+ info->keyread_buff);
+
+ _ma_dpointer(share, info->int_keypos - page.node -
share->rec_reflength,newpos);
- if (_ma_write_keypage(info, keyinfo, info->last_keypage,
- PAGECACHE_LOCK_LEFT_UNLOCKED, DFLT_INIT_HITS,
- info->buff))
+
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS))
DBUG_RETURN(-1);
}
else
@@ -3053,11 +3085,12 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
MARIA_KEYDEF *keyinfo,
my_off_t pagepos, File new_file)
{
- uint length,nod_flag,used_length;
+ uint length,nod_flag;
uchar *buff,*keypos,*endpos;
my_off_t new_page_pos,next_page;
MARIA_SHARE *share= info->s;
MARIA_KEY key;
+ MARIA_PAGE page;
DBUG_ENTER("sort_one_index");
/* cannot walk over R-tree indices */
@@ -3072,18 +3105,18 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
_ma_check_print_error(param,"Not enough memory for key block");
DBUG_RETURN(-1);
}
- if (!_ma_fetch_keypage(info, keyinfo, pagepos,PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, buff, 0, 0))
+ if (_ma_fetch_keypage(&page, info, keyinfo, pagepos,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, buff, 0))
{
report_keypage_fault(param, info, pagepos);
goto err;
}
- if ((nod_flag=_ma_test_if_nod(share, buff)) || keyinfo->flag & HA_FULLTEXT)
+
+ if ((nod_flag= page.node) || keyinfo->flag & HA_FULLTEXT)
{
- uint page_flag= _ma_get_keypage_flag(share, buff);
- used_length= _ma_get_page_used(share, buff);
- keypos=buff + share->keypage_header + nod_flag;
- endpos=buff + used_length;
+ keypos= page.buff + share->keypage_header + nod_flag;
+ endpos= page.buff + page.size;
for ( ;; )
{
@@ -3097,13 +3130,13 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
DBUG_PRINT("error",
("From page: %ld, keyoffset: %lu used_length: %d",
(ulong) pagepos, (ulong) (keypos - buff),
- (int) used_length));
- DBUG_DUMP("buff",(uchar*) buff,used_length);
+ (int) page.size));
+ DBUG_DUMP("buff", page.buff, page.size);
goto err;
}
}
if (keypos >= endpos ||
- !(*keyinfo->get_key)(&key, page_flag, nod_flag, &keypos))
+ !(*keyinfo->get_key)(&key, page.flag, nod_flag, &keypos))
break;
DBUG_ASSERT(keypos <= endpos);
if (keyinfo->flag & HA_FULLTEXT)
@@ -3126,7 +3159,7 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
}
/* Fill block with zero and write it to the new index file */
- length= _ma_get_page_used(share, buff);
+ length= page.size;
bzero((uchar*) buff+length,keyinfo->block_length-length);
put_crc(buff, new_page_pos, share);
if (my_pwrite(new_file,(uchar*) buff,(uint) keyinfo->block_length,
@@ -3198,9 +3231,11 @@ static my_bool maria_zerofill_index(HA_CHECK *param, MARIA_HA *info,
uint keynr= _ma_get_keynr(share, buff);
if (keynr != MARIA_DELETE_KEY_NR)
{
+ MARIA_PAGE page;
DBUG_ASSERT(keynr < share->base.keys);
- if (_ma_compact_keypage(info, share->keyinfo + keynr, pos,
- buff, ~(TrID) 0))
+
+ _ma_page_setup(&page, info, share->keyinfo + keynr, pos, buff);
+ if (_ma_compact_keypage(&page, ~(TrID) 0))
{
_ma_check_print_error(param,
"Page %9s: Got error %d when reading index "
@@ -3822,7 +3857,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
if (rep_quick && del+sort_info.dupp != share->state.state.del)
{
- _ma_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
+ _ma_check_print_error(param,"Couldn't fix table with quick recovery: "
+ "Found wrong number of deleted records");
_ma_check_print_error(param,"Run recovery again without -q");
got_error=1;
param->retry_repair=1;
@@ -3850,7 +3886,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
if (param->testflag & T_CALC_CHECKSUM)
share->state.state.checksum=param->glob_crc;
- if (my_chsize(share->kfile.file, share->state.state.key_file_length, 0, MYF(0)))
+ if (my_chsize(share->kfile.file, share->state.state.key_file_length, 0,
+ MYF(0)))
_ma_check_print_warning(param,
"Can't change size of indexfile, error: %d",
my_errno);
@@ -4198,8 +4235,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
if (sort_param[i].keyinfo->flag & HA_FULLTEXT)
{
- uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
- sort_param[i].keyinfo->seg->charset->mbmaxlen;
+ uint ft_max_word_len_for_sort=
+ (FT_MAX_WORD_LEN_FOR_SORT *
+ sort_param[i].keyinfo->seg->charset->mbmaxlen);
sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
}
@@ -4325,7 +4363,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
if (rep_quick && del+sort_info.dupp != share->state.state.del)
{
- _ma_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
+ _ma_check_print_error(param,"Couldn't fix table with quick recovery: "
+ "Found wrong number of deleted records");
_ma_check_print_error(param,"Run recovery again without -q");
param->retry_repair=1;
param->testflag|=T_RETRY_WITHOUT_QUICK;
@@ -4351,7 +4390,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
if (param->testflag & T_CALC_CHECKSUM)
share->state.state.checksum=param->glob_crc;
- if (my_chsize(share->kfile.file, share->state.state.key_file_length, 0, MYF(0)))
+ if (my_chsize(share->kfile.file, share->state.state.key_file_length, 0,
+ MYF(0)))
_ma_check_print_warning(param,
"Can't change size of indexfile, error: %d",
my_errno);
@@ -4794,12 +4834,14 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
block_info.next_filepos >=
share->state.state.data_file_length) ||
(block_info.prev_filepos != HA_OFFSET_ERROR &&
- block_info.prev_filepos >= share->state.state.data_file_length))
+ block_info.prev_filepos >=
+ share->state.state.data_file_length))
{
if (!searching)
_ma_check_print_info(param,
- "Delete link points outside datafile at %s",
- llstr(pos,llbuff));
+ "Delete link points outside datafile at "
+ "%s",
+ llstr(pos,llbuff));
error=1;
}
}
@@ -4881,14 +4923,16 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
{
if (param->max_record_length >= block_info.rec_len)
{
- _ma_check_print_error(param,"Not enough memory for blob at %s (need %lu)",
+ _ma_check_print_error(param,"Not enough memory for blob at %s "
+ "(need %lu)",
llstr(sort_param->start_recpos,llbuff),
(ulong) block_info.rec_len);
DBUG_RETURN(1);
}
else
{
- _ma_check_print_info(param,"Not enough memory for blob at %s (need %lu); Row skipped",
+ _ma_check_print_info(param,"Not enough memory for blob at %s "
+ "(need %lu); Row skipped",
llstr(sort_param->start_recpos,llbuff),
(ulong) block_info.rec_len);
goto try_next;
@@ -4941,7 +4985,8 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
parallel_flag))
{
_ma_check_print_info(param,
- "Read error for block at: %s (error: %d); Skipped",
+ "Read error for block at: %s (error: %d); "
+ "Skipped",
llstr(block_info.filepos,llbuff),my_errno);
goto try_next;
}
@@ -4950,13 +4995,18 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
pos=block_info.next_filepos;
if (pos == HA_OFFSET_ERROR && left_length)
{
- _ma_check_print_info(param,"Wrong block with wrong total length starting at %s",
+ _ma_check_print_info(param,
+ "Wrong block with wrong total length "
+ "starting at %s",
llstr(sort_param->start_recpos,llbuff));
goto try_next;
}
- if (pos + MARIA_BLOCK_INFO_HEADER_LENGTH > sort_param->read_cache.end_of_file)
+ if (pos + MARIA_BLOCK_INFO_HEADER_LENGTH >
+ sort_param->read_cache.end_of_file)
{
- _ma_check_print_info(param,"Found link that points at %s (outside data file) at %s",
+ _ma_check_print_info(param,
+ "Found link that points at %s (outside data "
+ "file) at %s",
llstr(pos,llbuff2),
llstr(sort_param->start_recpos,llbuff));
goto try_next;
@@ -5261,7 +5311,8 @@ static int sort_key_write(MARIA_SORT_PARAM *sort_param, const uchar *a)
sort_info->info->cur_row.lastpos= get_record_for_key(sort_param->keyinfo,
a);
_ma_check_print_warning(param,
- "Duplicate key %2u for record at %10s against record at %10s",
+ "Duplicate key %2u for record at %10s against "
+ "record at %10s",
sort_param->key + 1,
llstr(sort_info->info->cur_row.lastpos, llbuff),
llstr(get_record_for_key(sort_param->keyinfo,
@@ -5435,7 +5486,7 @@ static my_off_t get_record_for_key(MARIA_KEYDEF *keyinfo,
} /* get_record_for_key */
- /* Insert a key in sort-key-blocks */
+/* Insert a key in sort-key-blocks */
static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
register SORT_KEY_BLOCKS *key_block,
@@ -5465,7 +5516,9 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
key_block->inited=1;
if (key_block == sort_info->key_block_end)
{
- _ma_check_print_error(param,"To many key-block-levels; Try increasing sort_key_blocks");
+ _ma_check_print_error(param,
+ "To many key-block-levels; "
+ "Try increasing sort_key_blocks");
DBUG_RETURN(1);
}
a_length= share->keypage_header + nod_flag;
@@ -5517,10 +5570,10 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
/* If we read the page from the key cache, we have to write it back to it */
if (page_link->changed)
{
+ MARIA_PAGE page;
pop_dynamic(&info->pinned_pages);
- if (_ma_write_keypage(info, keyinfo, filepos,
- PAGECACHE_LOCK_WRITE_UNLOCK,
- DFLT_INIT_HITS, anc_buff))
+ _ma_page_setup(&page, info, keyinfo, filepos, anc_buff);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_WRITE_UNLOCK, DFLT_INIT_HITS))
DBUG_RETURN(1);
}
else
@@ -5557,8 +5610,8 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
{
_ma_check_print_error(param,
- "Quick-recover aborted; Run recovery without switch -q or with "
- "switch -qq");
+ "Quick-recover aborted; Run recovery without switch "
+ "-q or with switch -qq");
DBUG_RETURN(1);
}
if (key_info->s->options & HA_OPTION_COMPRESS_RECORD)
@@ -5646,10 +5699,12 @@ int _ma_flush_pending_blocks(MARIA_SORT_PARAM *sort_param)
/* If we read the page from the key cache, we have to write it back */
if (page_link->changed)
{
+ MARIA_PAGE page;
pop_dynamic(&info->pinned_pages);
- if (_ma_write_keypage(info, keyinfo, filepos,
- PAGECACHE_LOCK_WRITE_UNLOCK,
- DFLT_INIT_HITS, key_block->buff))
+
+ _ma_page_setup(&page, info, keyinfo, filepos, key_block->buff);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_WRITE_UNLOCK,
+ DFLT_INIT_HITS))
goto err;
}
else
@@ -5865,8 +5920,8 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
if (!*org_info)
{
_ma_check_print_error(param,
- "Got error %d when trying to open re-created indexfile",
- my_errno);
+ "Got error %d when trying to open re-created "
+ "indexfile", my_errno);
goto end;
}
/* We are modifing */
@@ -6644,13 +6699,17 @@ static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid)
if (!ma_control_file_inited())
{
_ma_check_print_warning(param,
- "Found row with transaction id %s but no maria_control_file was specified. The table may be corrupted",
+ "Found row with transaction id %s but no "
+ "maria_control_file was specified. "
+ "The table may be corrupted",
llstr(used_trid, buff));
}
else
{
_ma_check_print_error(param,
- "Found row with transaction id %s when max transaction id according to maria_control_file is %s",
+ "Found row with transaction id %s when max "
+ "transaction id according to maria_control_file "
+ "is %s",
llstr(used_trid, buff),
llstr(param->max_trid, buff2));
}
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index 26cc202f542..52e1f048eb6 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -19,16 +19,13 @@
#include "ma_key_recover.h"
static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
- my_off_t page, uchar *anc_buff,
- MARIA_PINNED_PAGE *anc_page_link);
+ MARIA_PAGE *page);
static int del(MARIA_HA *info, MARIA_KEY *key,
- my_off_t anc_page, uchar *anc_buff, my_off_t leaf_page,
- uchar *leaf_buff, MARIA_PINNED_PAGE *leaf_page_link,
- uchar *keypos, my_off_t next_block, uchar *ret_key);
-static int underflow(MARIA_HA *info,MARIA_KEYDEF *keyinfo,
- my_off_t anc_page, uchar *anc_buff,
- my_off_t leaf_page, uchar *leaf_buff,
- MARIA_PINNED_PAGE *leaf_page_link, uchar *keypos);
+ MARIA_PAGE *anc_page, MARIA_PAGE *leaf_page,
+ uchar *keypos, my_off_t next_block, uchar *ret_key_buff);
+static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ MARIA_PAGE *anc_page, MARIA_PAGE *leaf_page,
+ uchar *keypos);
static uint remove_key(MARIA_KEYDEF *keyinfo, uint page_flag, uint nod_flag,
uchar *keypos, uchar *lastkey, uchar *page_end,
my_off_t *next_block, MARIA_KEY_PARAM *s_temp);
@@ -161,7 +158,7 @@ err:
of key->data. This would allows us to remove the copying of the key here.
*/
-int _ma_ck_delete(register MARIA_HA *info, MARIA_KEY *key)
+my_bool _ma_ck_delete(MARIA_HA *info, MARIA_KEY *key)
{
MARIA_SHARE *share= info->s;
int res;
@@ -191,77 +188,78 @@ int _ma_ck_delete(register MARIA_HA *info, MARIA_KEY *key)
_ma_fast_unlock_key_del(info);
}
_ma_unpin_all_pages_and_finalize_row(info, lsn);
- DBUG_RETURN(res);
+ DBUG_RETURN(res != 0);
} /* _ma_ck_delete */
-int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEY *key,
- my_off_t *root)
+my_bool _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEY *key,
+ my_off_t *root)
{
int error;
- uint nod_flag;
+ my_bool result= 0;
my_off_t old_root;
uchar *root_buff;
- MARIA_PINNED_PAGE *page_link;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ MARIA_PAGE page;
DBUG_ENTER("_ma_ck_real_delete");
if ((old_root=*root) == HA_OFFSET_ERROR)
{
- maria_print_error(info->s, HA_ERR_CRASHED);
- DBUG_RETURN(my_errno=HA_ERR_CRASHED);
+ my_errno=HA_ERR_CRASHED;
+ DBUG_RETURN(1);
}
if (!(root_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MARIA_MAX_KEY_BUFF*2)))
{
DBUG_PRINT("error",("Couldn't allocate memory"));
- DBUG_RETURN(my_errno=ENOMEM);
+ my_errno=ENOMEM;
+ DBUG_RETURN(1);
}
DBUG_PRINT("info",("root_page: %ld", (long) old_root));
- if (!_ma_fetch_keypage(info, keyinfo, old_root,
- PAGECACHE_LOCK_WRITE, DFLT_INIT_HITS, root_buff, 0,
- &page_link))
+ if (_ma_fetch_keypage(&page, info, keyinfo, old_root,
+ PAGECACHE_LOCK_WRITE, DFLT_INIT_HITS, root_buff, 0))
{
- error= -1;
+ result= 1;
goto err;
}
if ((error= d_search(info, key, (keyinfo->flag & HA_FULLTEXT ?
SEARCH_FIND | SEARCH_UPDATE | SEARCH_INSERT:
SEARCH_SAME),
- old_root, root_buff, page_link)) > 0)
+ &page)))
{
- if (error == 2)
+ if (error < 0)
+ result= 1;
+ else if (error == 2)
{
DBUG_PRINT("test",("Enlarging of root when deleting"));
- error= _ma_enlarge_root(info, key, root);
+ if (_ma_enlarge_root(info, key, root))
+ result= 1;
}
else /* error == 1 */
{
- uint used_length;
MARIA_SHARE *share= info->s;
- _ma_get_used_and_nod(share, root_buff, used_length, nod_flag);
- page_link->changed= 1;
- if (used_length <= nod_flag + share->keypage_header + 1)
+
+ page_mark_changed(info, &page);
+
+ if (page.size <= page.node + share->keypage_header + 1)
{
- error=0;
- if (nod_flag)
- *root= _ma_kpos(nod_flag, root_buff +share->keypage_header +
- nod_flag);
+ if (page.node)
+ *root= _ma_kpos(page.node, root_buff +share->keypage_header +
+ page.node);
else
*root=HA_OFFSET_ERROR;
if (_ma_dispose(info, old_root, 0))
- error= -1;
+ result= 1;
}
- else
- error= _ma_write_keypage(info,keyinfo, old_root,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, root_buff);
+ else if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ result= 1;
}
}
err:
my_afree((uchar*) root_buff);
- DBUG_PRINT("exit",("Return: %d",error));
- DBUG_RETURN(error);
+ DBUG_PRINT("exit",("Return: %d",result));
+ DBUG_RETURN(result);
} /* _ma_ck_real_delete */
@@ -278,31 +276,29 @@ err:
*/
static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
- my_off_t anc_page, uchar *anc_buff,
- MARIA_PINNED_PAGE *anc_page_link)
+ MARIA_PAGE *anc_page)
{
int flag,ret_value,save_flag;
uint nod_flag, page_flag;
my_bool last_key;
uchar *leaf_buff,*keypos;
- my_off_t leaf_page,next_block;
uchar lastkey[MARIA_MAX_KEY_BUFF];
- MARIA_PINNED_PAGE *leaf_page_link;
MARIA_KEY_PARAM s_temp;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ MARIA_PAGE leaf_page;
DBUG_ENTER("d_search");
- DBUG_DUMP("page",anc_buff,_ma_get_page_used(share, anc_buff));
+ DBUG_DUMP("page", anc_page->buff, anc_page->size);
- flag=(*keyinfo->bin_search)(key, anc_buff, comp_flag, &keypos, lastkey,
+ flag=(*keyinfo->bin_search)(key, anc_page, comp_flag, &keypos, lastkey,
&last_key);
if (flag == MARIA_FOUND_WRONG_KEY)
{
DBUG_PRINT("error",("Found wrong key"));
DBUG_RETURN(-1);
}
- page_flag= _ma_get_keypage_flag(share, anc_buff);
- nod_flag= _ma_test_if_nod(share, anc_buff);
+ page_flag= anc_page->flag;
+ nod_flag= anc_page->node;
if (!flag && (keyinfo->flag & HA_FULLTEXT))
{
@@ -324,7 +320,7 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
else
{
/* we need exact match only if not in ft1->ft2 conversion mode */
- flag=(*keyinfo->bin_search)(key, anc_buff, comp_flag, &keypos,
+ flag=(*keyinfo->bin_search)(key, anc_page, comp_flag, &keypos,
lastkey, &last_key);
}
/* fall through to normal delete */
@@ -343,7 +339,6 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
if (!(tmp_key_length=(*keyinfo->get_key)(&tmp_key, page_flag, nod_flag,
&kpos)))
{
- maria_print_error(share, HA_ERR_CRASHED);
my_errno= HA_ERR_CRASHED;
DBUG_RETURN(-1);
}
@@ -374,10 +369,10 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
ft_intXstore(kpos, subkeys);
if (!ret_value)
{
- anc_page_link->changed= 1;
- ret_value= _ma_write_keypage(info, keyinfo, anc_page,
+ page_mark_changed(info, anc_page);
+ ret_value= _ma_write_keypage(anc_page,
PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, anc_buff);
+ DFLT_INIT_HITS);
}
DBUG_PRINT("exit",("Return: %d",ret_value));
DBUG_RETURN(ret_value);
@@ -385,11 +380,10 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
}
}
leaf_buff=0;
- LINT_INIT(leaf_page);
if (nod_flag)
{
/* Read left child page */
- leaf_page= _ma_kpos(nod_flag,keypos);
+ leaf_page.pos= _ma_kpos(nod_flag,keypos);
if (!(leaf_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MARIA_MAX_KEY_BUFF*2)))
{
@@ -397,9 +391,9 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
my_errno=ENOMEM;
DBUG_RETURN(-1);
}
- if (!_ma_fetch_keypage(info,keyinfo,leaf_page,
- PAGECACHE_LOCK_WRITE, DFLT_INIT_HITS, leaf_buff,
- 0, &leaf_page_link))
+ if (_ma_fetch_keypage(&leaf_page, info,keyinfo, leaf_page.pos,
+ PAGECACHE_LOCK_WRITE, DFLT_INIT_HITS, leaf_buff,
+ 0))
goto err;
}
@@ -408,28 +402,28 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
if (!nod_flag)
{
DBUG_PRINT("error",("Didn't find key"));
- maria_print_error(share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED; /* This should newer happend */
goto err;
}
save_flag=0;
- ret_value= d_search(info, key, comp_flag, leaf_page, leaf_buff,
- leaf_page_link);
+ ret_value= d_search(info, key, comp_flag, &leaf_page);
}
else
{ /* Found key */
uint tmp;
- uint anc_buff_length= _ma_get_page_used(share, anc_buff);
- uint anc_page_flag= _ma_get_keypage_flag(share, anc_buff);
+ uint anc_buff_length= anc_page->size;
+ uint anc_page_flag= anc_page->flag;
+ my_off_t next_block;
if (!(tmp= remove_key(keyinfo, anc_page_flag, nod_flag, keypos, lastkey,
- anc_buff + anc_buff_length,
+ anc_page->buff + anc_buff_length,
&next_block, &s_temp)))
goto err;
- anc_page_link->changed= 1;
+ page_mark_changed(info, anc_page);
anc_buff_length-= tmp;
- _ma_store_page_used(share, anc_buff, anc_buff_length);
+ anc_page->size= anc_buff_length;
+ page_store_size(share, anc_page);
/*
Log initial changes on pages
@@ -437,7 +431,7 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
page
*/
if (share->now_transactional &&
- _ma_log_delete(info, anc_page, anc_buff, s_temp.key_pos,
+ _ma_log_delete(anc_page, s_temp.key_pos,
s_temp.changed_length, s_temp.move_length))
DBUG_RETURN(-1);
@@ -450,23 +444,20 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
/* Page will be written by caller if we return 1 */
DBUG_RETURN(1);
}
- if (_ma_write_keypage(info, keyinfo, anc_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS,
- anc_buff))
+ if (_ma_write_keypage(anc_page,
+ PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS))
DBUG_RETURN(-1);
DBUG_RETURN(0);
}
save_flag=1; /* Mark that anc_buff is changed */
- ret_value= del(info, key, anc_page, anc_buff,
- leaf_page, leaf_buff, leaf_page_link,
+ ret_value= del(info, key, anc_page, &leaf_page,
keypos, next_block, lastkey);
}
if (ret_value >0)
{
save_flag=1;
if (ret_value == 1)
- ret_value= underflow(info, keyinfo, anc_page, anc_buff,
- leaf_page, leaf_buff, leaf_page_link, keypos);
+ ret_value= underflow(info, keyinfo, anc_page, &leaf_page, keypos);
else
{
/* This can only happen with variable length keys */
@@ -475,33 +466,33 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
last_key.data= lastkey;
last_key.keyinfo= keyinfo;
- if (!_ma_get_last_key(&last_key, anc_buff, keypos))
+ if (!_ma_get_last_key(&last_key, anc_page, keypos))
goto err;
- ret_value= _ma_insert(info, key, anc_buff, keypos, anc_page,
- last_key.data, (my_off_t) 0, (uchar*) 0,
- (MARIA_PINNED_PAGE*) 0, (uchar*) 0, (my_bool) 0);
+ ret_value= _ma_insert(info, key, anc_page, keypos,
+ last_key.data,
+ (MARIA_PAGE*) 0, (uchar*) 0, (my_bool) 0);
}
}
- if (ret_value == 0 && _ma_get_page_used(share, anc_buff) >
+ if (ret_value == 0 && anc_page->size >
(uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
{
/* parent buffer got too big ; We have to split the page */
save_flag=1;
- ret_value= _ma_split_page(info, key, anc_page, anc_buff,
+ ret_value= _ma_split_page(info, key, anc_page,
(uint) (keyinfo->block_length -
KEYPAGE_CHECKSUM_SIZE),
(uchar*) 0, 0, 0, lastkey, 0) | 2;
}
if (save_flag && ret_value != 1)
{
- anc_page_link->changed= 1;
- ret_value|= _ma_write_keypage(info, keyinfo, anc_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, anc_buff);
+ page_mark_changed(info, anc_page);
+ if (_ma_write_keypage(anc_page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ ret_value= -1;
}
else
{
- DBUG_DUMP("page", anc_buff, _ma_get_page_used(share, anc_buff));
+ DBUG_DUMP("page", anc_page->buff, anc_page->size);
}
my_afree(leaf_buff);
DBUG_PRINT("exit",("Return: %d",ret_value));
@@ -529,8 +520,8 @@ err:
@param ret_key_buff Key before keypos in anc_buff
@notes
- leaf_buff must be written to disk if retval > 0
- anc_buff is not updated on disk. Caller should do this
+ leaf_page must be written to disk if retval > 0
+ anc_page is not updated on disk. Caller should do this
@return
@retval < 0 Error
@@ -542,65 +533,60 @@ err:
*/
static int del(MARIA_HA *info, MARIA_KEY *key,
- my_off_t anc_page, uchar *anc_buff,
- my_off_t leaf_page, uchar *leaf_buff,
- MARIA_PINNED_PAGE *leaf_page_link,
+ MARIA_PAGE *anc_page, MARIA_PAGE *leaf_page,
uchar *keypos, my_off_t next_block, uchar *ret_key_buff)
{
int ret_value,length;
uint a_length, page_flag, nod_flag, leaf_length, new_leaf_length;
- my_off_t next_page;
uchar keybuff[MARIA_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
+ uchar *anc_buff;
MARIA_KEY_PARAM s_temp;
- MARIA_PINNED_PAGE *next_page_link;
MARIA_KEY tmp_key;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_KEY ret_key;
+ MARIA_PAGE next_page;
DBUG_ENTER("del");
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", (long) leaf_page,
(ulong) keypos));
+ DBUG_DUMP("leaf_buff", leaf_page->buff, leaf_page->size);
- page_flag= _ma_get_keypage_flag(share, leaf_buff);
- _ma_get_used_and_nod_with_flag(share, page_flag, leaf_buff, leaf_length,
- nod_flag);
- DBUG_DUMP("leaf_buff", leaf_buff, leaf_length);
+ page_flag= leaf_page->flag;
+ leaf_length= leaf_page->size;
+ nod_flag= leaf_page->node;
- endpos= leaf_buff + leaf_length;
+ endpos= leaf_page->buff + leaf_length;
tmp_key.keyinfo= keyinfo;
tmp_key.data= keybuff;
- if (!(key_start= _ma_get_last_key(&tmp_key, leaf_buff, endpos)))
+ if (!(key_start= _ma_get_last_key(&tmp_key, leaf_page, endpos)))
DBUG_RETURN(-1);
if (nod_flag)
{
- next_page= _ma_kpos(nod_flag,endpos);
+ next_page.pos= _ma_kpos(nod_flag,endpos);
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MARIA_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
- if (!_ma_fetch_keypage(info, keyinfo, next_page, PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, next_buff, 0, &next_page_link))
+ if (_ma_fetch_keypage(&next_page, info, keyinfo, next_page.pos,
+ PAGECACHE_LOCK_WRITE, DFLT_INIT_HITS, next_buff, 0))
ret_value= -1;
else
{
- DBUG_DUMP("next_page", next_buff, _ma_get_page_used(share, next_buff));
- if ((ret_value= del(info, key, anc_page, anc_buff, next_page,
- next_buff, next_page_link, keypos, next_block,
- ret_key_buff)) >0)
+ DBUG_DUMP("next_page", next_page.buff, next_page.size);
+ if ((ret_value= del(info, key, anc_page, &next_page,
+ keypos, next_block, ret_key_buff)) >0)
{
/* Get new length after key was deleted */
- endpos=leaf_buff+_ma_get_page_used(share, leaf_buff);
+ endpos= leaf_page->buff+ leaf_page->size;
if (ret_value == 1)
{
- ret_value= underflow(info, keyinfo, leaf_page, leaf_buff, next_page,
- next_buff, next_page_link, endpos);
- if (ret_value == 0 &&
- _ma_get_page_used(share, leaf_buff) >
+ ret_value= underflow(info, keyinfo, leaf_page, &next_page,
+ endpos);
+ if (ret_value == 0 && leaf_page->size >
(uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
{
- ret_value= (_ma_split_page(info, key,
- leaf_page, leaf_buff,
+ ret_value= (_ma_split_page(info, key, leaf_page,
(uint) (keyinfo->block_length -
KEYPAGE_CHECKSUM_SIZE),
(uchar*) 0, 0, 0,
@@ -610,24 +596,23 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
else
{
DBUG_PRINT("test",("Inserting of key when deleting"));
- if (!_ma_get_last_key(&tmp_key, leaf_buff, endpos))
+ if (!_ma_get_last_key(&tmp_key, leaf_page, endpos))
goto err;
- ret_value= _ma_insert(info, key, leaf_buff, endpos,
- leaf_page, tmp_key.data, (my_off_t) 0,
- (uchar*) 0, (MARIA_PINNED_PAGE *) 0,
- (uchar*) 0, 0);
+ ret_value= _ma_insert(info, key, leaf_page, endpos,
+ tmp_key.data, (MARIA_PAGE *) 0, (uchar*) 0,
+ 0);
}
}
- leaf_page_link->changed= 1;
+ page_mark_changed(info, leaf_page);
/*
If ret_value <> 0, then leaf_page underflowed and caller will have
to handle underflow and write leaf_page to disk.
We can't write it here, as if leaf_page is empty we get an assert
in _ma_write_keypage.
*/
- if (ret_value == 0 && _ma_write_keypage(info, keyinfo, leaf_page,
+ if (ret_value == 0 && _ma_write_keypage(leaf_page,
PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, leaf_buff))
+ DFLT_INIT_HITS))
goto err;
}
my_afree(next_buff);
@@ -640,15 +625,15 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
happen in quick mode), in which ase it will now temporary have 0 keys
on it. This will be corrected by the caller as we will return 0.
*/
- new_leaf_length= (uint) (key_start - leaf_buff);
- _ma_store_page_used(share, leaf_buff, new_leaf_length);
+ new_leaf_length= (uint) (key_start - leaf_page->buff);
+ leaf_page->size= new_leaf_length;
+ page_store_size(share, leaf_page);
if (share->now_transactional &&
- _ma_log_suffix(info, leaf_page, leaf_buff, leaf_length,
- new_leaf_length))
+ _ma_log_suffix(leaf_page, leaf_length, new_leaf_length))
goto err;
- leaf_page_link->changed= 1; /* Safety */
+ page_mark_changed(info, leaf_page); /* Safety */
if (new_leaf_length <= (info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH :
(uint) keyinfo->underflow_block_length))
{
@@ -658,15 +643,15 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
else
{
ret_value= 0;
- if (_ma_write_keypage(info, keyinfo, leaf_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS,
- leaf_buff))
+ if (_ma_write_keypage(leaf_page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
goto err;
}
/* Place last key in ancestor page on deleted key position */
- a_length= _ma_get_page_used(share, anc_buff);
- endpos=anc_buff+a_length;
+ a_length= anc_page->size;
+ anc_buff= anc_page->buff;
+ endpos= anc_buff + a_length;
ret_key.keyinfo= keyinfo;
ret_key.data= ret_key_buff;
@@ -674,7 +659,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
prev_key= 0;
if (keypos != anc_buff+share->keypage_header + share->base.key_reflength)
{
- if (!_ma_get_last_key(&ret_key, anc_buff, keypos))
+ if (!_ma_get_last_key(&ret_key, anc_page, keypos))
goto err;
prev_key= ret_key.data;
}
@@ -690,17 +675,20 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
key_start= keypos;
if (tmp_key.flag & (SEARCH_USER_KEY_HAS_TRANSID |
SEARCH_PAGE_KEY_HAS_TRANSID))
- _ma_mark_page_with_transid(share, anc_buff);
+ {
+ _ma_mark_page_with_transid(share, anc_page);
+ }
/* Save pointer to next leaf on parent page */
if (!(*keyinfo->get_key)(&ret_key, page_flag, share->base.key_reflength,
&keypos))
goto err;
_ma_kpointer(info,keypos - share->base.key_reflength,next_block);
- _ma_store_page_used(share, anc_buff, a_length + length);
+ anc_page->size= a_length + length;
+ page_store_size(share, anc_page);
if (share->now_transactional &&
- _ma_log_add(info, anc_page, anc_buff, a_length,
+ _ma_log_add(anc_page, a_length,
key_start, s_temp.changed_length, s_temp.move_length, 1))
goto err;
@@ -733,10 +721,8 @@ err:
@retval -1 error
*/
-static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t anc_page, uchar *anc_buff,
- my_off_t leaf_page, uchar *leaf_buff,
- MARIA_PINNED_PAGE *leaf_page_link,
+static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ MARIA_PAGE *anc_page, MARIA_PAGE *leaf_page,
uchar *keypos)
{
int t_length;
@@ -744,35 +730,36 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
uint next_buff_length, new_buff_length, key_reflength;
uint unchanged_leaf_length, new_leaf_length, new_anc_length;
uint anc_page_flag, page_flag;
- my_off_t next_page;
uchar anc_key_buff[MARIA_MAX_KEY_BUFF], leaf_key_buff[MARIA_MAX_KEY_BUFF];
- uchar *buff,*endpos,*next_keypos,*anc_pos,*half_pos,*prev_key;
+ uchar *endpos, *next_keypos, *anc_pos, *half_pos, *prev_key;
+ uchar *anc_buff, *leaf_buff;
uchar *after_key, *anc_end_pos;
MARIA_KEY_PARAM key_deleted, key_inserted;
MARIA_SHARE *share= info->s;
- MARIA_PINNED_PAGE *next_page_link;
my_bool first_key;
MARIA_KEY tmp_key, anc_key, leaf_key;
+ MARIA_PAGE next_page;
DBUG_ENTER("underflow");
- DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page,
+ DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page->pos,
(ulong) keypos));
- DBUG_DUMP("anc_buff", anc_buff, _ma_get_page_used(share, anc_buff));
- DBUG_DUMP("leaf_buff", leaf_buff, _ma_get_page_used(share, leaf_buff));
+ DBUG_DUMP("anc_buff", anc_page->buff, anc_page->size);
+ DBUG_DUMP("leaf_buff", leaf_page->buff, leaf_page->size);
- anc_page_flag= _ma_get_keypage_flag(share, anc_buff);
- buff=info->buff;
+ anc_page_flag= anc_page->flag;
+ anc_buff= anc_page->buff;
+ leaf_buff= leaf_page->buff;
info->keyread_buff_used=1;
next_keypos=keypos;
- nod_flag= _ma_test_if_nod(share, leaf_buff);
+ nod_flag= leaf_page->node;
p_length= nod_flag+share->keypage_header;
- anc_length= _ma_get_page_used(share, anc_buff);
- leaf_length= _ma_get_page_used(share, leaf_buff);
- key_reflength=share->base.key_reflength;
+ anc_length= anc_page->size;
+ leaf_length= leaf_page->size;
+ key_reflength= share->base.key_reflength;
if (share->keyinfo+info->lastinx == keyinfo)
info->page_changed=1;
first_key= keypos == anc_buff + share->keypage_header + key_reflength;
- tmp_key.data= buff;
+ tmp_key.data= info->buff;
anc_key.data= anc_key_buff;
leaf_key.data= leaf_key_buff;
tmp_key.keyinfo= leaf_key.keyinfo= anc_key.keyinfo= keyinfo;
@@ -791,85 +778,89 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
*/
if (keyinfo->flag & HA_BINARY_PACK_KEY)
{
- if (!(next_keypos= _ma_get_key(&tmp_key, anc_buff, keypos)))
+ if (!(next_keypos= _ma_get_key(&tmp_key, anc_page, keypos)))
goto err;
}
else
{
+ /* Avoid length error check if packed key */
+ tmp_key.data[0]= tmp_key.data[1]= 0;
/* Got to end of found key */
- buff[0]=buff[1]=0; /* Avoid length error check if packed key */
if (!(*keyinfo->get_key)(&tmp_key, anc_page_flag, key_reflength,
&next_keypos))
goto err;
}
- next_page= _ma_kpos(key_reflength,next_keypos);
- if (!_ma_fetch_keypage(info,keyinfo, next_page, PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, buff, 0, &next_page_link))
+ next_page.pos= _ma_kpos(key_reflength, next_keypos);
+ if (_ma_fetch_keypage(&next_page, info, keyinfo, next_page.pos,
+ PAGECACHE_LOCK_WRITE, DFLT_INIT_HITS, info->buff, 0))
goto err;
- next_buff_length= _ma_get_page_used(share, buff);
- next_page_flag= _ma_get_keypage_flag(share,buff);
- DBUG_DUMP("next", buff, next_buff_length);
+ next_buff_length= next_page.size;
+ next_page_flag= next_page.flag;
+ DBUG_DUMP("next", next_page.buff, next_page.size);
/* find keys to make a big key-page */
- bmove(next_keypos-key_reflength, buff + share->keypage_header,
+ bmove(next_keypos-key_reflength, next_page.buff + share->keypage_header,
key_reflength);
- if (!_ma_get_last_key(&anc_key, anc_buff, next_keypos) ||
- !_ma_get_last_key(&leaf_key, leaf_buff, leaf_buff+leaf_length))
+ if (!_ma_get_last_key(&anc_key, anc_page, next_keypos) ||
+ !_ma_get_last_key(&leaf_key, leaf_page, leaf_buff+leaf_length))
goto err;
- /* merge pages and put parting key from anc_buff between */
+ /* merge pages and put parting key from anc_page between */
prev_key= (leaf_length == p_length ? (uchar*) 0 : leaf_key.data);
- t_length= (*keyinfo->pack_key)(&anc_key, nod_flag, buff+p_length,
+ t_length= (*keyinfo->pack_key)(&anc_key, nod_flag, next_page.buff+p_length,
prev_key, prev_key, &key_inserted);
tmp_length= next_buff_length - p_length;
- endpos= buff+tmp_length+leaf_length+t_length;
- /* buff will always be larger than before !*/
- bmove_upp(endpos, buff + next_buff_length, tmp_length);
- memcpy(buff, leaf_buff,(size_t) leaf_length);
- (*keyinfo->store_key)(keyinfo, buff+leaf_length, &key_inserted);
- buff_length= (uint) (endpos-buff);
- _ma_store_page_used(share, buff, buff_length);
+ endpos= next_page.buff + tmp_length + leaf_length + t_length;
+ /* next_page.buff will always be larger than before !*/
+ bmove_upp(endpos, next_page.buff + next_buff_length, tmp_length);
+ memcpy(next_page.buff, leaf_buff,(size_t) leaf_length);
+ (*keyinfo->store_key)(keyinfo, next_page.buff+leaf_length, &key_inserted);
+ buff_length= (uint) (endpos - next_page.buff);
/* Set page flag from combination of both key pages and parting key */
- page_flag= (next_page_flag |
- _ma_get_keypage_flag(share, leaf_buff));
+ page_flag= next_page_flag | leaf_page->flag;
if (anc_key.flag & (SEARCH_USER_KEY_HAS_TRANSID |
SEARCH_PAGE_KEY_HAS_TRANSID))
page_flag|= KEYPAGE_FLAG_HAS_TRANSID;
- _ma_store_keypage_flag(share, buff, page_flag);
- /* remove key from anc_buff */
+ next_page.size= buff_length;
+ next_page.flag= page_flag;
+ page_store_info(share, &next_page);
+
+ /* remove key from anc_page */
if (!(s_length=remove_key(keyinfo, anc_page_flag, key_reflength, keypos,
anc_key_buff, anc_buff+anc_length,
(my_off_t *) 0, &key_deleted)))
goto err;
new_anc_length= anc_length - s_length;
- _ma_store_page_used(share, anc_buff, new_anc_length);
+ anc_page->size= new_anc_length;
+ page_store_size(share, anc_page);
if (buff_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
{
/* All keys fitted into one page */
- next_page_link->changed= 1;
- if (_ma_dispose(info, next_page, 0))
+ page_mark_changed(info, &next_page);
+ if (_ma_dispose(info, next_page.pos, 0))
goto err;
- memcpy(leaf_buff, buff, (size_t) buff_length);
+ memcpy(leaf_buff, next_page.buff, (size_t) buff_length);
+ leaf_page->size= next_page.size;
+ leaf_page->flag= next_page.flag;
if (share->now_transactional)
{
/* Log changes to parent page */
- if (_ma_log_delete(info, anc_page, anc_buff, key_deleted.key_pos,
+ if (_ma_log_delete(anc_page, key_deleted.key_pos,
key_deleted.changed_length,
key_deleted.move_length))
goto err;
/*
- Log changes to leaf page. Data for leaf page is in buff
+ Log changes to leaf page. Data for leaf page is in leaf_buff
which contains original leaf_buff, parting key and next_buff
*/
- if (_ma_log_suffix(info, leaf_page, leaf_buff,
- leaf_length, buff_length))
+ if (_ma_log_suffix(leaf_page, leaf_length, buff_length))
goto err;
}
}
@@ -879,9 +870,9 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
Balancing didn't free a page, so we have to split 'buff' into two
pages:
- Find key in middle of buffer
- - Store everything before key in 'leaf_buff'
- - Pack key into anc_buff at position of deleted key
- Note that anc_buff may overflow! (is handled by caller)
+ - Store everything before key in 'leaf_page'
+ - Pack key into anc_page at position of deleted key
+ Note that anc_page may overflow! (is handled by caller)
- Store remaining keys in next_page (buff)
*/
MARIA_KEY_PARAM anc_key_inserted;
@@ -891,23 +882,24 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
DBUG_PRINT("test",("anc_buff: 0x%lx anc_end_pos: 0x%lx",
(long) anc_buff, (long) anc_end_pos));
- if (!first_key && !_ma_get_last_key(&anc_key, anc_buff, keypos))
+ if (!first_key && !_ma_get_last_key(&anc_key, anc_page, keypos))
goto err;
- if (!(half_pos= _ma_find_half_pos(info, &leaf_key, nod_flag, buff,
- &after_key)))
+ if (!(half_pos= _ma_find_half_pos(&leaf_key, &next_page, &after_key)))
goto err;
- new_leaf_length= (uint) (half_pos-buff);
- memcpy(leaf_buff, buff, (size_t) new_leaf_length);
- _ma_store_page_used(share, leaf_buff, new_leaf_length);
- _ma_store_keypage_flag(share, leaf_buff, page_flag);
+ new_leaf_length= (uint) (half_pos - next_page.buff);
+ memcpy(leaf_buff, next_page.buff, (size_t) new_leaf_length);
+
+ leaf_page->size= new_leaf_length;
+ leaf_page->flag= page_flag;
+ page_store_info(share, leaf_page);
/* Correct new keypointer to leaf_page */
half_pos=after_key;
_ma_kpointer(info,
- leaf_key.data+leaf_key.data_length + leaf_key.ref_length,
- next_page);
+ leaf_key.data + leaf_key.data_length + leaf_key.ref_length,
+ next_page.pos);
- /* Save key in anc_buff */
+ /* Save key in anc_page */
prev_key= (first_key ? (uchar*) 0 : anc_key.data);
t_length= (*keyinfo->pack_key)(&leaf_key, key_reflength,
(keypos == anc_end_pos ? (uchar*) 0 :
@@ -920,14 +912,16 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
bmove(keypos,keypos-t_length,(uint) (anc_end_pos-keypos)+t_length);
(*keyinfo->store_key)(keyinfo,keypos, &anc_key_inserted);
new_anc_length+= t_length;
- _ma_store_page_used(share, anc_buff, new_anc_length);
+ anc_page->size= new_anc_length;
+ page_store_size(share, anc_page);
+
if (leaf_key.flag & (SEARCH_USER_KEY_HAS_TRANSID |
SEARCH_PAGE_KEY_HAS_TRANSID))
- _ma_mark_page_with_transid(share, anc_buff);
+ _ma_mark_page_with_transid(share, anc_page);
/* Store key first in new page */
if (nod_flag)
- bmove(buff+share->keypage_header, half_pos-nod_flag,
+ bmove(next_page.buff + share->keypage_header, half_pos-nod_flag,
(size_t) nod_flag);
if (!(*keyinfo->get_key)(&leaf_key, page_flag, nod_flag, &half_pos))
goto err;
@@ -935,11 +929,12 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
(uchar*) 0, (uchar*) 0,
&key_inserted);
/* t_length will always be > 0 for a new page !*/
- tmp_length= (size_t) ((buff + buff_length) - half_pos);
- bmove(buff+p_length+t_length, half_pos, tmp_length);
- (*keyinfo->store_key)(keyinfo,buff+p_length, &key_inserted);
+ tmp_length= (size_t) ((next_page.buff + buff_length) - half_pos);
+ bmove(next_page.buff + p_length + t_length, half_pos, tmp_length);
+ (*keyinfo->store_key)(keyinfo, next_page.buff + p_length, &key_inserted);
new_buff_length= tmp_length + t_length + p_length;
- _ma_store_page_used(share, buff, new_buff_length);
+ next_page.size= new_buff_length;
+ page_store_size(share, &next_page);
/* keypage flag is already up to date */
if (share->now_transactional)
@@ -952,8 +947,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
ma_log_add ensures that we don't log changes that is outside of
key block size, as the REDO code can't handle that
*/
- if (_ma_log_add(info, anc_page, anc_buff, anc_length,
- keypos,
+ if (_ma_log_add(anc_page, anc_length, keypos,
anc_key_inserted.move_length +
max(anc_key_inserted.changed_length -
anc_key_inserted.move_length,
@@ -967,8 +961,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
This contains original data with new data added at end
*/
DBUG_ASSERT(leaf_length <= new_leaf_length);
- if (_ma_log_suffix(info, leaf_page, leaf_buff, leaf_length,
- new_leaf_length))
+ if (_ma_log_suffix(leaf_page, leaf_length, new_leaf_length))
goto err;
/*
Log changes to next page
@@ -989,22 +982,19 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
*/
DBUG_ASSERT(new_buff_length <= next_buff_length);
- if (_ma_log_prefix(info, next_page, buff,
- key_inserted.changed_length,
+ if (_ma_log_prefix(&next_page, key_inserted.changed_length,
(int) (new_buff_length - next_buff_length)))
goto err;
}
- next_page_link->changed= 1;
- if (_ma_write_keypage(info, keyinfo, next_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS,
- buff))
+ page_mark_changed(info, &next_page);
+ if (_ma_write_keypage(&next_page,
+ PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS))
goto err;
}
- leaf_page_link->changed= 1;
- if (_ma_write_keypage(info, keyinfo, leaf_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS,
- leaf_buff))
+ page_mark_changed(info, leaf_page);
+ if (_ma_write_keypage(leaf_page,
+ PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS))
goto err;
DBUG_RETURN(new_anc_length <=
((info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH :
@@ -1013,16 +1003,16 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
DBUG_PRINT("test",("use left page"));
- keypos= _ma_get_last_key(&anc_key, anc_buff, keypos);
+ keypos= _ma_get_last_key(&anc_key, anc_page, keypos);
if (!keypos)
goto err;
- next_page= _ma_kpos(key_reflength,keypos);
- if (!_ma_fetch_keypage(info, keyinfo, next_page, PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, buff, 0, &next_page_link))
+ next_page.pos= _ma_kpos(key_reflength,keypos);
+ if (_ma_fetch_keypage(&next_page, info, keyinfo, next_page.pos,
+ PAGECACHE_LOCK_WRITE, DFLT_INIT_HITS, info->buff, 0))
goto err;
- buff_length= _ma_get_page_used(share, buff);
- endpos= buff + buff_length;
- DBUG_DUMP("prev",buff,buff_length);
+ buff_length= next_page.size;
+ endpos= next_page.buff + buff_length;
+ DBUG_DUMP("prev", next_page.buff, next_page.size);
/* find keys to make a big key-page */
bmove(next_keypos - key_reflength, leaf_buff + share->keypage_header,
@@ -1031,10 +1021,10 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (!(*keyinfo->get_key)(&anc_key, anc_page_flag, key_reflength,
&next_keypos))
goto err;
- if (!_ma_get_last_key(&leaf_key, buff, endpos))
+ if (!_ma_get_last_key(&leaf_key, &next_page, endpos))
goto err;
- /* merge pages and put parting key from anc_buff between */
+ /* merge pages and put parting key from anc_page between */
prev_key= (leaf_length == p_length ? (uchar*) 0 : leaf_key.data);
t_length=(*keyinfo->pack_key)(&anc_key, nod_flag,
(leaf_length == p_length ?
@@ -1055,16 +1045,17 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
key_inserted.move_length);
new_buff_length= buff_length + leaf_length - p_length + t_length;
- _ma_store_page_used(share, buff, new_buff_length);
- page_flag= (_ma_get_keypage_flag(share, buff) |
- _ma_get_keypage_flag(share, leaf_buff));
+ page_flag= next_page.flag | leaf_page->flag;
if (anc_key.flag & (SEARCH_USER_KEY_HAS_TRANSID |
SEARCH_PAGE_KEY_HAS_TRANSID))
page_flag|= KEYPAGE_FLAG_HAS_TRANSID;
- _ma_store_keypage_flag(share, buff, page_flag);
- /* remove key from anc_buff */
+ next_page.size= new_buff_length;
+ next_page.flag= page_flag;
+ page_store_info(share, &next_page);
+
+ /* remove key from anc_page */
if (!(s_length= remove_key(keyinfo, anc_page_flag, key_reflength, keypos,
anc_key_buff,
anc_buff+anc_length, (my_off_t *) 0,
@@ -1072,20 +1063,21 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
goto err;
new_anc_length= anc_length - s_length;
- _ma_store_page_used(share, anc_buff, new_anc_length);
+ anc_page->size= new_anc_length;
+ page_store_size(share, anc_page);
if (new_buff_length <= (uint) (keyinfo->block_length -
KEYPAGE_CHECKSUM_SIZE))
{
/* All keys fitted into one page */
- leaf_page_link->changed= 1;
- if (_ma_dispose(info, leaf_page, 0))
+ page_mark_changed(info, leaf_page);
+ if (_ma_dispose(info, leaf_page->pos, 0))
goto err;
if (share->now_transactional)
{
/* Log changes to parent page */
- if (_ma_log_delete(info, anc_page, anc_buff, key_deleted.key_pos,
+ if (_ma_log_delete(anc_page, key_deleted.key_pos,
key_deleted.changed_length, key_deleted.move_length))
goto err;
@@ -1093,19 +1085,18 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
Log changes to next page. Data for leaf page is in buff
that contains original leaf_buff, parting key and next_buff
*/
- if (_ma_log_suffix(info, next_page, buff,
- buff_length, new_buff_length))
+ if (_ma_log_suffix(&next_page, buff_length, new_buff_length))
goto err;
}
}
else
{
/*
- Balancing didn't free a page, so we have to split 'buff' into two
+ Balancing didn't free a page, so we have to split 'next_page' into two
pages
- Find key in middle of buffer (buff)
- - Pack key at half_buff into anc_buff at position of deleted key
- Note that anc_buff may overflow! (is handled by caller)
+ - Pack key at half_buff into anc_page at position of deleted key
+ Note that anc_page may overflow! (is handled by caller)
- Move everything after middlekey to 'leaf_buff'
- Shorten buff at 'endpos'
*/
@@ -1116,19 +1107,18 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
anc_pos= 0; /* First key */
else
{
- if (!_ma_get_last_key(&anc_key, anc_buff, keypos))
+ if (!_ma_get_last_key(&anc_key, anc_page, keypos))
goto err;
anc_pos= anc_key.data;
}
- if (!(endpos= _ma_find_half_pos(info, &leaf_key, nod_flag, buff,
- &half_pos)))
+ if (!(endpos= _ma_find_half_pos(&leaf_key, &next_page, &half_pos)))
goto err;
/* Correct new keypointer to leaf_page */
_ma_kpointer(info,leaf_key.data + leaf_key.data_length +
- leaf_key.ref_length, leaf_page);
+ leaf_key.ref_length, leaf_page->pos);
- /* Save key in anc_buff */
+ /* Save key in anc_page */
DBUG_DUMP("anc_buff", anc_buff, new_anc_length);
DBUG_DUMP_KEY("key_to_anc", &leaf_key);
anc_end_pos= anc_buff + new_anc_length;
@@ -1144,10 +1134,12 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
bmove(keypos,keypos-t_length,(uint) (anc_end_pos-keypos)+t_length);
(*keyinfo->store_key)(keyinfo,keypos, &anc_key_inserted);
new_anc_length+= t_length;
- _ma_store_page_used(share, anc_buff, new_anc_length);
+ anc_page->size= new_anc_length;
+ page_store_size(share, anc_page);
+
if (leaf_key.flag & (SEARCH_USER_KEY_HAS_TRANSID |
SEARCH_PAGE_KEY_HAS_TRANSID))
- _ma_mark_page_with_transid(share, anc_buff);
+ _ma_mark_page_with_transid(share, anc_page);
/* Store first key on new page */
if (nod_flag)
@@ -1159,15 +1151,19 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
t_length=(*keyinfo->pack_key)(&leaf_key, nod_flag, (uchar*) 0,
(uchar*) 0, (uchar*) 0, &key_inserted);
/* t_length will always be > 0 for a new page !*/
- tmp_length= (size_t) ((buff + new_buff_length) - half_pos);
+ tmp_length= (size_t) ((next_page.buff + new_buff_length) - half_pos);
DBUG_PRINT("info",("t_length: %d length: %d",t_length, (int) tmp_length));
bmove(leaf_buff+p_length+t_length, half_pos, tmp_length);
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length, &key_inserted);
new_leaf_length= tmp_length + t_length + p_length;
- _ma_store_page_used(share, leaf_buff, new_leaf_length);
- _ma_store_keypage_flag(share, leaf_buff, page_flag);
- new_buff_length= (uint) (endpos - buff);
- _ma_store_page_used(share, buff, new_buff_length);
+
+ leaf_page->size= new_leaf_length;
+ leaf_page->flag= page_flag;
+ page_store_info(share, leaf_page);
+
+ new_buff_length= (uint) (endpos - next_page.buff);
+ next_page.size= new_buff_length;
+ page_store_size(share, &next_page);
if (share->now_transactional)
{
@@ -1179,8 +1175,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
ma_log_add() ensures that we don't log changes that is outside of
key block size, as the REDO code can't handle that
*/
- if (_ma_log_add(info, anc_page, anc_buff, anc_length,
- keypos,
+ if (_ma_log_add(anc_page, anc_length, keypos,
anc_key_inserted.move_length +
max(anc_key_inserted.changed_length -
anc_key_inserted.move_length,
@@ -1194,8 +1189,7 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
This contains original data with new data added first
*/
DBUG_ASSERT(leaf_length <= new_leaf_length);
- if (_ma_log_prefix(info, leaf_page, leaf_buff,
- new_leaf_length - unchanged_leaf_length,
+ if (_ma_log_prefix(leaf_page, new_leaf_length - unchanged_leaf_length,
(int) (new_leaf_length - leaf_length)))
goto err;
/*
@@ -1204,20 +1198,18 @@ static int underflow(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
*/
DBUG_ASSERT(new_buff_length <= buff_length);
- if (_ma_log_suffix(info, next_page, buff,
- buff_length, new_buff_length))
+ if (_ma_log_suffix(&next_page, buff_length, new_buff_length))
goto err;
}
- leaf_page_link->changed= 1;
- if (_ma_write_keypage(info, keyinfo, leaf_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS,
- leaf_buff))
+ page_mark_changed(info, leaf_page);
+ if (_ma_write_keypage(leaf_page,
+ PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS))
goto err;
}
- next_page_link->changed= 1;
- if (_ma_write_keypage(info, keyinfo, next_page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS, buff))
+ page_mark_changed(info, &next_page);
+ if (_ma_write_keypage(&next_page,
+ PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS))
goto err;
DBUG_RETURN(new_anc_length <=
@@ -1412,24 +1404,25 @@ static uint remove_key(MARIA_KEYDEF *keyinfo, uint page_flag, uint nod_flag,
*/
-my_bool _ma_log_delete(MARIA_HA *info, my_off_t page, const uchar *buff,
- const uchar *key_pos, uint changed_length,
- uint move_length)
+my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos,
+ uint changed_length, uint move_length)
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 9 + 7], *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
- MARIA_SHARE *share= info->s;
uint translog_parts;
- uint offset= (uint) (key_pos - buff);
+ uint offset= (uint) (key_pos - ma_page->buff);
+ MARIA_HA *info= ma_page->info;
+ MARIA_SHARE *share= info->s;
+ my_off_t page;
DBUG_ENTER("_ma_log_delete");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
- (ulong) page, changed_length, move_length));
+ (ulong) ma_page->pos, changed_length, move_length));
DBUG_ASSERT(share->now_transactional && move_length);
- DBUG_ASSERT(offset + changed_length <= _ma_get_page_used(share, buff));
+ DBUG_ASSERT(offset + changed_length <= ma_page->size);
/* 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);
log_pos= log_data+ FILEID_STORE_SIZE + PAGE_STORE_SIZE;
log_pos[0]= KEY_OP_OFFSET;
@@ -1444,15 +1437,16 @@ my_bool _ma_log_delete(MARIA_HA *info, my_off_t page, const uchar *buff,
int2store(log_pos+1, changed_length);
log_pos+= 3;
translog_parts= 2;
- log_array[TRANSLOG_INTERNAL_PARTS + 1].str= buff + offset;
+ log_array[TRANSLOG_INTERNAL_PARTS + 1].str= ma_page->buff + offset;
log_array[TRANSLOG_INTERNAL_PARTS + 1].length= changed_length;
}
#ifdef EXTRA_DEBUG_KEY_CHANGES
{
- int page_length= _ma_get_page_used(share, 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[0]= KEY_OP_CHECK;
int2store(log_pos+1, page_length);
int4store(log_pos+3, crc);
@@ -1483,8 +1477,8 @@ my_bool _ma_log_delete(MARIA_HA *info, my_off_t page, const uchar *buff,
Logging of undos
****************************************************************************/
-int _ma_write_undo_key_delete(MARIA_HA *info, const MARIA_KEY *key,
- my_off_t new_root, LSN *res_lsn)
+my_bool _ma_write_undo_key_delete(MARIA_HA *info, const MARIA_KEY *key,
+ my_off_t new_root, LSN *res_lsn)
{
MARIA_SHARE *share= info->s;
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE +
diff --git a/storage/maria/ma_ft_update.c b/storage/maria/ma_ft_update.c
index 567eb4dec13..05150070c0c 100644
--- a/storage/maria/ma_ft_update.c
+++ b/storage/maria/ma_ft_update.c
@@ -220,8 +220,11 @@ int _ma_ft_update(MARIA_HA *info, uint keynr, uchar *keybuf,
{
MARIA_KEY key;
_ma_ft_make_key(info, &key, keynr, keybuf, old_word, pos);
- if ((error= _ma_ck_delete(info, &key)))
+ if (_ma_ck_delete(info, &key))
+ {
+ error= -1;
goto err;
+ }
}
if (cmp > 0 || cmp2)
{
@@ -317,6 +320,7 @@ uint _ma_ft_convert_to_ft2(MARIA_HA *info, MARIA_KEY *key)
uint length, key_length;
MARIA_PINNED_PAGE tmp_page_link, *page_link= &tmp_page_link;
MARIA_KEY tmp_key;
+ MARIA_PAGE page;
DBUG_ENTER("_ma_ft_convert_to_ft2");
/* we'll generate one pageful at once, and insert the rest one-by-one */
@@ -344,9 +348,11 @@ uint _ma_ft_convert_to_ft2(MARIA_HA *info, MARIA_KEY *key)
@todo RECOVERY BUG this is not logged yet. Ok as this code is never
called, but soon it will be.
*/
- if ((root= _ma_new(info, DFLT_INIT_HITS, &page_link)) == HA_OFFSET_ERROR ||
- _ma_write_keypage(info, keyinfo, root, page_link->write_lock,
- DFLT_INIT_HITS, info->buff))
+ if ((root= _ma_new(info, DFLT_INIT_HITS, &page_link)) == HA_OFFSET_ERROR)
+ DBUG_RETURN(-1);
+
+ _ma_page_setup(&page, info, keyinfo, root, info->buff);
+ if (_ma_write_keypage(&page, page_link->write_lock, DFLT_INIT_HITS))
DBUG_RETURN(-1);
/* inserting the rest of key values */
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index 3787e69f4a0..a79d5d2c950 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -295,19 +295,21 @@ my_bool write_hook_for_undo_key_delete(enum translog_record_type type,
Write log entry for page that has got data added or deleted at start of page
*/
-my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
- uchar *buff, uint changed_length,
+my_bool _ma_log_prefix(MARIA_PAGE *ma_page, uint changed_length,
int move_length)
{
uint translog_parts;
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 7 + 7 + 2], *log_pos;
+ uchar *buff= ma_page->buff;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
+ pgcache_page_no_t page;
+ MARIA_HA *info= ma_page->info;
DBUG_ENTER("_ma_log_prefix");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
- (ulong) page, changed_length, move_length));
+ (ulong) ma_page->pos, changed_length, move_length));
- page/= info->s->block_size;
+ page= ma_page->pos / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
@@ -357,7 +359,7 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
#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);
log_pos[0]= KEY_OP_CHECK;
@@ -386,19 +388,21 @@ my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
Write log entry for page that has got data added or deleted at end of page
*/
-my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page,
- uchar *buff, uint org_length, uint new_length)
+my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length)
{
LSN lsn;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 10 + 7 + 2], *log_pos;
+ uchar *buff= ma_page->buff;
int diff;
uint translog_parts, extra_length;
+ MARIA_HA *info= ma_page->info;
+ pgcache_page_no_t page;
DBUG_ENTER("_ma_log_suffix");
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));
- page/= info->s->block_size;
+ page= ma_page->pos / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
@@ -459,8 +463,8 @@ my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page,
/**
@brief Log that a key was added to the page
- @param buff Page buffer
- @param buff_length Original length of buff (before key was added)
+ @param ma_page Changed page
+ @param org_page_length Length of data in page before key was added
@note
If handle_overflow is set, then we have to protect against
@@ -469,22 +473,25 @@ my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page,
in memory temporary contains more data than block_size
*/
-my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff,
- uint buff_length, uchar *key_pos,
+my_bool _ma_log_add(MARIA_PAGE *ma_page,
+ uint org_page_length, uchar *key_pos,
uint changed_length, int move_length,
my_bool handle_overflow __attribute__ ((unused)))
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 3 + 3 + 3 + 7 + 2];
uchar *log_pos;
+ uchar *buff= ma_page->buff;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 3];
+ MARIA_HA *info= ma_page->info;
uint offset= (uint) (key_pos - buff);
uint page_length= info->s->block_size - KEYPAGE_CHECKSUM_SIZE;
uint translog_parts;
+ pgcache_page_no_t page_pos;
DBUG_ENTER("_ma_log_add");
DBUG_PRINT("enter", ("page: %lu org_page_length: %u changed_length: %u "
"move_length: %d",
- (ulong) page, buff_length, changed_length,
+ (ulong) ma_page->pos, org_page_length, changed_length,
move_length));
DBUG_ASSERT(info->s->now_transactional);
@@ -493,20 +500,20 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff,
to do the page
*/
log_pos= log_data + FILEID_STORE_SIZE;
- page/= info->s->block_size;
- page_store(log_pos, page);
+ page_pos= ma_page->pos / info->s->block_size;
+ page_store(log_pos, page_pos);
log_pos+= PAGE_STORE_SIZE;
/* Store keypage_flag */
*log_pos++= KEY_OP_SET_PAGEFLAG;
*log_pos++= buff[KEYPAGE_TRANSFLAG_OFFSET];
- if (buff_length + move_length > page_length)
+ if (org_page_length + move_length > page_length)
{
/*
Overflow. Cut either key or data from page end so that key fits
The code that splits the too big page will ignore logging any
- data over page_length
+ data over org_page_length
*/
DBUG_ASSERT(handle_overflow);
if (offset + changed_length > page_length)
@@ -516,15 +523,15 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff,
}
else
{
- uint diff= buff_length + move_length - page_length;
+ uint diff= org_page_length + move_length - page_length;
log_pos[0]= KEY_OP_DEL_SUFFIX;
int2store(log_pos+1, diff);
log_pos+= 3;
- buff_length= page_length - move_length;
+ org_page_length= page_length - move_length;
}
}
- if (offset == buff_length)
+ if (offset == org_page_length)
log_pos[0]= KEY_OP_ADD_SUFFIX;
else
{
@@ -553,8 +560,8 @@ my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff,
{
MARIA_SHARE *share= info->s;
ha_checksum crc;
- uint save_page_length= _ma_get_page_used(share, buff);
- uint new_length= buff_length + move_length;
+ uint save_page_length= ma_page->size;
+ uint new_length= org_page_length + move_length;
_ma_store_page_used(share, buff, new_length);
crc= my_checksum(0, buff + LSN_STORE_SIZE, new_length - LSN_STORE_SIZE);
log_pos[0]= KEY_OP_CHECK;
@@ -822,22 +829,22 @@ uint _ma_apply_redo_index(MARIA_HA *info,
LSN lsn, const uchar *header, uint head_length)
{
MARIA_SHARE *share= info->s;
- pgcache_page_no_t page= page_korr(header);
+ pgcache_page_no_t page_pos= page_korr(header);
MARIA_PINNED_PAGE page_link;
uchar *buff;
const uchar *header_end= header + head_length;
- uint page_offset= 0;
- uint nod_flag, page_length, keypage_header;
+ uint page_offset= 0, org_page_length;
+ uint nod_flag, page_length, keypage_header, keynr;
int result;
- uint org_page_length;
+ MARIA_PAGE page;
DBUG_ENTER("_ma_apply_redo_index");
- DBUG_PRINT("enter", ("page: %lu", (ulong) page));
+ DBUG_PRINT("enter", ("page: %lu", (ulong) page_pos));
/* Set header to point at key data */
header+= PAGE_STORE_SIZE;
if (!(buff= pagecache_read(share->pagecache, &share->kfile,
- page, 0, 0,
+ page_pos, 0, 0,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
{
@@ -852,9 +859,12 @@ uint _ma_apply_redo_index(MARIA_HA *info,
goto err;
}
- _ma_get_used_and_nod(share, buff, page_length, nod_flag);
+ keynr= _ma_get_keynr(share, buff);
+ _ma_page_setup(&page, info, share->keyinfo + keynr, page_pos, buff);
+ nod_flag= page.node;
+ org_page_length= page_length= page.size;
+
keypage_header= share->keypage_header;
- org_page_length= page_length;
DBUG_PRINT("redo", ("page_length: %u", page_length));
/* Apply modifications to page */
@@ -1007,16 +1017,15 @@ uint _ma_apply_redo_index(MARIA_HA *info,
case KEY_OP_COMPACT_PAGE:
{
TrID transid= transid_korr(header);
- uint keynr= _ma_get_keynr(share, buff);
DBUG_PRINT("redo", ("key_op_compact_page"));
header+= TRANSID_SIZE;
- if (_ma_compact_keypage(info, share->keyinfo + keynr, (my_off_t) 0,
- buff, transid))
+ if (_ma_compact_keypage(&page, transid))
{
result= 1;
goto err;
}
+ page_length= page.size;
}
case KEY_OP_NONE:
default:
@@ -1028,6 +1037,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
DBUG_ASSERT(header == header_end);
/* Write modified page */
+ page.size= page_length;
_ma_store_page_used(share, buff, page_length);
/*
diff --git a/storage/maria/ma_key_recover.h b/storage/maria/ma_key_recover.h
index 2366d53f143..4b4198f3008 100644
--- a/storage/maria/ma_key_recover.h
+++ b/storage/maria/ma_key_recover.h
@@ -49,8 +49,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
int _ma_write_undo_key_insert(MARIA_HA *info, const MARIA_KEY *key,
my_off_t *root, my_off_t new_root,
LSN *res_lsn);
-int _ma_write_undo_key_delete(MARIA_HA *info, const MARIA_KEY *key,
- my_off_t new_root, LSN *res_lsn);
+my_bool _ma_write_undo_key_delete(MARIA_HA *info, const MARIA_KEY *key,
+ my_off_t new_root, LSN *res_lsn);
my_bool write_hook_for_clr_end(enum translog_record_type type,
TRN *trn, MARIA_HA *tbl_info, LSN *lsn,
void *hook_arg);
@@ -65,23 +65,16 @@ extern my_bool write_hook_for_undo_key_delete(enum translog_record_type type,
LSN *lsn, void *hook_arg);
void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn);
-my_bool _ma_log_prefix(MARIA_HA *info, my_off_t page,
- uchar *buff, uint changed_length,
- int move_length);
-my_bool _ma_log_suffix(MARIA_HA *info, my_off_t page,
- uchar *buff, uint org_length,
+my_bool _ma_log_prefix(MARIA_PAGE *page, uint changed_length, int move_length);
+my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length,
uint new_length);
-my_bool _ma_log_add(MARIA_HA *info, my_off_t page, uchar *buff,
- uint buff_length, uchar *key_pos,
+my_bool _ma_log_add(MARIA_PAGE *page, uint buff_length, uchar *key_pos,
uint changed_length, int move_length,
my_bool handle_overflow);
-my_bool _ma_log_delete(MARIA_HA *info, my_off_t page, const uchar *buff,
- const uchar *key_pos, uint changed_length,
- uint move_length);
-my_bool _ma_log_change(MARIA_HA *info, my_off_t page, const uchar *buff,
- const uchar *key_pos, uint length);
-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_delete(MARIA_PAGE *page, const uchar *key_pos,
+ uint changed_length, uint move_length);
+my_bool _ma_log_change(MARIA_PAGE *page, const uchar *key_pos, uint length);
+my_bool _ma_log_new(MARIA_PAGE *page, my_bool root_page);
uint _ma_apply_redo_index_new_page(MARIA_HA *info, LSN lsn,
const uchar *header, uint length);
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index afe40aad399..8d91880eed6 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -44,14 +44,50 @@
#include "trnman.h"
#include "ma_key_recover.h"
-/* Fetch a key-page in memory */
-
-uchar *_ma_fetch_keypage(register MARIA_HA *info,
- const MARIA_KEYDEF *keyinfo __attribute__ ((unused)),
- my_off_t pos, enum pagecache_page_lock lock,
- int level, uchar *buff,
- int return_buffer __attribute__ ((unused)),
- MARIA_PINNED_PAGE **page_link_res)
+/**
+ Fill MARIA_PAGE structure for usage with _ma_write_keypage
+*/
+
+void _ma_page_setup(MARIA_PAGE *page, MARIA_HA *info,
+ const MARIA_KEYDEF *keyinfo, my_off_t pos,
+ uchar *buff)
+{
+ MARIA_SHARE *share= info->s;
+
+ page->info= info;
+ page->keyinfo= keyinfo;
+ page->buff= buff;
+ page->pos= pos;
+ page->size= _ma_get_page_used(share, buff);
+ page->flag= _ma_get_keypage_flag(share, buff);
+ page->node= ((page->flag & KEYPAGE_FLAG_ISNOD) ?
+ share->base.key_reflength : 0);
+}
+
+
+/**
+ Fetch a key-page in memory
+
+ @fn _ma_fetch_keypage()
+ @param page Fill this struct with information about read page
+ @param info Maria handler
+ @param keyinfo Key definition for used key
+ @param pos Position for page (in bytes)
+ @param lock Lock type for page
+ @param level Importance of page; Priority for page cache
+ @param buff Buffer to use for page
+ @param return_buffer Set to 1 if we want to force useage of buff
+
+ @return
+ @retval 0 ok
+ @retval 1 error
+*/
+
+my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
+ const MARIA_KEYDEF *keyinfo,
+ my_off_t pos, enum pagecache_page_lock lock,
+ int level, uchar *buff,
+ my_bool return_buffer __attribute__ ((unused)))
{
uchar *tmp;
MARIA_PINNED_PAGE page_link;
@@ -70,9 +106,7 @@ uchar *_ma_fetch_keypage(register MARIA_HA *info,
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
page_link.changed= 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
- *page_link_res= dynamic_element(&info->pinned_pages,
- info->pinned_pages.elements-1,
- MARIA_PINNED_PAGE *);
+ page->link_offset= info->pinned_pages.elements-1;
}
if (tmp == info->buff)
@@ -83,12 +117,27 @@ uchar *_ma_fetch_keypage(register MARIA_HA *info,
info->last_keypage=HA_OFFSET_ERROR;
maria_print_error(share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
info->last_keypage= pos;
+
+ /*
+ Setup page structure to make pages easy to use
+ This is same as page_fill_info, but here inlined as this si used
+ so often.
+ */
+ page->info= info;
+ page->keyinfo= keyinfo;
+ page->buff= tmp;
+ page->pos= pos;
+ page->size= _ma_get_page_used(share, tmp);
+ page->flag= _ma_get_keypage_flag(share, tmp);
+ page->node= ((page->flag & KEYPAGE_FLAG_ISNOD) ?
+ share->base.key_reflength : 0);
+
#ifdef EXTRA_DEBUG
{
- uint page_size= _ma_get_page_used(share, tmp);
+ uint page_size= page->size;
if (page_size < 4 || page_size > block_size ||
_ma_get_keynr(share, tmp) != keyinfo->key_nr)
{
@@ -103,55 +152,58 @@ uchar *_ma_fetch_keypage(register MARIA_HA *info,
}
}
#endif
- DBUG_RETURN(tmp);
+ DBUG_RETURN(0);
} /* _ma_fetch_keypage */
/* Write a key-page on disk */
-int _ma_write_keypage(register MARIA_HA *info,
- register const MARIA_KEYDEF *keyinfo
- __attribute__((unused)),
- my_off_t pos, enum pagecache_page_lock lock,
- int level, uchar *buff)
+my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock,
+ int level)
{
- MARIA_SHARE *share= info->s;
- MARIA_PINNED_PAGE page_link;
+ MARIA_SHARE *share= page->info->s;
uint block_size= share->block_size;
- int res;
+ uchar *buff= page->buff;
+ my_bool res;
+ MARIA_PINNED_PAGE page_link;
DBUG_ENTER("_ma_write_keypage");
#ifdef EXTRA_DEBUG /* Safety check */
{
- uint page_length, nod;
- _ma_get_used_and_nod(share, buff, page_length, nod);
- if (pos < share->base.keystart ||
- pos+block_size > share->state.state.key_file_length ||
- (pos & (maria_block_size-1)))
+ uint page_length, nod_flag;
+ page_length= _ma_get_page_used(share, buff);
+ nod_flag= _ma_test_if_nod(share, buff);
+
+ DBUG_ASSERT(page->size == page_length);
+ DBUG_ASSERT(page->flag == _ma_get_keypage_flag(share, buff));
+
+ if (page->pos < share->base.keystart ||
+ page->pos+block_size > share->state.state.key_file_length ||
+ (page->pos & (maria_block_size-1)))
{
DBUG_PRINT("error",("Trying to write inside key status region: "
"key_start: %lu length: %lu page: %lu",
(long) share->base.keystart,
(long) share->state.state.key_file_length,
- (long) pos));
+ (long) page->pos));
my_errno=EINVAL;
DBUG_ASSERT(0);
- DBUG_RETURN((-1));
+ DBUG_RETURN(1);
}
- DBUG_PRINT("page",("write page at: %lu",(long) pos));
+ DBUG_PRINT("page",("write page at: %lu",(long) page->pos));
DBUG_DUMP("buff", buff, page_length);
- DBUG_ASSERT(page_length >= share->keypage_header + nod +
- keyinfo->minlength || maria_in_recovery);
+ DBUG_ASSERT(page_length >= share->keypage_header + nod_flag +
+ page->keyinfo->minlength || maria_in_recovery);
}
#endif
/* Verify that keynr is correct */
- DBUG_ASSERT(_ma_get_keynr(share, buff) == keyinfo->key_nr);
+ DBUG_ASSERT(_ma_get_keynr(share, buff) == page->keyinfo->key_nr);
#if defined(EXTRA_DEBUG) && defined(HAVE_purify) && defined(NOT_ANYMORE)
{
/* This is here to catch uninitialized bytes */
- uint length= _ma_get_page_used(share, buff);
+ uint length= page->size;
ulong crc= my_checksum(0, buff, length);
int4store(buff + block_size - KEYPAGE_CHECKSUM_SIZE, crc);
}
@@ -159,15 +211,15 @@ int _ma_write_keypage(register MARIA_HA *info,
#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
{
- uint length= _ma_get_page_used(share, buff);
+ uint length= page->size;
DBUG_ASSERT(length <= block_size - KEYPAGE_CHECKSUM_SIZE);
bzero(buff + length, block_size - length);
}
#endif
- DBUG_ASSERT(share->pagecache->block_size == block_size);
res= pagecache_write(share->pagecache,
- &share->kfile, (pgcache_page_no_t) (pos / block_size),
+ &share->kfile,
+ (pgcache_page_no_t) (page->pos / block_size),
level, buff, share->page_type,
lock,
lock == PAGECACHE_LOCK_LEFT_WRITELOCKED ?
@@ -182,7 +234,7 @@ int _ma_write_keypage(register MARIA_HA *info,
/* It was not locked before, we have to unlock it when we unpin pages */
page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
page_link.changed= 1;
- push_dynamic(&info->pinned_pages, (void*) &page_link);
+ push_dynamic(&page->info->pinned_pages, (void*) &page_link);
}
DBUG_RETURN(res);
}
@@ -441,26 +493,26 @@ static my_bool _ma_log_compact_keypage(MARIA_HA *info, my_off_t page,
®retval 1 Error; my_errno contains the error
*/
-my_bool _ma_compact_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t page_pos, uchar *page, TrID min_read_from)
+my_bool _ma_compact_keypage(MARIA_PAGE *ma_page, TrID min_read_from)
{
- MARIA_SHARE *share= keyinfo->share;
+ MARIA_HA *info= ma_page->info;
+ MARIA_SHARE *share= info->s;
MARIA_KEY key;
- uchar *start_of_page, *endpos, *start_of_empty_space;
+ uchar *page, *endpos, *start_of_empty_space;
uint page_flag, nod_flag, saved_space;
my_bool page_has_transid;
DBUG_ENTER("_ma_compact_keypage");
- page_flag= _ma_get_keypage_flag(share, page);
+ page_flag= ma_page->flag;
if (!(page_flag & KEYPAGE_FLAG_HAS_TRANSID))
DBUG_RETURN(0); /* No transaction id on page */
- nod_flag= _ma_test_if_nod(share, page);
- endpos= page + _ma_get_page_used(share, page);
+ nod_flag= ma_page->node;
+ page= ma_page->buff;
+ endpos= page + ma_page->size;
key.data= info->lastkey_buff;
- key.keyinfo= keyinfo;
+ key.keyinfo= (MARIA_KEYDEF*) ma_page->keyinfo;
- start_of_page= page;
page_has_transid= 0;
page+= share->keypage_header + nod_flag;
key.data[0]= 0; /* safety */
@@ -468,7 +520,7 @@ my_bool _ma_compact_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
saved_space= 0;
do
{
- if (!(page= (*keyinfo->skip_key)(&key, 0, 0, page)))
+ if (!(page= (*ma_page->keyinfo->skip_key)(&key, 0, 0, page)))
{
DBUG_PRINT("error",("Couldn't find last key: page: 0x%lx",
(long) page));
@@ -514,26 +566,25 @@ my_bool _ma_compact_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
This is always true if any transid was removed
*/
uint copy_length= (uint) (endpos - start_of_empty_space) - saved_space;
- uint page_length;
if (copy_length)
memmove(start_of_empty_space, start_of_empty_space + saved_space,
copy_length);
- page_length= (uint) (start_of_empty_space + copy_length - start_of_page);
- _ma_store_page_used(share, start_of_page, page_length);
+ ma_page->size= (uint) (start_of_empty_space + copy_length - ma_page->buff);
+ page_store_size(share, ma_page);
}
if (!page_has_transid)
{
- page_flag&= ~KEYPAGE_FLAG_HAS_TRANSID;
- _ma_store_keypage_flag(share, start_of_page, page_flag);
+ ma_page->flag&= ~KEYPAGE_FLAG_HAS_TRANSID;
+ _ma_store_keypage_flag(share, ma_page->buff, ma_page->flag);
/* Clear packed transid (in case of zerofill) */
- bzero(start_of_page + LSN_STORE_SIZE, TRANSID_SIZE);
+ bzero(ma_page->buff + LSN_STORE_SIZE, TRANSID_SIZE);
}
if (share->now_transactional)
{
- if (_ma_log_compact_keypage(info, page_pos, min_read_from))
+ if (_ma_log_compact_keypage(info, ma_page->pos, min_read_from))
DBUG_RETURN(1);
}
DBUG_RETURN(0);
diff --git a/storage/maria/ma_range.c b/storage/maria/ma_range.c
index 38f1d8aa44d..5dc4e3a9959 100644
--- a/storage/maria/ma_range.c
+++ b/storage/maria/ma_range.c
@@ -24,7 +24,7 @@
static ha_rows _ma_record_pos(MARIA_HA *,const uchar *, key_part_map,
enum ha_rkey_function);
static double _ma_search_pos(MARIA_HA *, MARIA_KEY *, uint32, my_off_t);
-static uint _ma_keynr(MARIA_HA *, MARIA_KEYDEF *, uchar *, uchar *, uint *);
+static uint _ma_keynr(MARIA_PAGE *page, uchar *keypos, uint *ret_max_key);
/**
@@ -205,25 +205,25 @@ static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
uint32 nextflag, my_off_t pos)
{
int flag;
- uint nod_flag,keynr,max_keynr;
+ uint keynr, max_keynr;
my_bool after_key;
- uchar *keypos, *buff;
+ uchar *keypos;
double offset;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ MARIA_PAGE page;
DBUG_ENTER("_ma_search_pos");
LINT_INIT(max_keynr);
if (pos == HA_OFFSET_ERROR)
DBUG_RETURN(0.5);
- if (!(buff= _ma_fetch_keypage(info,keyinfo, pos,
- PAGECACHE_LOCK_LEFT_UNLOCKED, DFLT_INIT_HITS,
- info->buff, 1, 0)))
+ if (_ma_fetch_keypage(&page, info, keyinfo, pos,
+ PAGECACHE_LOCK_LEFT_UNLOCKED, DFLT_INIT_HITS,
+ info->buff, 1))
goto err;
- flag= (*keyinfo->bin_search)(key, buff, nextflag, &keypos,
+ flag= (*keyinfo->bin_search)(key, &page, nextflag, &keypos,
info->lastkey_buff, &after_key);
- nod_flag=_ma_test_if_nod(info->s, buff);
- keynr= _ma_keynr(info,keyinfo,buff,keypos,&max_keynr);
+ keynr= _ma_keynr(&page, keypos, &max_keynr);
if (flag)
{
@@ -234,10 +234,10 @@ static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
Try to find a smaller, better matching key.
Matches keynr + [0-1]
*/
- if (flag > 0 && ! nod_flag)
+ if (flag > 0 && ! page.node)
offset= 1.0;
else if ((offset= _ma_search_pos(info, key, nextflag,
- _ma_kpos(nod_flag,keypos))) < 0)
+ _ma_kpos(page.node,keypos))) < 0)
DBUG_RETURN(offset);
}
else
@@ -247,7 +247,7 @@ static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
Matches keynr+1
*/
offset=1.0; /* Matches keynr+1 */
- if ((nextflag & SEARCH_FIND) && nod_flag &&
+ if ((nextflag & SEARCH_FIND) && page.node &&
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
(nextflag & (SEARCH_PREFIX | SEARCH_NO_FIND | SEARCH_LAST |
SEARCH_PART_KEY))))
@@ -257,12 +257,12 @@ static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
Matches keynr + [0-1]
*/
if ((offset= _ma_search_pos(info, key, SEARCH_FIND,
- _ma_kpos(nod_flag,keypos))) < 0)
+ _ma_kpos(page.node,keypos))) < 0)
DBUG_RETURN(offset); /* Read error */
}
}
DBUG_PRINT("info",("keynr: %d offset: %g max_keynr: %d nod: %d flag: %d",
- keynr,offset,max_keynr,nod_flag,flag));
+ keynr,offset,max_keynr,page.node,flag));
DBUG_RETURN((keynr+offset)/(max_keynr+1));
err:
DBUG_PRINT("exit",("Error: %d",my_errno));
@@ -272,40 +272,39 @@ err:
/* Get keynummer of current key and max number of keys in nod */
-static uint _ma_keynr(MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- uchar *page, uchar *keypos, uint *ret_max_key)
+static uint _ma_keynr(MARIA_PAGE *page, uchar *keypos, uint *ret_max_key)
{
- uint page_flag, nod_flag, used_length, keynr, max_key;
- uchar t_buff[MARIA_MAX_KEY_BUFF],*end;
+ uint page_flag, nod_flag, keynr, max_key;
+ uchar t_buff[MARIA_MAX_KEY_BUFF], *pos, *end;
+ const MARIA_KEYDEF *keyinfo= page->keyinfo;
MARIA_KEY key;
- page_flag= _ma_get_keypage_flag(info->s, page);
- _ma_get_used_and_nod_with_flag(info->s, page_flag, page, used_length,
- nod_flag);
- end= page+ used_length;
- page+= info->s->keypage_header + nod_flag;
+ page_flag= page->flag;
+ nod_flag= page->node;
+ pos= page->buff + page->info->s->keypage_header + nod_flag;
+ end= page->buff + page->size;
if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)) &&
! (page_flag & KEYPAGE_FLAG_HAS_TRANSID))
{
- *ret_max_key= (uint) (end-page)/(keyinfo->keylength+nod_flag);
- return (uint) (keypos-page)/(keyinfo->keylength+nod_flag);
+ *ret_max_key= (uint) (end - pos)/(keyinfo->keylength+nod_flag);
+ return (uint) (keypos - pos)/(keyinfo->keylength+nod_flag);
}
max_key=keynr=0;
t_buff[0]=0; /* Safety */
key.data= t_buff;
- key.keyinfo= keyinfo;
+ key.keyinfo= (MARIA_KEYDEF*) keyinfo;
- while (page < end)
+ while (pos < end)
{
- if (!(page= (*keyinfo->skip_key)(&key, page_flag, nod_flag, page)))
+ if (!(pos= (*keyinfo->skip_key)(&key, page_flag, nod_flag, pos)))
{
DBUG_ASSERT(0);
return 0; /* Error */
}
max_key++;
- if (page == keypos)
+ if (pos == keypos)
keynr= max_key;
}
*ret_max_key=max_key;
diff --git a/storage/maria/ma_rt_index.c b/storage/maria/ma_rt_index.c
index ccdddf5906d..7ae3344ef9b 100644
--- a/storage/maria/ma_rt_index.c
+++ b/storage/maria/ma_rt_index.c
@@ -36,8 +36,8 @@ typedef struct st_page_level
typedef struct st_page_list
{
- ulong n_pages;
- ulong m_pages;
+ uint n_pages;
+ uint m_pages;
stPageLevel *pages;
} stPageList;
@@ -56,7 +56,8 @@ typedef struct st_page_list
static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
uint32 search_flag,
- uint nod_cmp_flag, my_off_t page, int level)
+ uint nod_cmp_flag, my_off_t page_pos,
+ int level)
{
MARIA_SHARE *share= info->s;
uint nod_flag;
@@ -64,16 +65,18 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
uchar *page_buf, *k, *last;
int key_data_length;
uint *saved_key= (uint*) (info->maria_rtree_recursion_state) + level;
+ MARIA_PAGE page;
if (!(page_buf= (uchar*) my_alloca((uint) keyinfo->block_length)))
{
my_errno= HA_ERR_OUT_OF_MEM;
return -1;
}
- if (!_ma_fetch_keypage(info, keyinfo, page, PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, page_buf, 0, 0))
- goto err1;
- nod_flag= _ma_test_if_nod(share, page_buf);
+ if (_ma_fetch_keypage(&page, info, keyinfo, page_pos,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, page_buf, 0))
+ goto err;
+ nod_flag= page.node;
key_data_length= keyinfo->keylength - share->base.rec_reflength;
@@ -85,7 +88,7 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
{
k= rt_PAGE_FIRST_KEY(share, page_buf, nod_flag);
}
- last= rt_PAGE_END(share, page_buf);
+ last= rt_PAGE_END(&page);
for (; k < last; k= rt_PAGE_NEXT_KEY(share, k, key_data_length, nod_flag))
{
@@ -109,7 +112,7 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
break;
default: /* error */
case -1:
- goto err1;
+ goto err;
}
}
}
@@ -166,7 +169,7 @@ ok:
my_afree((uchar*)page_buf);
return res;
-err1:
+err:
my_afree((uchar*)page_buf);
info->cur_row.lastpos= HA_OFFSET_ERROR;
return -1;
@@ -302,26 +305,28 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint32 search_flag)
*/
static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- uint key_length, my_off_t page, int level)
+ uint key_length, my_off_t page_pos, int level)
{
MARIA_SHARE *share= info->s;
uchar *page_buf, *last, *k;
uint nod_flag, key_data_length;
int res;
uint *saved_key= (uint*) (info->maria_rtree_recursion_state) + level;
+ MARIA_PAGE page;
if (!(page_buf= (uchar*) my_alloca((uint) keyinfo->block_length)))
return -1;
- if (!_ma_fetch_keypage(info, keyinfo, page, PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, page_buf, 0, 0))
- goto err1;
- nod_flag= _ma_test_if_nod(share, page_buf);
+ if (_ma_fetch_keypage(&page, info, keyinfo, page_pos,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, page_buf, 0))
+ goto err;
+ nod_flag= page.node;
key_data_length= keyinfo->keylength - share->base.rec_reflength;
if (info->maria_rtree_recursion_depth >= level)
{
- k= page_buf + *saved_key;
+ k= page.buff + *saved_key;
if (!nod_flag)
{
/* Only leaf pages contain data references. */
@@ -331,9 +336,9 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
}
else
{
- k= rt_PAGE_FIRST_KEY(share, page_buf, nod_flag);
+ k= rt_PAGE_FIRST_KEY(share, page.buff, nod_flag);
}
- last= rt_PAGE_END(share, page_buf);
+ last= rt_PAGE_END(&page);
for (; k < last; k= rt_PAGE_NEXT_KEY(share, k, key_data_length, nod_flag))
{
@@ -344,14 +349,14 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_kpos(nod_flag, k), level + 1)))
{
case 0: /* found - exit from recursion */
- *saved_key= k - page_buf;
+ *saved_key= k - page.buff;
goto ok;
case 1: /* not found - continue searching */
info->maria_rtree_recursion_depth= level;
break;
default:
case -1: /* error */
- goto err1;
+ goto err;
}
}
else
@@ -376,14 +381,14 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
info->last_key.data_length + info->last_key.ref_length);
info->maria_rtree_recursion_depth= level;
- *saved_key= k - page_buf;
+ *saved_key= k - page.buff;
if (after_key < last)
{
uchar *keyread_buff= info->keyread_buff;
info->last_rtree_keypos= saved_key;
- memcpy(keyread_buff, page_buf, keyinfo->block_length);
- info->int_maxpos= rt_PAGE_END(share, keyread_buff);
+ memcpy(keyread_buff, page.buff, page.size);
+ info->int_maxpos= keyread_buff + page.size;
info->keyread_buff_used= 0;
}
else
@@ -403,7 +408,7 @@ ok:
my_afree((uchar*)page_buf);
return res;
-err1:
+err:
my_afree((uchar*)page_buf);
info->cur_row.lastpos= HA_OFFSET_ERROR;
return -1;
@@ -497,18 +502,18 @@ int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length)
Returns a pointer inside the page_buf buffer.
*/
#ifdef PICK_BY_PERIMETER
-static const uchar *maria_rtree_pick_key(const MARIA_HA *info,
- const MARIA_KEY *key,
- const uchar *page_buf,
- uint nod_flag)
+static const uchar *maria_rtree_pick_key(const MARIA_KEY *key,
+ const MARIA_PAGE *page)
{
double increase;
double best_incr;
double perimeter;
double best_perimeter;
uchar *best_key= NULL;
- uchar *k= rt_PAGE_FIRST_KEY(page_buf, nod_flag);
- uchar *last= rt_PAGE_END(info, page_buf);
+ const MARIA_HA *info= page->info;
+
+ uchar *k= rt_PAGE_FIRST_KEY(info->s, page->buf, page->node);
+ uchar *last= rt_PAGE_END(info, page);
LINT_INIT(best_perimeter);
LINT_INIT(best_key);
@@ -533,24 +538,23 @@ static const uchar *maria_rtree_pick_key(const MARIA_HA *info,
#endif /*PICK_BY_PERIMETER*/
#ifdef PICK_BY_AREA
-static const uchar *maria_rtree_pick_key(const MARIA_HA *info,
- const MARIA_KEY *key,
- const uchar *page_buf,
- uint nod_flag)
+static const uchar *maria_rtree_pick_key(const MARIA_KEY *key,
+ const MARIA_PAGE *page)
{
+ const MARIA_HA *info= page->info;
MARIA_SHARE *share= info->s;
double increase;
double best_incr= DBL_MAX;
double area;
double best_area;
const uchar *best_key= NULL;
- const uchar *k= rt_PAGE_FIRST_KEY(share, page_buf, nod_flag);
- const uchar *last= rt_PAGE_END(share, page_buf);
+ const uchar *k= rt_PAGE_FIRST_KEY(share, page->buff, page->node);
+ const uchar *last= rt_PAGE_END(page);
LINT_INIT(best_area);
for (; k < last;
- k= rt_PAGE_NEXT_KEY(share, k, key->data_length, nod_flag))
+ k= rt_PAGE_NEXT_KEY(share, k, key->data_length, page->node))
{
/* The following is safe as -1.0 is an exact number */
if ((increase= maria_rtree_area_increase(key->keyinfo->seg, k, key->data,
@@ -582,16 +586,16 @@ static const uchar *maria_rtree_pick_key(const MARIA_HA *info,
*/
static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEY *key,
- my_off_t page, my_off_t *new_page,
+ my_off_t page_pos, my_off_t *new_page,
int ins_level, int level)
{
- uint nod_flag, page_link_idx;
+ uint nod_flag;
uint key_length= key->data_length;
int res;
uchar *page_buf, *k;
- MARIA_PINNED_PAGE *page_link;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ MARIA_PAGE page;
DBUG_ENTER("maria_rtree_insert_req");
if (!(page_buf= (uchar*) my_alloca((uint) keyinfo->block_length +
@@ -600,19 +604,18 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEY *key,
my_errno= HA_ERR_OUT_OF_MEM;
DBUG_RETURN(-1); /* purecov: inspected */
}
- if (!_ma_fetch_keypage(info, keyinfo, page, PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, page_buf, 0, &page_link))
- goto err1;
- page_link_idx= page_link_to_idx(info);
- nod_flag= _ma_test_if_nod(share, page_buf);
+ if (_ma_fetch_keypage(&page, info, keyinfo, page_pos, PAGECACHE_LOCK_WRITE,
+ DFLT_INIT_HITS, page_buf, 0))
+ goto err;
+ nod_flag= page.node;
DBUG_PRINT("rtree", ("page: %lu level: %d ins_level: %d nod_flag: %u",
- (ulong) page, level, ins_level, nod_flag));
+ (ulong) page.pos, level, ins_level, nod_flag));
if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */
(ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */
{
- if (!(k= (uchar *)maria_rtree_pick_key(info, key, page_buf, nod_flag)))
- goto err1;
+ if (!(k= (uchar *)maria_rtree_pick_key(key, &page)))
+ goto err;
/* k is now a pointer inside the page_buf buffer */
switch ((res= maria_rtree_insert_req(info, key,
_ma_kpos(nod_flag, k), new_page,
@@ -622,13 +625,12 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEY *key,
{
maria_rtree_combine_rect(keyinfo->seg, k, key->data, k, key_length);
if (share->now_transactional &&
- _ma_log_change(info, page, page_buf, k, key_length))
- goto err1;
- page_link_from_idx(info, page_link_idx)->changed= 1;
- if (_ma_write_keypage(info, keyinfo, page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, page_buf))
- goto err1;
+ _ma_log_change(&page, k, key_length))
+ goto err;
+ page_mark_changed(info, &page);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ goto err;
goto ok;
}
case 1: /* child was split */
@@ -648,43 +650,42 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEY *key,
/* set proper MBR for key */
if (maria_rtree_set_key_mbr(info, &k_key, _ma_kpos(nod_flag, k)))
- goto err1;
+ goto err;
if (share->now_transactional &&
- _ma_log_change(info, page, page_buf, k, key_length))
- goto err1;
+ _ma_log_change(&page, k, key_length))
+ goto err;
/* add new key for new page */
_ma_kpointer(info, new_key_buff - nod_flag, *new_page);
if (maria_rtree_set_key_mbr(info, &new_key, *new_page))
- goto err1;
- res= maria_rtree_add_key(info, &new_key, page_buf, page, new_page);
- page_link_from_idx(info, page_link_idx)->changed= 1;
- if (_ma_write_keypage(info, keyinfo, page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, page_buf))
- goto err1;
+ goto err;
+ res= maria_rtree_add_key(&new_key, &page, new_page);
+ page_mark_changed(info, &page);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ goto err;
goto ok;
}
default:
case -1: /* error */
{
- goto err1;
+ goto err;
}
}
}
else
{
- res= maria_rtree_add_key(info, key, page_buf, page, new_page);
- page_link_from_idx(info, page_link_idx)->changed= 1;
- if (_ma_write_keypage(info, keyinfo, page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, page_buf))
- goto err1;
+ res= maria_rtree_add_key(key, &page, new_page);
+ page_mark_changed(info, &page);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ goto err;
}
ok:
my_afree(page_buf);
DBUG_RETURN(res);
-err1:
+err:
res= -1; /* purecov: inspected */
goto ok; /* purecov: inspected */
}
@@ -712,13 +713,14 @@ int maria_rtree_insert_level(MARIA_HA *info, MARIA_KEY *key, int ins_level,
MARIA_KEYDEF *keyinfo= key->keyinfo;
int res;
my_off_t new_page;
- MARIA_PINNED_PAGE *page_link;
enum pagecache_page_lock write_lock;
DBUG_ENTER("maria_rtree_insert_level");
if ((old_root= share->state.key_root[keyinfo->key_nr]) == HA_OFFSET_ERROR)
{
- MARIA_PINNED_PAGE tmp_page_link;
+ MARIA_PINNED_PAGE tmp_page_link, *page_link;
+ MARIA_PAGE page;
+
page_link= &tmp_page_link;
if ((old_root= _ma_new(info, DFLT_INIT_HITS, &page_link)) ==
HA_OFFSET_ERROR)
@@ -728,15 +730,13 @@ int maria_rtree_insert_level(MARIA_HA *info, MARIA_KEY *key, int ins_level,
bzero(info->buff, share->block_size);
_ma_store_keynr(share, info->buff, keyinfo->key_nr);
_ma_store_page_used(share, info->buff, share->keypage_header);
+ _ma_page_setup(&page, info, keyinfo, old_root, info->buff);
- if (share->now_transactional &&
- _ma_log_new(info, old_root, info->buff, share->keypage_header,
- keyinfo->key_nr, 1))
+ if (share->now_transactional && _ma_log_new(&page, 1))
DBUG_RETURN(1);
- res= maria_rtree_add_key(info, key, info->buff, old_root, NULL);
- if (_ma_write_keypage(info, keyinfo, old_root, write_lock,
- DFLT_INIT_HITS, info->buff))
+ res= maria_rtree_add_key(key, &page, NULL);
+ if (_ma_write_keypage(&page, write_lock, DFLT_INIT_HITS))
DBUG_RETURN(1);
*root= old_root;
DBUG_RETURN(res);
@@ -754,8 +754,9 @@ int maria_rtree_insert_level(MARIA_HA *info, MARIA_KEY *key, int ins_level,
uchar *new_root_buf, *new_key_buff;
my_off_t new_root;
uint nod_flag= share->base.key_reflength;
- MARIA_PINNED_PAGE tmp_page_link;
+ MARIA_PINNED_PAGE tmp_page_link, *page_link;
MARIA_KEY new_key;
+ MARIA_PAGE page;
page_link= &tmp_page_link;
DBUG_PRINT("rtree", ("root was split, grow a new root"));
@@ -767,19 +768,18 @@ int maria_rtree_insert_level(MARIA_HA *info, MARIA_KEY *key, int ins_level,
}
bzero(new_root_buf, share->block_size);
- if (nod_flag)
- _ma_store_keypage_flag(share, new_root_buf, KEYPAGE_FLAG_ISNOD);
+ _ma_store_keypage_flag(share, new_root_buf, KEYPAGE_FLAG_ISNOD);
_ma_store_keynr(share, new_root_buf, keyinfo->key_nr);
_ma_store_page_used(share, new_root_buf, share->keypage_header);
if ((new_root= _ma_new(info, DFLT_INIT_HITS, &page_link)) ==
HA_OFFSET_ERROR)
- goto err1;
+ goto err;
write_lock= page_link->write_lock;
- if (share->now_transactional &&
- _ma_log_new(info, new_root, new_root_buf, share->keypage_header,
- keyinfo->key_nr, 1))
- goto err1;
+ _ma_page_setup(&page, info, keyinfo, new_root, new_root_buf);
+
+ if (share->now_transactional && _ma_log_new(&page, 1))
+ goto err;
/* Point to some free space */
new_key_buff= new_root_buf + keyinfo->block_length + nod_flag;
@@ -791,28 +791,26 @@ int maria_rtree_insert_level(MARIA_HA *info, MARIA_KEY *key, int ins_level,
_ma_kpointer(info, new_key_buff - nod_flag, old_root);
if (maria_rtree_set_key_mbr(info, &new_key, old_root))
- goto err1;
- if (maria_rtree_add_key(info, &new_key, new_root_buf, new_root, NULL)
+ goto err;
+ if (maria_rtree_add_key(&new_key, &page, NULL)
== -1)
- goto err1;
+ goto err;
_ma_kpointer(info, new_key_buff - nod_flag, new_page);
if (maria_rtree_set_key_mbr(info, &new_key, new_page))
- goto err1;
- if (maria_rtree_add_key(info, &new_key, new_root_buf, new_root, NULL)
+ goto err;
+ if (maria_rtree_add_key(&new_key, &page, NULL)
== -1)
- goto err1;
- if (_ma_write_keypage(info, keyinfo, new_root, write_lock,
- DFLT_INIT_HITS, new_root_buf))
- goto err1;
+ goto err;
+ if (_ma_write_keypage(&page, write_lock, DFLT_INIT_HITS))
+ goto err;
*root= new_root;
DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u",
- (ulong) new_root, 0,
- _ma_test_if_nod(share, new_root_buf)));
+ (ulong) new_root, 0, page.node));
- my_afree((uchar*)new_root_buf);
+ my_afree(new_root_buf);
break;
-err1:
- my_afree((uchar*)new_root_buf);
+err:
+ my_afree(new_root_buf);
DBUG_RETURN(-1); /* purecov: inspected */
}
default:
@@ -867,12 +865,12 @@ err:
Fill reinsert page buffer
RETURN
- -1 Error
+ 1 Error
0 OK
*/
-static int maria_rtree_fill_reinsert_list(stPageList *ReinsertList,
- my_off_t page, int level)
+static my_bool maria_rtree_fill_reinsert_list(stPageList *ReinsertList,
+ my_off_t page, int level)
{
DBUG_ENTER("maria_rtree_fill_reinsert_list");
DBUG_PRINT("rtree", ("page: %lu level: %d", (ulong) page, level));
@@ -881,7 +879,7 @@ static int maria_rtree_fill_reinsert_list(stPageList *ReinsertList,
ReinsertList->m_pages += REINSERT_BUFFER_INC;
if (!(ReinsertList->pages= (stPageLevel*)my_realloc((uchar*)ReinsertList->pages,
ReinsertList->m_pages * sizeof(stPageLevel), MYF(MY_ALLOW_ZERO_PTR))))
- goto err1;
+ goto err;
}
/* save page to ReinsertList */
ReinsertList->pages[ReinsertList->n_pages].offs= page;
@@ -889,8 +887,8 @@ static int maria_rtree_fill_reinsert_list(stPageList *ReinsertList,
ReinsertList->n_pages++;
DBUG_RETURN(0);
-err1:
- DBUG_RETURN(-1); /* purecov: inspected */
+err:
+ DBUG_RETURN(1); /* purecov: inspected */
}
@@ -905,16 +903,16 @@ err1:
*/
static int maria_rtree_delete_req(MARIA_HA *info, const MARIA_KEY *key,
- my_off_t page, uint *page_size,
+ my_off_t page_pos, uint *page_size,
stPageList *ReinsertList, int level)
{
ulong i;
- uint nod_flag, page_link_idx;
+ uint nod_flag;
int res;
uchar *page_buf, *last, *k;
- MARIA_PINNED_PAGE *page_link;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ MARIA_PAGE page;
DBUG_ENTER("maria_rtree_delete_req");
if (!(page_buf= (uchar*) my_alloca((uint) keyinfo->block_length)))
@@ -922,16 +920,15 @@ static int maria_rtree_delete_req(MARIA_HA *info, const MARIA_KEY *key,
my_errno= HA_ERR_OUT_OF_MEM;
DBUG_RETURN(-1); /* purecov: inspected */
}
- if (!_ma_fetch_keypage(info, keyinfo, page, PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, page_buf, 0, &page_link))
- goto err1;
- page_link_idx= page_link_to_idx(info);
- nod_flag= _ma_test_if_nod(share, page_buf);
+ if (_ma_fetch_keypage(&page, info, keyinfo, page_pos, PAGECACHE_LOCK_WRITE,
+ DFLT_INIT_HITS, page_buf, 0))
+ goto err;
+ nod_flag= page.node;
DBUG_PRINT("rtree", ("page: %lu level: %d nod_flag: %u",
- (ulong) page, level, nod_flag));
+ (ulong) page_pos, level, nod_flag));
k= rt_PAGE_FIRST_KEY(share, page_buf, nod_flag);
- last= rt_PAGE_END(share, page_buf);
+ last= rt_PAGE_END(&page);
for (i= 0;
k < last;
@@ -965,15 +962,15 @@ static int maria_rtree_delete_req(MARIA_HA *info, const MARIA_KEY *key,
if (maria_rtree_set_key_mbr(info, &tmp_key,
_ma_kpos(nod_flag, k)))
- goto err1;
+ goto err;
if (share->now_transactional &&
- _ma_log_change(info, page, page_buf, k, key->data_length))
- goto err1;
- page_link_from_idx(info, page_link_idx)->changed= 1;
- if (_ma_write_keypage(info, keyinfo, page,
+ _ma_log_change(&page, k, key->data_length))
+ goto err;
+ page_mark_changed(info, &page)
+ if (_ma_write_keypage(&page,
PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, page_buf))
- goto err1;
+ DFLT_INIT_HITS))
+ goto err;
}
else
{
@@ -986,7 +983,7 @@ static int maria_rtree_delete_req(MARIA_HA *info, const MARIA_KEY *key,
if (maria_rtree_fill_reinsert_list(ReinsertList,
_ma_kpos(nod_flag, k),
level + 1))
- goto err1;
+ goto err;
/*
Delete the key that references the block. This makes the
block disappear from the index. Hence we need to insert
@@ -995,15 +992,13 @@ static int maria_rtree_delete_req(MARIA_HA *info, const MARIA_KEY *key,
subtree. So we need to re-insert its keys on the same
level later to reintegrate the subtrees.
*/
- if (maria_rtree_delete_key(info, page_buf, k, key->data_length,
- nod_flag, page))
- goto err1;
- page_link_from_idx(info, page_link_idx)->changed= 1;
- if (_ma_write_keypage(info, keyinfo, page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, page_buf))
- goto err1;
- *page_size= _ma_get_page_used(share, page_buf);
+ if (maria_rtree_delete_key(&page, k, key->data_length))
+ goto err;
+ page_mark_changed(info, &page);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ goto err;
+ *page_size= page.size;
}
goto ok;
@@ -1014,22 +1009,20 @@ static int maria_rtree_delete_req(MARIA_HA *info, const MARIA_KEY *key,
}
case 2: /* vacuous case: last key in the leaf */
{
- if (maria_rtree_delete_key(info, page_buf, k, key->data_length,
- nod_flag, page))
- goto err1;
- page_link_from_idx(info, page_link_idx)->changed= 1;
- if (_ma_write_keypage(info, keyinfo, page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, page_buf))
- goto err1;
- *page_size= _ma_get_page_used(share, page_buf);
+ if (maria_rtree_delete_key(&page, k, key->data_length))
+ goto err;
+ page_mark_changed(info, &page);
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ goto err;
+ *page_size= page.size;
res= 0;
goto ok;
}
default: /* error */
case -1:
{
- goto err1;
+ goto err;
}
}
}
@@ -1040,26 +1033,23 @@ static int maria_rtree_delete_req(MARIA_HA *info, const MARIA_KEY *key,
if (!maria_rtree_key_cmp(keyinfo->seg, key->data, k, key->data_length,
MBR_EQUAL | MBR_DATA))
{
- page_link_from_idx(info, page_link_idx)->changed= 1;
-
- if (maria_rtree_delete_key(info, page_buf, k, key->data_length,
- nod_flag, page))
- goto err1;
- *page_size= _ma_get_page_used(share, page_buf);
+ page_mark_changed(info, &page);
+ if (maria_rtree_delete_key(&page, k, key->data_length))
+ goto err;
+ *page_size= page.size;
if (*page_size == info->s->keypage_header)
{
/* last key in the leaf */
res= 2;
- if (_ma_dispose(info, page, 0))
- goto err1;
+ if (_ma_dispose(info, page.pos, 0))
+ goto err;
}
else
{
res= 0;
- if (_ma_write_keypage(info, keyinfo, page,
- PAGECACHE_LOCK_LEFT_WRITELOCKED,
- DFLT_INIT_HITS, page_buf))
- goto err1;
+ if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
+ DFLT_INIT_HITS))
+ goto err;
}
goto ok;
}
@@ -1071,7 +1061,7 @@ ok:
my_afree((uchar*)page_buf);
DBUG_RETURN(res);
-err1:
+err:
my_afree((uchar*)page_buf);
DBUG_RETURN(-1); /* purecov: inspected */
}
@@ -1081,11 +1071,11 @@ err1:
Delete key - interface function
RETURN
- -1 Error
+ 1 Error
0 Deleted
*/
-int maria_rtree_delete(MARIA_HA *info, MARIA_KEY *key)
+my_bool maria_rtree_delete(MARIA_HA *info, MARIA_KEY *key)
{
MARIA_SHARE *share= info->s;
my_off_t new_root= share->state.key_root[key->keyinfo->key_nr];
@@ -1104,18 +1094,16 @@ int maria_rtree_delete(MARIA_HA *info, MARIA_KEY *key)
err:
_ma_fast_unlock_key_del(info);
_ma_unpin_all_pages_and_finalize_row(info, lsn);
- DBUG_RETURN(res);
+ DBUG_RETURN(res != 0);
}
-int maria_rtree_real_delete(MARIA_HA *info, MARIA_KEY *key,
- my_off_t *root)
+my_bool maria_rtree_real_delete(MARIA_HA *info, MARIA_KEY *key,
+ my_off_t *root)
{
- int res;
- uint page_size, page_link_idx;
+ uint page_size;
stPageList ReinsertList;
my_off_t old_root;
- MARIA_PINNED_PAGE *page_link, *root_page_link;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
uint key_data_length= key->data_length;
@@ -1125,7 +1113,7 @@ int maria_rtree_real_delete(MARIA_HA *info, MARIA_KEY *key,
HA_OFFSET_ERROR)
{
my_errno= HA_ERR_END_OF_FILE;
- DBUG_RETURN(-1); /* purecov: inspected */
+ DBUG_RETURN(1); /* purecov: inspected */
}
DBUG_PRINT("rtree", ("starting deletion at root page: %lu",
(ulong) old_root));
@@ -1139,8 +1127,7 @@ int maria_rtree_real_delete(MARIA_HA *info, MARIA_KEY *key,
case 2: /* empty */
{
*root= HA_OFFSET_ERROR;
- res= 0;
- goto err;
+ break;
}
case 0: /* deleted */
{
@@ -1151,102 +1138,101 @@ int maria_rtree_real_delete(MARIA_HA *info, MARIA_KEY *key,
tmp_key.data_length= key->data_length;
tmp_key.ref_length= key->ref_length;
tmp_key.flag= 0; /* Safety */
+ uchar *page_buf;
+ MARIA_PAGE page;
- for (i= 0; i < ReinsertList.n_pages; ++i)
+ if (ReinsertList.n_pages)
{
- uchar *page_buf, *k, *last;
-
if (!(page_buf= (uchar*) my_alloca((uint) keyinfo->block_length)))
{
my_errno= HA_ERR_OUT_OF_MEM;
- goto err1;
+ goto err;
}
- if (!_ma_fetch_keypage(info, keyinfo, ReinsertList.pages[i].offs,
- PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, page_buf, 0, &page_link))
- goto err1;
- page_link_idx= page_link_to_idx(info);
- nod_flag= _ma_test_if_nod(share, page_buf);
- DBUG_PRINT("rtree", ("reinserting keys from "
- "page: %lu level: %d nod_flag: %u",
- (ulong) ReinsertList.pages[i].offs,
- ReinsertList.pages[i].level, nod_flag));
-
- k= rt_PAGE_FIRST_KEY(share, page_buf, nod_flag);
- last= rt_PAGE_END(share, page_buf);
- for (; k < last; k= rt_PAGE_NEXT_KEY(share, k, key_data_length,
- nod_flag))
+
+ for (i= 0; i < ReinsertList.n_pages; ++i)
{
- tmp_key.data= k;
- if ((res=
- maria_rtree_insert_level(info, &tmp_key,
- ReinsertList.pages[i].level,
- root)) == -1)
+ uchar *k, *last;
+ if (_ma_fetch_keypage(&page, info, keyinfo, ReinsertList.pages[i].offs,
+ PAGECACHE_LOCK_WRITE,
+ DFLT_INIT_HITS, page_buf, 0))
+ goto err;
+ nod_flag= page.node;
+ DBUG_PRINT("rtree", ("reinserting keys from "
+ "page: %lu level: %d nod_flag: %u",
+ (ulong) ReinsertList.pages[i].offs,
+ ReinsertList.pages[i].level, nod_flag));
+
+ k= rt_PAGE_FIRST_KEY(share, page.buff, nod_flag);
+ last= rt_PAGE_END(&page);
+ for (; k < last; k= rt_PAGE_NEXT_KEY(share, k, key_data_length,
+ nod_flag))
{
- my_afree(page_buf);
- goto err1;
- }
- if (res)
- {
- ulong j;
- DBUG_PRINT("rtree", ("root has been split, adjust levels"));
- for (j= i; j < ReinsertList.n_pages; j++)
+ int res;
+ tmp_key.data= k;
+ if ((res= maria_rtree_insert_level(info, &tmp_key,
+ ReinsertList.pages[i].level,
+ root)) == -1)
+ {
+ my_afree(page_buf);
+ goto err;
+ }
+ if (res)
{
- ReinsertList.pages[j].level++;
- DBUG_PRINT("rtree", ("keys from page: %lu now level: %d",
- (ulong) ReinsertList.pages[i].offs,
- ReinsertList.pages[i].level));
+ uint j;
+ DBUG_PRINT("rtree", ("root has been split, adjust levels"));
+ for (j= i; j < ReinsertList.n_pages; j++)
+ {
+ ReinsertList.pages[j].level++;
+ DBUG_PRINT("rtree", ("keys from page: %lu now level: %d",
+ (ulong) ReinsertList.pages[i].offs,
+ ReinsertList.pages[i].level));
+ }
}
}
+ page_mark_changed(info, &page);
+ if (_ma_dispose(info, page.pos, 0))
+ {
+ my_afree(page_buf);
+ goto err;
+ }
}
- res= 0;
my_afree(page_buf);
- page_link_from_idx(info, page_link_idx)->changed= 1;
- if (_ma_dispose(info, ReinsertList.pages[i].offs, 0))
- goto err1;
- }
- if (ReinsertList.pages)
my_free((uchar*) ReinsertList.pages, MYF(0));
+ }
/* check for redundant root (not leaf, 1 child) and eliminate */
if ((old_root= *root) == HA_OFFSET_ERROR)
- goto err1;
- if (!_ma_fetch_keypage(info, keyinfo, old_root,
- PAGECACHE_LOCK_WRITE,
- DFLT_INIT_HITS, info->buff, 0, &root_page_link))
- goto err1;
- nod_flag= _ma_test_if_nod(share, info->buff);
- page_size= _ma_get_page_used(share, info->buff);
- if (nod_flag && (page_size == share->keypage_header + key_data_length +
+ goto err;
+ if (_ma_fetch_keypage(&page, info, keyinfo, old_root,
+ PAGECACHE_LOCK_WRITE,
+ DFLT_INIT_HITS, info->buff, 0))
+ goto err;
+ nod_flag= page.node;
+ if (nod_flag && (page.size == share->keypage_header + key_data_length +
nod_flag))
{
*root= _ma_kpos(nod_flag,
rt_PAGE_FIRST_KEY(share, info->buff, nod_flag));
- root_page_link->changed= 1;
- if (_ma_dispose(info, old_root, 0))
- goto err1;
+ page_mark_changed(info, &page);
+ if (_ma_dispose(info, page.pos, 0))
+ goto err;
}
info->update= HA_STATE_DELETED;
- res= 0;
- goto err;
-
-err1:
- res= -1;
- goto err; /* purecov: inspected */
+ break;
}
case 1: /* not found */
{
my_errno= HA_ERR_KEY_NOT_FOUND;
- res= -1;
- goto err; /* purecov: inspected */
+ goto err;
}
- default:
case -1: /* error */
- res= -1;
- goto err; /* purecov: inspected */
+ default:
+ goto err; /* purecov: inspected */
}
+ DBUG_RETURN(0);
+
err:
- DBUG_RETURN(res);
+ DBUG_RETURN(1);
}
@@ -1267,6 +1253,7 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, MARIA_KEY *key, uint32 flag)
ha_rows res= 0;
MARIA_SHARE *share= info->s;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ MARIA_PAGE page;
if (flag & MBR_DISJOINT)
return info->state->records;
@@ -1275,18 +1262,19 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, MARIA_KEY *key, uint32 flag)
return HA_POS_ERROR;
if (!(page_buf= (uchar*) my_alloca((uint) keyinfo->block_length)))
return HA_POS_ERROR;
- if (!_ma_fetch_keypage(info, keyinfo, root, PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, page_buf, 0, 0))
- goto err1;
- nod_flag= _ma_test_if_nod(share, page_buf);
+ if (_ma_fetch_keypage(&page, info, keyinfo, root,
+ PAGECACHE_LOCK_LEFT_UNLOCKED, DFLT_INIT_HITS, page_buf,
+ 0))
+ goto err;
+ nod_flag= page.node;
key_data_length= key->data_length;
- k= rt_PAGE_FIRST_KEY(share, page_buf, nod_flag);
- last= rt_PAGE_END(share, page_buf);
+ k= rt_PAGE_FIRST_KEY(share, page.buff, nod_flag);
+ last= rt_PAGE_END(&page);
- for (; k < last; k= rt_PAGE_NEXT_KEY(share, k, key_data_length,
- nod_flag), i++)
+ for (; k < last;
+ k= rt_PAGE_NEXT_KEY(share, k, key_data_length, nod_flag), i++)
{
if (nod_flag)
{
@@ -1297,16 +1285,16 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, MARIA_KEY *key, uint32 flag)
{
if (flag & (MBR_CONTAIN | MBR_INTERSECT))
{
- area += 1;
+ area+= 1;
}
else if (flag & (MBR_WITHIN | MBR_EQUAL))
{
if (!maria_rtree_key_cmp(keyinfo->seg, key->data, k, key_data_length,
MBR_WITHIN))
- area += 1;
+ area+= 1;
}
else
- goto err1;
+ goto err;
}
else
{
@@ -1323,7 +1311,7 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, MARIA_KEY *key, uint32 flag)
key_data_length) / k_area);
}
else
- goto err1;
+ goto err;
}
}
else
@@ -1344,7 +1332,7 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, MARIA_KEY *key, uint32 flag)
my_afree((uchar*)page_buf);
return res;
-err1:
+err:
my_afree(page_buf);
return HA_POS_ERROR;
}
diff --git a/storage/maria/ma_rt_index.h b/storage/maria/ma_rt_index.h
index 8705128e226..dacaa4389b7 100644
--- a/storage/maria/ma_rt_index.h
+++ b/storage/maria/ma_rt_index.h
@@ -22,15 +22,16 @@
#define rt_PAGE_FIRST_KEY(share, page, nod_flag) (page + share->keypage_header + nod_flag)
#define rt_PAGE_NEXT_KEY(share, key, key_length, nod_flag) (key + key_length +\
(nod_flag ? nod_flag : share->base.rec_reflength))
-#define rt_PAGE_END(share, page) (page + _ma_get_page_used(share, page))
+#define rt_PAGE_END(page) ((page)->buff + (page)->size)
#define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length - KEYPAGE_CHECKSUM_SIZE) / 3)
my_bool maria_rtree_insert(MARIA_HA *info, MARIA_KEY *key);
-int maria_rtree_delete(MARIA_HA *info, MARIA_KEY *key);
+my_bool maria_rtree_delete(MARIA_HA *info, MARIA_KEY *key);
int maria_rtree_insert_level(MARIA_HA *info, MARIA_KEY *key,
int ins_level, my_off_t *root);
-int maria_rtree_real_delete(MARIA_HA *info, MARIA_KEY *key, my_off_t *root);
+my_bool maria_rtree_real_delete(MARIA_HA *info, MARIA_KEY *key,
+ my_off_t *root);
int maria_rtree_find_first(MARIA_HA *info, MARIA_KEY *key, uint search_flag);
int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint32 search_flag);
@@ -39,21 +40,7 @@ int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length);
ha_rows maria_rtree_estimate(MARIA_HA *info, MARIA_KEY *key, uint32 flag);
-int maria_rtree_split_page(MARIA_HA *info, const MARIA_KEY *key,
- my_off_t page_offs, uchar *page,
+int maria_rtree_split_page(const MARIA_KEY *key, MARIA_PAGE *page,
my_off_t *new_page_offs);
-/**
- When you obtain a MARIA_PINNED_PAGE* link (by calling
- _ma_fetch_keypage()/_ma_new()/etc), it is valid only until the next call to
- those functions on this MARIA_HA*, because that next call may cause a
- realloc of the pinned_pages DYNAMIC_ARRAY, causing the first link to become
- wrong. The _index_ in the array is however invariant, so in these situations
- you should save the index immediately and use it to later obtain an
- up-to-date link.
-*/
-#define page_link_to_idx(INFO) ((INFO)->pinned_pages.elements - 1)
-#define page_link_from_idx(INFO, IDX) \
- dynamic_element(&(INFO)->pinned_pages, (IDX), MARIA_PINNED_PAGE *)
-
#endif /*HAVE_RTREE_KEYS*/
#endif /* _rt_index_h */
diff --git a/storage/maria/ma_rt_key.c b/storage/maria/ma_rt_key.c
index bf70d2ba798..bc2c8f71f5d 100644
--- a/storage/maria/ma_rt_key.c
+++ b/storage/maria/ma_rt_key.c
@@ -31,13 +31,14 @@
1 Split
*/
-int maria_rtree_add_key(MARIA_HA *info, const MARIA_KEY *key,
- uchar *page_buf, my_off_t page, my_off_t *new_page)
+int maria_rtree_add_key(const MARIA_KEY *key, MARIA_PAGE *page,
+ my_off_t *new_page)
{
+ MARIA_HA *info= page->info;
MARIA_SHARE *share= info->s;
- uint page_size= _ma_get_page_used(share, page_buf);
- uint nod_flag= _ma_test_if_nod(share, page_buf);
- uchar *key_pos= rt_PAGE_END(share, page_buf);
+ uint page_size= page->size;
+ uint nod_flag= page->node;
+ uchar *key_pos= rt_PAGE_END(page);
uint tot_key_length= key->data_length + key->ref_length + nod_flag;
DBUG_ENTER("maria_rtree_add_key");
@@ -54,16 +55,15 @@ int maria_rtree_add_key(MARIA_HA *info, const MARIA_KEY *key,
}
/* save key */
memcpy(key_pos, key->data - nod_flag, tot_key_length);
- page_size+= tot_key_length;
- _ma_store_page_used(share, page_buf, page_size);
+ page->size+= tot_key_length;
+ page_store_size(share, page);
if (share->now_transactional &&
- _ma_log_add(info, page, page_buf, key_pos - page_buf,
+ _ma_log_add(page, key_pos - page->buff,
key_pos, tot_key_length, tot_key_length, 0))
DBUG_RETURN(-1);
DBUG_RETURN(0);
}
- DBUG_RETURN(maria_rtree_split_page(info, key, page, page_buf, new_page)
- ? -1 : 1);
+ DBUG_RETURN(maria_rtree_split_page(key, page, new_page) ? -1 : 1);
}
@@ -74,27 +74,24 @@ int maria_rtree_add_key(MARIA_HA *info, const MARIA_KEY *key,
key_length is only the data part of the key
*/
-int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
- uint key_length, uint nod_flag, my_off_t page)
+int maria_rtree_delete_key(MARIA_PAGE *page, uchar *key, uint key_length)
{
+ MARIA_HA *info= page->info;
MARIA_SHARE *share= info->s;
- uint16 page_size= _ma_get_page_used(share, page_buf);
uint key_length_with_nod_flag;
uchar *key_start;
- key_start= key - nod_flag;
- if (!nod_flag)
+ key_start= key - page->node;
+ if (!page->node)
key_length+= share->base.rec_reflength;
- memmove(key_start, key + key_length, page_size - key_length -
- (key - page_buf));
- key_length_with_nod_flag= key_length + nod_flag;
- page_size-= key_length_with_nod_flag;
- _ma_store_page_used(share, page_buf, page_size);
+ memmove(key_start, key + key_length, page->size - key_length -
+ (key - page->buff));
+ key_length_with_nod_flag= key_length + page->node;
+ page->size-= key_length_with_nod_flag;
+ page_store_size(share, page);
if (share->now_transactional &&
- _ma_log_delete(info, page, page_buf, key_start, 0,
- key_length_with_nod_flag))
-
+ _ma_log_delete(page, key_start, 0, key_length_with_nod_flag))
return -1;
return 0;
}
@@ -107,15 +104,15 @@ int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEY *key,
my_off_t child_page)
{
+ MARIA_PAGE page;
DBUG_ENTER("maria_rtree_set_key_mbr");
- if (!_ma_fetch_keypage(info, key->keyinfo, child_page,
- PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, info->buff, 0, 0))
+ if (_ma_fetch_keypage(&page, info, key->keyinfo, child_page,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, info->buff, 0))
DBUG_RETURN(-1);
- DBUG_RETURN(maria_rtree_page_mbr(info, key->keyinfo->seg,
- info->buff, key->data,
- key->data_length));
+ DBUG_RETURN(maria_rtree_page_mbr(key->keyinfo->seg,
+ &page, key->data, key->data_length));
}
#endif /*HAVE_RTREE_KEYS*/
diff --git a/storage/maria/ma_rt_key.h b/storage/maria/ma_rt_key.h
index 5e24ac51b93..948809f3d38 100644
--- a/storage/maria/ma_rt_key.h
+++ b/storage/maria/ma_rt_key.h
@@ -21,10 +21,9 @@
#ifdef HAVE_RTREE_KEYS
-int maria_rtree_add_key(MARIA_HA *info, const MARIA_KEY *key, uchar *page_buf,
- my_off_t page, my_off_t *new_page);
-int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
- uint key_length, uint nod_flag, my_off_t page);
+int maria_rtree_add_key(const MARIA_KEY *key, MARIA_PAGE *page,
+ my_off_t *new_page);
+int maria_rtree_delete_key(MARIA_PAGE *page, uchar *key, uint key_length);
int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEY *key,
my_off_t child_page);
diff --git a/storage/maria/ma_rt_mbr.c b/storage/maria/ma_rt_mbr.c
index 9a5e60e36e7..b3e2b0ceab8 100644
--- a/storage/maria/ma_rt_mbr.c
+++ b/storage/maria/ma_rt_mbr.c
@@ -743,16 +743,17 @@ double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
Calculates key page total MBR= MBR(key1) + MBR(key2) + ...
Stores into *to.
*/
-int maria_rtree_page_mbr(const MARIA_HA *info, const HA_KEYSEG *keyseg,
- const uchar *page_buf,
+int maria_rtree_page_mbr(const HA_KEYSEG *keyseg,
+ MARIA_PAGE *page,
uchar *to, uint key_length)
{
+ MARIA_HA *info= page->info;
MARIA_SHARE *share= info->s;
uint inc= 0;
uint k_len= key_length;
- uint nod_flag= _ma_test_if_nod(share, page_buf);
+ uint nod_flag= page->node;
const uchar *k;
- const uchar *last= rt_PAGE_END(share, page_buf);
+ const uchar *last= rt_PAGE_END(page);
for (; (int)key_length > 0; keyseg += 2)
{
@@ -764,7 +765,7 @@ int maria_rtree_page_mbr(const MARIA_HA *info, const HA_KEYSEG *keyseg,
return 1;
}
- k= rt_PAGE_FIRST_KEY(share, page_buf, nod_flag);
+ k= rt_PAGE_FIRST_KEY(share, page->buff, nod_flag);
switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_INT8:
diff --git a/storage/maria/ma_rt_mbr.h b/storage/maria/ma_rt_mbr.h
index 11988868317..8fcd3d37b99 100644
--- a/storage/maria/ma_rt_mbr.h
+++ b/storage/maria/ma_rt_mbr.h
@@ -34,8 +34,7 @@ double maria_rtree_area_increase(const HA_KEYSEG *keyseg, const uchar *a,
uint key_length, double *ab_area);
double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
uint key_length, double *ab_perim);
-int maria_rtree_page_mbr(const MARIA_HA *info, const HA_KEYSEG *keyseg,
- const uchar *page_buf,
- uchar* c, uint key_length);
+int maria_rtree_page_mbr(const HA_KEYSEG *keyseg, MARIA_PAGE *page,
+ uchar *key, uint key_length);
#endif /*HAVE_RTREE_KEYS*/
#endif /* _rt_mbr_h */
diff --git a/storage/maria/ma_rt_split.c b/storage/maria/ma_rt_split.c
index f2a64c55251..8f137c2e0cf 100644
--- a/storage/maria/ma_rt_split.c
+++ b/storage/maria/ma_rt_split.c
@@ -295,9 +295,7 @@ static int split_maria_rtree_node(SplitStruct *node, int n_entries,
@param length_diff by how much the page has shrunk during split
*/
-static my_bool _ma_log_rt_split(MARIA_HA *info,
- my_off_t page,
- const uchar *buff __attribute__((unused)),
+static my_bool _ma_log_rt_split(MARIA_PAGE *page,
const uchar *key_with_nod_flag,
uint full_length,
const uchar *log_internal_copy,
@@ -305,18 +303,20 @@ static my_bool _ma_log_rt_split(MARIA_HA *info,
const uchar *log_key_copy,
uint length_diff)
{
+ MARIA_HA *info= page->info;
MARIA_SHARE *share= info->s;
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 1 + 2 + 1 + 2 + 2 + 7],
*log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 5];
uint translog_parts, extra_length= 0;
+ my_off_t page_pos;
DBUG_ENTER("_ma_log_rt_split");
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
DBUG_ASSERT(share->now_transactional);
- page/= share->block_size;
- page_store(log_data + FILEID_STORE_SIZE, page);
+ page_pos= page->pos / share->block_size;
+ page_store(log_data + FILEID_STORE_SIZE, page_pos);
log_pos= log_data+ FILEID_STORE_SIZE + PAGE_STORE_SIZE;
log_pos[0]= KEY_OP_DEL_SUFFIX;
log_pos++;
@@ -346,10 +346,11 @@ static my_bool _ma_log_rt_split(MARIA_HA *info,
#ifdef EXTRA_DEBUG_KEY_CHANGES
{
- int page_length= _ma_get_page_used(share, buff);
+ int page_length= page->size;
ha_checksum crc;
uchar *check_start= log_pos;
- crc= my_checksum(0, buff + LSN_STORE_SIZE, page_length - LSN_STORE_SIZE);
+ crc= my_checksum(0, page->buff + LSN_STORE_SIZE,
+ page_length - LSN_STORE_SIZE);
log_pos[0]= KEY_OP_CHECK;
log_pos++;
int2store(log_pos, page_length);
@@ -380,10 +381,10 @@ static my_bool _ma_log_rt_split(MARIA_HA *info,
If new_page_offs==NULL, won't create new page (for redo phase).
*/
-int maria_rtree_split_page(MARIA_HA *info, const MARIA_KEY *key,
- my_off_t page_offs, uchar *page,
+int maria_rtree_split_page(const MARIA_KEY *key, MARIA_PAGE *page,
my_off_t *new_page_offs)
{
+ MARIA_HA *info= page->info;
MARIA_SHARE *share= info->s;
const my_bool transactional= share->now_transactional;
int n1, n2; /* Number of items in groups */
@@ -395,11 +396,12 @@ int maria_rtree_split_page(MARIA_HA *info, const MARIA_KEY *key,
double *old_coord;
int n_dim;
uchar *source_cur, *cur1, *cur2;
- uchar *new_page, *log_internal_copy, *log_internal_copy_ptr,
+ uchar *new_page_buff, *log_internal_copy, *log_internal_copy_ptr,
*log_key_copy= NULL;
int err_code= 0;
- uint nod_flag= _ma_test_if_nod(share, page);
- uint org_length= _ma_get_page_used(share, page), new_length;
+ uint new_page_length;
+ uint nod_flag= page->node;
+ uint org_length= page->size;
uint full_length= key->data_length + (nod_flag ? nod_flag :
key->ref_length);
uint key_data_length= key->data_length;
@@ -421,7 +423,7 @@ int maria_rtree_split_page(MARIA_HA *info, const MARIA_KEY *key,
next_coord= coord_buf;
stop= task + max_keys;
- source_cur= rt_PAGE_FIRST_KEY(share, page, nod_flag);
+ source_cur= rt_PAGE_FIRST_KEY(share, page->buff, nod_flag);
for (cur= task;
cur < stop;
@@ -440,7 +442,7 @@ int maria_rtree_split_page(MARIA_HA *info, const MARIA_KEY *key,
old_coord= next_coord;
if (split_maria_rtree_node(task, max_keys + 1,
- _ma_get_page_used(share, page) + full_length + 2,
+ page->size + full_length + 2,
full_length,
rt_PAGE_MIN_SIZE(keyinfo->block_length),
2, 2, &next_coord, n_dim))
@@ -450,20 +452,21 @@ int maria_rtree_split_page(MARIA_HA *info, const MARIA_KEY *key,
}
/* Allocate buffer for new page and piece of log record */
- if (!(new_page= (uchar*) my_alloca((uint)keyinfo->block_length +
- (transactional ?
- (max_keys * (2 + 2) +
- 1 + 2 + 1 + 2) : 0))))
+ if (!(new_page_buff= (uchar*) my_alloca((uint)keyinfo->block_length +
+ (transactional ?
+ (max_keys * (2 + 2) +
+ 1 + 2 + 1 + 2) : 0))))
{
err_code= -1;
goto split_err;
}
- log_internal_copy= log_internal_copy_ptr= new_page + keyinfo->block_length;
- bzero(new_page, share->block_size);
+ log_internal_copy= log_internal_copy_ptr= new_page_buff +
+ keyinfo->block_length;
+ bzero(new_page_buff, share->block_size);
stop= task + (max_keys + 1);
- cur1= rt_PAGE_FIRST_KEY(share, page, nod_flag);
- cur2= rt_PAGE_FIRST_KEY(share, new_page, nod_flag);
+ cur1= rt_PAGE_FIRST_KEY(share, page->buff, nod_flag);
+ cur2= rt_PAGE_FIRST_KEY(share, new_page_buff, nod_flag);
n1= n2= 0;
for (cur= task; cur < stop; cur++)
@@ -493,11 +496,11 @@ int maria_rtree_split_page(MARIA_HA *info, const MARIA_KEY *key,
memcpy(to_with_nod_flag, cur_key_with_nod_flag, full_length);
if (log_this_change)
{
- uint to_with_nod_flag_offs= to_with_nod_flag - page;
+ uint to_with_nod_flag_offs= to_with_nod_flag - page->buff;
if (likely(cur_key != key->data))
{
/* this memcpy() is internal to the page (source in the page) */
- uint cur_key_with_nod_flag_offs= cur_key_with_nod_flag - page;
+ uint cur_key_with_nod_flag_offs= cur_key_with_nod_flag - page->buff;
int2store(log_internal_copy_ptr, to_with_nod_flag_offs);
log_internal_copy_ptr+= 2;
int2store(log_internal_copy_ptr, cur_key_with_nod_flag_offs);
@@ -519,36 +522,37 @@ int maria_rtree_split_page(MARIA_HA *info, const MARIA_KEY *key,
{ /* verify that above loop didn't touch header bytes */
uint i;
for (i= 0; i < share->keypage_header; i++)
- DBUG_ASSERT(new_page[i]==0);
+ DBUG_ASSERT(new_page_buff[i]==0);
}
if (nod_flag)
- _ma_store_keypage_flag(share, new_page, KEYPAGE_FLAG_ISNOD);
- _ma_store_keynr(share, new_page, keyinfo->key_nr);
- _ma_store_page_used(share, new_page, share->keypage_header +
- n2 * full_length);
- new_length= share->keypage_header + n1 * full_length;
- _ma_store_page_used(share, page, new_length);
+ _ma_store_keypage_flag(share, new_page_buff, KEYPAGE_FLAG_ISNOD);
+ _ma_store_keynr(share, new_page_buff, keyinfo->key_nr);
+ new_page_length= share->keypage_header + n2 * full_length;
+ _ma_store_page_used(share, new_page_buff, new_page_length);
+ page->size= share->keypage_header + n1 * full_length;
+ page_store_size(share, page);
if ((*new_page_offs= _ma_new(info, DFLT_INIT_HITS, &page_link)) ==
HA_OFFSET_ERROR)
err_code= -1;
else
{
+ MARIA_PAGE new_page;
+ _ma_page_setup(&new_page, info, keyinfo, *new_page_offs, new_page_buff);
+
if (transactional &&
( /* log change to split page */
- _ma_log_rt_split(info, page_offs, page, key->data - nod_flag,
+ _ma_log_rt_split(page, key->data - nod_flag,
full_length, log_internal_copy,
log_internal_copy_ptr - log_internal_copy,
- log_key_copy, org_length - new_length) ||
+ log_key_copy, org_length - page->size) ||
/* and to new page */
- _ma_log_new(info, *new_page_offs, new_page,
- share->keypage_header + n2 * full_length,
- keyinfo->key_nr, 0)))
+ _ma_log_new(&new_page, 0)))
err_code= -1;
- if ( _ma_write_keypage(info, keyinfo, *new_page_offs,
- page_link->write_lock,
- DFLT_INIT_HITS, new_page))
+
+ if (_ma_write_keypage(&new_page, page_link->write_lock,
+ DFLT_INIT_HITS))
err_code= -1;
}
DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index cf7ec5f9724..e34bca4aa57 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -18,7 +18,8 @@
#include "ma_fulltext.h"
#include "m_ctype.h"
-static my_bool _ma_get_prev_key(MARIA_KEY *key, uchar *page, uchar *keypos);
+static my_bool _ma_get_prev_key(MARIA_KEY *key, MARIA_PAGE *ma_page,
+ uchar *keypos);
/* Check that new index is ok */
@@ -62,8 +63,9 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
int error,flag;
uint page_flag, nod_flag, used_length;
uchar *keypos,*maxpos;
- uchar lastkey[MARIA_MAX_KEY_BUFF],*buff;
+ uchar lastkey[MARIA_MAX_KEY_BUFF];
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ MARIA_PAGE page;
DBUG_ENTER("_ma_search");
DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu",
(ulong) pos, nextflag, (ulong) info->cur_row.lastpos));
@@ -78,21 +80,21 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
DBUG_RETURN(1); /* Search at upper levels */
}
- if (!(buff= _ma_fetch_keypage(info, keyinfo, pos,
- PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, info->keyread_buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)), 0)))
+ if (_ma_fetch_keypage(&page, info, keyinfo, pos,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, info->keyread_buff,
+ test(!(nextflag & SEARCH_SAVE_BUFF))))
goto err;
- DBUG_DUMP("page", buff, _ma_get_page_used(info->s, buff));
+ DBUG_DUMP("page", page.buff, page.size);
- flag= (*keyinfo->bin_search)(key, buff, nextflag, &keypos, lastkey,
+ flag= (*keyinfo->bin_search)(key, &page, nextflag, &keypos, lastkey,
&last_key_not_used);
if (flag == MARIA_FOUND_WRONG_KEY)
DBUG_RETURN(-1);
- page_flag= _ma_get_keypage_flag(info->s, buff);
- _ma_get_used_and_nod_with_flag(info->s, page_flag, buff, used_length,
- nod_flag);
- maxpos= buff + used_length -1;
+ page_flag= page.flag;
+ used_length= page.size;
+ nod_flag= page.node;
+ maxpos= page.buff + used_length -1;
if (flag)
{
@@ -103,7 +105,7 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
if (flag >0)
{
if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
- keypos == buff + info->s->keypage_header + nod_flag)
+ keypos == page.buff + info->s->keypage_header + nod_flag)
DBUG_RETURN(1); /* Bigger than key */
}
else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
@@ -126,21 +128,22 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
}
if (pos != info->last_keypage)
{
- uchar *old_buff=buff;
- if (!(buff= _ma_fetch_keypage(info,keyinfo, pos,
- PAGECACHE_LOCK_LEFT_UNLOCKED,DFLT_INIT_HITS,
- info->keyread_buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)), 0)))
+ uchar *old_buff= page.buff;
+ if (_ma_fetch_keypage(&page, info, keyinfo, pos,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,DFLT_INIT_HITS,
+ info->keyread_buff,
+ test(!(nextflag & SEARCH_SAVE_BUFF))))
goto err;
- keypos=buff+(keypos-old_buff);
- maxpos=buff+(maxpos-old_buff);
+ /* Restore position if page buffer moved */
+ keypos= page.buff + (keypos - old_buff);
+ maxpos= page.buff + (maxpos - old_buff);
}
info->last_key.keyinfo= keyinfo;
if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0)
{
uint not_used[2];
- if (_ma_get_prev_key(&info->last_key, buff, keypos))
+ if (_ma_get_prev_key(&info->last_key, &page, keypos))
goto err;
/*
We have to use key->flag >> 1 here to transform
@@ -170,14 +173,14 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
info->cur_row.lastpos= _ma_row_pos_from_key(&info->last_key);
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
/* Save position for a possible read next / previous */
- info->int_keypos= info->keyread_buff+ (keypos-buff);
- info->int_maxpos= info->keyread_buff+ (maxpos-buff);
+ info->int_keypos= info->keyread_buff + (keypos - page.buff);
+ info->int_maxpos= info->keyread_buff + (maxpos - page.buff);
info->int_nod_flag=nod_flag;
info->int_keytree_version=keyinfo->version;
info->last_search_keypage=info->last_keypage;
info->page_changed=0;
/* Set marker that buffer was used (Marker for mi_search_next()) */
- info->keyread_buff_used= (info->keyread_buff != buff);
+ info->keyread_buff_used= (info->keyread_buff != page.buff);
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
DBUG_RETURN(0);
@@ -211,38 +214,39 @@ err:
@retval last_key Set to 1 if key is the last key in the page.
*/
-int _ma_bin_search(const MARIA_KEY *key, uchar *page,
+int _ma_bin_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
uint32 comp_flag, uchar **ret_pos,
uchar *buff __attribute__((unused)), my_bool *last_key)
{
int flag;
uint page_flag;
- uint start, mid, end, save_end, totlength, nod_flag, used_length;
+ uint start, mid, end, save_end, totlength, nod_flag;
uint not_used[2];
MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_SHARE *share= keyinfo->share;
+ uchar *page;
DBUG_ENTER("_ma_bin_search");
LINT_INIT(flag);
- page_flag= _ma_get_keypage_flag(share, page);
+ page_flag= ma_page->flag;
if (page_flag & KEYPAGE_FLAG_HAS_TRANSID)
{
/* Keys have varying length, can't use binary search */
- DBUG_RETURN(_ma_seq_search(key, page, comp_flag, ret_pos, buff, last_key));
+ DBUG_RETURN(_ma_seq_search(key, ma_page, comp_flag, ret_pos, buff,
+ last_key));
}
- _ma_get_used_and_nod_with_flag(share, page_flag, page, used_length,
- nod_flag);
+ nod_flag= ma_page->node;
totlength= keyinfo->keylength + nod_flag;
- DBUG_ASSERT(used_length >= share->keypage_header + nod_flag + totlength);
+ DBUG_ASSERT(ma_page->size >= share->keypage_header + nod_flag + totlength);
start=0;
mid=1;
- save_end= end= ((used_length - nod_flag - share->keypage_header) /
+ save_end= end= ((ma_page->size - nod_flag - share->keypage_header) /
totlength-1);
- DBUG_PRINT("test",("page_length: %u end: %u", used_length, end));
- page+= share->keypage_header + nod_flag;
+ DBUG_PRINT("test",("page_length: %u end: %u", ma_page->size, end));
+ page= ma_page->buff + share->keypage_header + nod_flag;
while (start != end)
{
@@ -297,13 +301,14 @@ int _ma_bin_search(const MARIA_KEY *key, uchar *page,
@retval buff Copy of previous or identical unpacked key
*/
-int _ma_seq_search(const MARIA_KEY *key, uchar *page,
+int _ma_seq_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
uint32 comp_flag, uchar **ret_pos,
uchar *buff, my_bool *last_key)
{
int flag;
- uint page_flag, nod_flag, length, used_length, not_used[2];
+ uint page_flag, nod_flag, length, not_used[2];
uchar t_buff[MARIA_MAX_KEY_BUFF], *end;
+ uchar *page;
MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_SHARE *share= keyinfo->share;
MARIA_KEY tmp_key;
@@ -312,10 +317,10 @@ int _ma_seq_search(const MARIA_KEY *key, uchar *page,
LINT_INIT(flag);
LINT_INIT(length);
- page_flag= _ma_get_keypage_flag(share, page);
- _ma_get_used_and_nod_with_flag(share, page_flag, page, used_length,
- nod_flag);
- end= page + used_length;
+ page_flag= ma_page->flag;
+ nod_flag= ma_page->node;
+ page= ma_page->buff;
+ end= page + ma_page->size;
page+= share->keypage_header + nod_flag;
*ret_pos= (uchar*) page;
t_buff[0]=0; /* Avoid bugs */
@@ -362,7 +367,7 @@ int _ma_seq_search(const MARIA_KEY *key, uchar *page,
Same interface as for _ma_seq_search()
*/
-int _ma_prefix_search(const MARIA_KEY *key, uchar *page,
+int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
uint32 nextflag, uchar **ret_pos, uchar *buff,
my_bool *last_key)
{
@@ -372,11 +377,11 @@ int _ma_prefix_search(const MARIA_KEY *key, uchar *page,
flag is the value returned by ha_key_cmp and as treated as final
*/
int flag=0, my_flag=-1;
- uint nod_flag, used_length, length, len, matched, cmplen, kseg_len;
+ uint nod_flag, length, len, matched, cmplen, kseg_len;
uint page_flag, prefix_len,suffix_len;
int key_len_skip, seg_len_pack, key_len_left;
- uchar *end;
- uchar *vseg, *saved_vseg, *saved_from;
+ uchar *end, *vseg, *saved_vseg, *saved_from;
+ uchar *page;
uchar tt_buff[MARIA_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
uchar *saved_to;
const uchar *kseg;
@@ -395,11 +400,11 @@ int _ma_prefix_search(const MARIA_KEY *key, uchar *page,
LINT_INIT(saved_vseg);
t_buff[0]=0; /* Avoid bugs */
- page_flag= _ma_get_keypage_flag(share, page);
- _ma_get_used_and_nod_with_flag(share, page_flag, page, used_length,
- nod_flag);
+ page_flag= ma_page->flag;
+ nod_flag= ma_page->node;
page_flag&= KEYPAGE_FLAG_HAS_TRANSID; /* For faster test in loop */
- end= page + used_length;
+ page= ma_page->buff;
+ end= page + ma_page->size;
page+= share->keypage_header + nod_flag;
*ret_pos= page;
kseg= key->data;
@@ -1364,14 +1369,16 @@ uchar *_ma_skip_binary_pack_key(MARIA_KEY *key, uint page_flag,
@return pointer to next key
*/
-uchar *_ma_get_key(MARIA_KEY *key, uchar *page, uchar *keypos)
+uchar *_ma_get_key(MARIA_KEY *key, MARIA_PAGE *ma_page, uchar *keypos)
{
uint page_flag, nod_flag;
MARIA_KEYDEF *keyinfo= key->keyinfo;
+ uchar *page;
DBUG_ENTER("_ma_get_key");
- page_flag= _ma_get_keypage_flag(keyinfo->share, page);
- nod_flag= _ma_test_if_nod(keyinfo->share, page);
+ page= ma_page->buff;
+ page_flag= ma_page->flag;
+ nod_flag= ma_page->node;
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)) &&
! (page_flag & KEYPAGE_FLAG_HAS_TRANSID))
@@ -1410,14 +1417,15 @@ uchar *_ma_get_key(MARIA_KEY *key, uchar *page, uchar *keypos)
@retval 1 error
*/
-static my_bool _ma_get_prev_key(MARIA_KEY *key, uchar *page, uchar *keypos)
+static my_bool _ma_get_prev_key(MARIA_KEY *key, MARIA_PAGE *ma_page,
+ uchar *keypos)
{
uint page_flag, nod_flag;
MARIA_KEYDEF *keyinfo= key->keyinfo;
DBUG_ENTER("_ma_get_prev_key");
- page_flag= _ma_get_keypage_flag(keyinfo->share, page);
- nod_flag= _ma_test_if_nod(keyinfo->share, page);
+ page_flag= ma_page->flag;
+ nod_flag= ma_page->node;
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)) &&
! (page_flag & KEYPAGE_FLAG_HAS_TRANSID))
@@ -1431,7 +1439,9 @@ static my_bool _ma_get_prev_key(MARIA_KEY *key, uchar *page, uchar *keypos)
}
else
{
- page+= keyinfo->share->keypage_header + nod_flag;
+ uchar *page;
+
+ page= ma_page->buff + keyinfo->share->keypage_header + nod_flag;
key->data[0]= 0; /* safety */
DBUG_ASSERT(page != keypos);
while (page < keypos)
@@ -1458,17 +1468,19 @@ static my_bool _ma_get_prev_key(MARIA_KEY *key, uchar *page, uchar *keypos)
@retval pointer to where key starts
*/
-uchar *_ma_get_last_key(MARIA_KEY *key, uchar *page, uchar *endpos)
+uchar *_ma_get_last_key(MARIA_KEY *key, MARIA_PAGE *ma_page, uchar *endpos)
{
uint page_flag,nod_flag;
- uchar *lastpos;
+ uchar *lastpos, *page;
MARIA_KEYDEF *keyinfo= key->keyinfo;
DBUG_ENTER("_ma_get_last_key");
- DBUG_PRINT("enter",("page: 0x%lx endpos: 0x%lx", (long) page,
+ DBUG_PRINT("enter",("page: 0x%lx endpos: 0x%lx", (long) ma_page->buff,
(long) endpos));
- page_flag= _ma_get_keypage_flag(keyinfo->share, page);
- nod_flag= _ma_test_if_nod(keyinfo->share, page);
+ page_flag= ma_page->flag;
+ nod_flag= ma_page->node;
+ page= ma_page->buff + keyinfo->share->keypage_header + nod_flag;
+
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)) &&
! (page_flag & KEYPAGE_FLAG_HAS_TRANSID))
{
@@ -1476,12 +1488,11 @@ uchar *_ma_get_last_key(MARIA_KEY *key, uchar *page, uchar *endpos)
key->ref_length= keyinfo->share->rec_reflength;
key->data_length= keyinfo->keylength - key->ref_length;
key->flag= 0;
- if (lastpos > page)
+ if (lastpos >= page)
bmove(key->data, lastpos, keyinfo->keylength + nod_flag);
}
else
{
- page+= keyinfo->share->keypage_header + nod_flag;
lastpos= page;
key->data[0]=0; /* safety */
while (page < endpos)
@@ -1591,10 +1602,10 @@ int _ma_search_next(register MARIA_HA *info, MARIA_KEY *key,
uint32 nextflag, my_off_t pos)
{
int error;
- uint page_flag,nod_flag;
uchar lastkey[MARIA_MAX_KEY_BUFF];
MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_KEY tmp_key;
+ MARIA_PAGE page;
DBUG_ENTER("_ma_search_next");
DBUG_PRINT("enter",("nextflag: %u lastpos: %lu int_keypos: 0x%lx page_changed %d keyread_buff_used: %d",
nextflag, (ulong) info->cur_row.lastpos,
@@ -1619,25 +1630,27 @@ int _ma_search_next(register MARIA_HA *info, MARIA_KEY *key,
if (info->keyread_buff_used)
{
- if (!_ma_fetch_keypage(info, keyinfo, info->last_search_keypage,
- PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, info->keyread_buff, 0, 0))
+ if (_ma_fetch_keypage(&page, info, keyinfo, info->last_search_keypage,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, info->keyread_buff, 0))
DBUG_RETURN(-1);
info->keyread_buff_used=0;
}
-
- /* Last used buffer is in info->keyread_buff */
- page_flag= _ma_get_keypage_flag(keyinfo->share, info->keyread_buff);
- nod_flag= _ma_test_if_nod(keyinfo->share, info->keyread_buff);
+ else
+ {
+ /* Last used buffer is in info->keyread_buff */
+ /* Todo: Add info->keyread_page to keep track of this */
+ _ma_page_setup(&page, info, keyinfo, 0, info->keyread_buff);
+ }
tmp_key.data= lastkey;
info->last_key.keyinfo= tmp_key.keyinfo= keyinfo;
if (nextflag & SEARCH_BIGGER) /* Next key */
{
- if (nod_flag)
+ if (page.node)
{
- my_off_t tmp_pos= _ma_kpos(nod_flag,info->int_keypos);
+ my_off_t tmp_pos= _ma_kpos(page.node, info->int_keypos);
if ((error= _ma_search(info, key, nextflag | SEARCH_SAVE_BUFF,
tmp_pos)) <=0)
@@ -1647,15 +1660,14 @@ int _ma_search_next(register MARIA_HA *info, MARIA_KEY *key,
info->last_key.data != key->data)
memcpy(info->last_key.data, key->data,
key->data_length + key->ref_length);
- if (!(*keyinfo->get_key)(&info->last_key, page_flag, nod_flag,
+ if (!(*keyinfo->get_key)(&info->last_key, page.flag, page.node,
&info->int_keypos))
DBUG_RETURN(-1);
}
else /* Previous key */
{
/* Find start of previous key */
- info->int_keypos= _ma_get_last_key(&tmp_key, info->keyread_buff,
- info->int_keypos);
+ info->int_keypos= _ma_get_last_key(&tmp_key, &page, info->int_keypos);
if (!info->int_keypos)
DBUG_RETURN(-1);
if (info->int_keypos == info->keyread_buff + info->s->keypage_header)
@@ -1664,14 +1676,13 @@ int _ma_search_next(register MARIA_HA *info, MARIA_KEY *key,
DBUG_RETURN(_ma_search(info, key, nextflag | SEARCH_SAVE_BUFF,
pos));
}
- if (nod_flag &&
+ if (page.node &&
(error= _ma_search(info, key, nextflag | SEARCH_SAVE_BUFF,
- _ma_kpos(nod_flag,info->int_keypos))) <= 0)
+ _ma_kpos(page.node,info->int_keypos))) <= 0)
DBUG_RETURN(error);
/* QQ: We should be able to optimize away the following call */
- if (! _ma_get_last_key(&info->last_key, info->keyread_buff,
- info->int_keypos))
+ if (! _ma_get_last_key(&info->last_key, &page, info->int_keypos))
DBUG_RETURN(-1);
}
info->cur_row.lastpos= _ma_row_pos_from_key(&info->last_key);
@@ -1688,11 +1699,11 @@ int _ma_search_next(register MARIA_HA *info, MARIA_KEY *key,
Found row is stored in info->cur_row.lastpos
*/
-int _ma_search_first(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- register my_off_t pos)
+int _ma_search_first(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ my_off_t pos)
{
- uint page_flag, nod_flag;
- uchar *page;
+ uchar *first_pos;
+ MARIA_PAGE page;
MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_search_first");
@@ -1705,28 +1716,26 @@ int _ma_search_first(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
do
{
- if (!_ma_fetch_keypage(info, keyinfo, pos, PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, info->keyread_buff, 0, 0))
+ if (_ma_fetch_keypage(&page, info, keyinfo, pos,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, info->keyread_buff, 0))
{
info->cur_row.lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
}
- page_flag= _ma_get_keypage_flag(share, info->keyread_buff);
- nod_flag= _ma_test_if_nod(share, info->keyread_buff);
- page= info->keyread_buff + share->keypage_header + nod_flag;
- } while ((pos= _ma_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
+ first_pos= page.buff + share->keypage_header + page.node;
+ } while ((pos= _ma_kpos(page.node, first_pos)) != HA_OFFSET_ERROR);
info->last_key.keyinfo= keyinfo;
- if (!(*keyinfo->get_key)(&info->last_key, page_flag, nod_flag, &page))
+ if (!(*keyinfo->get_key)(&info->last_key, page.flag, page.node, &first_pos))
DBUG_RETURN(-1); /* Crashed */
- info->int_keypos=page;
- info->int_maxpos= (info->keyread_buff +
- _ma_get_page_used(share, info->keyread_buff)-1);
- info->int_nod_flag=nod_flag;
- info->int_keytree_version=keyinfo->version;
- info->last_search_keypage=info->last_keypage;
+ info->int_keypos= first_pos;
+ info->int_maxpos= (page.buff + page.size -1);
+ info->int_nod_flag= page.node;
+ info->int_keytree_version= keyinfo->version;
+ info->last_search_keypage= info->last_keypage;
info->page_changed=info->keyread_buff_used=0;
info->cur_row.lastpos= _ma_row_pos_from_key(&info->last_key);
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
@@ -1743,11 +1752,11 @@ int _ma_search_first(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
Found row is stored in info->cur_row.lastpos
*/
-int _ma_search_last(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
- register my_off_t pos)
+int _ma_search_last(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
+ my_off_t pos)
{
- uint page_flag, nod_flag;
- uchar *buff,*end_of_page;
+ uchar *end_of_page;
+ MARIA_PAGE page;
DBUG_ENTER("_ma_search_last");
if (pos == HA_OFFSET_ERROR)
@@ -1757,32 +1766,28 @@ int _ma_search_last(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
DBUG_RETURN(-1);
}
- buff=info->keyread_buff;
do
{
- uint used_length;
- if (!_ma_fetch_keypage(info, keyinfo, pos, PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, buff, 0, 0))
+ if (_ma_fetch_keypage(&page, info, keyinfo, pos,
+ PAGECACHE_LOCK_LEFT_UNLOCKED,
+ DFLT_INIT_HITS, info->keyread_buff, 0))
{
info->cur_row.lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
}
- page_flag= _ma_get_keypage_flag(info->s, info->keyread_buff);
- _ma_get_used_and_nod_with_flag(info->s, page_flag, buff, used_length,
- nod_flag);
- end_of_page= buff + used_length;
- } while ((pos= _ma_kpos(nod_flag, end_of_page)) != HA_OFFSET_ERROR);
+ end_of_page= page.buff + page.size;
+ } while ((pos= _ma_kpos(page.node, end_of_page)) != HA_OFFSET_ERROR);
info->last_key.keyinfo= keyinfo;
- if (!_ma_get_last_key(&info->last_key, buff, end_of_page))
+ if (!_ma_get_last_key(&info->last_key, &page, end_of_page))
DBUG_RETURN(-1);
info->cur_row.lastpos= _ma_row_pos_from_key(&info->last_key);
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
- info->int_keypos= info->int_maxpos= end_of_page;
- info->int_nod_flag=nod_flag;
- info->int_keytree_version=keyinfo->version;
- info->last_search_keypage=info->last_keypage;
+ info->int_keypos= info->int_maxpos= end_of_page;
+ info->int_nod_flag= page.node;
+ info->int_keytree_version= keyinfo->version;
+ info->last_search_keypage= info->last_keypage;
info->page_changed=info->keyread_buff_used=0;
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
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);
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 661d6bd40bb..9dac722af1c 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -82,10 +82,9 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name);
static int maria_sort_records(HA_CHECK *param, register MARIA_HA *info,
char *name, uint sort_key,
my_bool write_info, my_bool update_index);
-static int sort_record_index(MARIA_SORT_PARAM *sort_param, MARIA_HA *info,
- MARIA_KEYDEF *keyinfo,
- my_off_t page, uchar *buff,uint sortkey,
- File new_file, my_bool update_index);
+static int sort_record_index(MARIA_SORT_PARAM *sort_param, MARIA_PAGE *page,
+ uint sortkey, File new_file,
+ my_bool update_index);
static my_bool write_log_record(HA_CHECK *param);
HA_CHECK check_param;
@@ -1663,6 +1662,7 @@ static int maria_sort_records(HA_CHECK *param,
char llbuff[22],llbuff2[22];
MARIA_SORT_INFO sort_info;
MARIA_SORT_PARAM sort_param;
+ MARIA_PAGE page;
DBUG_ENTER("sort_records");
bzero((char*)&sort_info,sizeof(sort_info));
@@ -1781,9 +1781,9 @@ static int maria_sort_records(HA_CHECK *param,
if (sort_info.new_data_file_type != COMPRESSED_RECORD)
info->state->checksum=0;
- if (sort_record_index(&sort_param,info,keyinfo,
- share->state.key_root[sort_key],
- temp_buff, sort_key,new_file,update_index) ||
+ _ma_page_setup(&page, info, keyinfo, share->state.key_root[sort_key],
+ temp_buff);
+ if (sort_record_index(&sort_param, &page, sort_key,new_file,update_index) ||
maria_write_data_suffix(&sort_info,1) ||
flush_io_cache(&info->rec_cache))
goto err;
@@ -1839,11 +1839,11 @@ err:
/* Sort records recursive using one index */
-static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
- MARIA_KEYDEF *keyinfo,
- my_off_t page, uchar *buff, uint sort_key,
+static int sort_record_index(MARIA_SORT_PARAM *sort_param,
+ MARIA_PAGE *ma_page, uint sort_key,
File new_file,my_bool update_index)
{
+ MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
uint page_flag, nod_flag,used_length;
uchar *temp_buff,*keypos,*endpos;
@@ -1853,41 +1853,44 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
MARIA_SORT_INFO *sort_info= sort_param->sort_info;
HA_CHECK *param=sort_info->param;
MARIA_KEY tmp_key;
+ MARIA_PAGE new_page;
+ const MARIA_KEYDEF *keyinfo= ma_page->keyinfo;
DBUG_ENTER("sort_record_index");
- page_flag= _ma_get_keypage_flag(share, buff);
- nod_flag= _ma_test_if_nod(share, buff);
+ page_flag= ma_page->flag;
+ nod_flag= ma_page->node;
temp_buff=0;
- tmp_key.keyinfo= keyinfo;
+ tmp_key.keyinfo= (MARIA_KEYDEF*) keyinfo;
tmp_key.data= lastkey;
if (nod_flag)
{
- if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length)))
+ if (!(temp_buff= (uchar*) my_alloca(tmp_key.keyinfo->block_length)))
{
_ma_check_print_error(param,"Not Enough memory");
DBUG_RETURN(-1);
}
}
- used_length= _ma_get_page_used(share, buff);
- keypos= buff + share->keypage_header + nod_flag;
- endpos= buff + used_length;
+ used_length= ma_page->size;
+ keypos= ma_page->buff + share->keypage_header + nod_flag;
+ endpos= ma_page->buff + used_length;
for ( ;; )
{
_sanity(__FILE__,__LINE__);
if (nod_flag)
{
next_page= _ma_kpos(nod_flag, keypos);
- if (my_pread(share->kfile.file, (uchar*)temp_buff,
- (uint) keyinfo->block_length, next_page,
+ if (my_pread(share->kfile.file, temp_buff,
+ (uint) tmp_key.keyinfo->block_length, next_page,
MYF(MY_NABP+MY_WME)))
{
_ma_check_print_error(param,"Can't read keys from filepos: %s",
llstr(next_page,llbuff));
goto err;
}
- if (sort_record_index(sort_param, info,keyinfo,next_page,temp_buff,
- sort_key,
+ _ma_page_setup(&new_page, info, ma_page->keyinfo, next_page, temp_buff);
+
+ if (sort_record_index(sort_param, &new_page, sort_key,
new_file, update_index))
goto err;
}
@@ -1917,9 +1920,9 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
goto err;
}
/* Clear end of block to get better compression if the table is backuped */
- bzero((uchar*) buff+used_length,keyinfo->block_length-used_length);
- if (my_pwrite(share->kfile.file, (uchar*)buff, (uint)keyinfo->block_length,
- page,param->myf_rw))
+ bzero(ma_page->buff + used_length, keyinfo->block_length - used_length);
+ if (my_pwrite(share->kfile.file, ma_page->buff, (uint)keyinfo->block_length,
+ ma_page->pos, param->myf_rw))
{
_ma_check_print_error(param,"%d when updating keyblock",my_errno);
goto err;
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 8eb985ab763..8bd2bafbb64 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -607,28 +607,20 @@ struct st_maria_handler
((uint) mi_uint2korr((x) + (share)->keypage_header - KEYPAGE_USED_SIZE))
#define _ma_store_page_used(share,x,y) \
mi_int2store((x) + (share)->keypage_header - KEYPAGE_USED_SIZE, (y))
+#define _ma_get_keypage_flag(share,x) x[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]
#define _ma_test_if_nod(share,x) \
((_ma_get_keypage_flag(share,x) & KEYPAGE_FLAG_ISNOD) ? (share)->base.key_reflength : 0)
-#define _ma_get_used_and_nod(share,buff,length,nod) \
-{ \
- (nod)= _ma_test_if_nod((share),(buff)); \
- (length)= _ma_get_page_used((share),(buff)); \
-}
-#define _ma_get_used_and_nod_with_flag(share,flag,buff,length,nod) \
-{ \
- (nod)= (((flag) & KEYPAGE_FLAG_ISNOD) ? (share)->base.key_reflength : 0); \
- (length)= _ma_get_page_used((share),(buff)); \
-}
#define _ma_store_keynr(share, x, nr) x[(share)->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= (nr)
#define _ma_get_keynr(share, x) ((uchar) x[(share)->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE])
#define _ma_store_transid(buff, transid) \
transid_store((buff) + LSN_STORE_SIZE, (transid))
#define _ma_korr_transid(buff) \
transid_korr((buff) + LSN_STORE_SIZE)
-#define _ma_get_keypage_flag(share,x) x[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]
#define _ma_store_keypage_flag(share,x,flag) x[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]= (flag)
-#define _ma_mark_page_with_transid(share, x) x[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]|= KEYPAGE_FLAG_HAS_TRANSID
+#define _ma_mark_page_with_transid(share, page) \
+ (page)->flag|= KEYPAGE_FLAG_HAS_TRANSID; \
+ (page)->buff[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]= (page)->flag;
/*
@@ -783,6 +775,21 @@ typedef struct st_pinned_page
} MARIA_PINNED_PAGE;
+/* Keeps all information about a page and related to a page */
+
+typedef struct st_maria_page
+{
+ MARIA_HA *info;
+ const MARIA_KEYDEF *keyinfo;
+ uchar *buff; /* Data for page */
+ my_off_t pos; /* Disk address to page */
+ uint size; /* Size of data on page */
+ uint node; /* 0 or share->base.key_reflength */
+ uint flag; /* Page flag */
+ uint link_offset;
+} MARIA_PAGE;
+
+
/* Prototypes for intern functions */
extern int _ma_read_dynamic_record(MARIA_HA *, uchar *, MARIA_RECORD_POS);
extern int _ma_read_rnd_dynamic_record(MARIA_HA *, uchar *, MARIA_RECORD_POS,
@@ -804,22 +811,22 @@ extern my_bool _ma_update_static_record(MARIA_HA *, MARIA_RECORD_POS,
extern my_bool _ma_delete_static_record(MARIA_HA *info, const uchar *record);
extern my_bool _ma_cmp_static_record(MARIA_HA *info, const uchar *record);
extern my_bool _ma_ck_write(MARIA_HA *info, MARIA_KEY *key);
-extern int _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key,
- MARIA_RECORD_POS *root);
-extern int _ma_insert(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);
-extern int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEY *key,
+extern my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key,
+ MARIA_RECORD_POS *root);
+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);
+extern my_bool _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEY *key,
MARIA_RECORD_POS *root, uint32 comp_flag);
-extern int _ma_split_page(MARIA_HA *info, MARIA_KEY *key, my_off_t split_page,
- uchar *split_buff, uint org_split_length,
+extern 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,
uchar *key_buff, my_bool insert_last_key);
-extern uchar *_ma_find_half_pos(MARIA_HA *info, MARIA_KEY *key, uint nod_flag,
- uchar *page, uchar ** after_key);
+extern uchar *_ma_find_half_pos(MARIA_KEY *key, MARIA_PAGE *page,
+ uchar ** after_key);
extern int _ma_calc_static_key_length(const MARIA_KEY *key, uint nod_flag,
uchar *key_pos, uchar *org_key,
uchar *key_buff,
@@ -847,9 +854,9 @@ extern void _ma_store_pack_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
extern void _ma_store_bin_pack_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
MARIA_KEY_PARAM *s_temp);
-extern int _ma_ck_delete(MARIA_HA *info, MARIA_KEY *key);
-extern int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEY *key,
- my_off_t *root);
+extern my_bool _ma_ck_delete(MARIA_HA *info, MARIA_KEY *key);
+extern my_bool _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEY *key,
+ my_off_t *root);
extern int _ma_readinfo(MARIA_HA *info, int lock_flag, int check_keybuffer);
extern int _ma_writeinfo(MARIA_HA *info, uint options);
extern int _ma_test_if_changed(MARIA_HA *info);
@@ -861,13 +868,13 @@ extern int _ma_decrement_open_count(MARIA_HA *info);
extern int _ma_check_index(MARIA_HA *info, int inx);
extern int _ma_search(MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
my_off_t pos);
-extern int _ma_bin_search( const MARIA_KEY *key, uchar *page,
+extern int _ma_bin_search(const MARIA_KEY *key, const MARIA_PAGE *page,
uint32 comp_flag, uchar **ret_pos, uchar *buff,
my_bool *was_last_key);
-extern int _ma_seq_search(const MARIA_KEY *key, uchar *page,
+extern int _ma_seq_search(const MARIA_KEY *key, const MARIA_PAGE *page,
uint comp_flag, uchar ** ret_pos, uchar *buff,
my_bool *was_last_key);
-extern int _ma_prefix_search(const MARIA_KEY *key, uchar *page,
+extern int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *page,
uint32 comp_flag, uchar ** ret_pos, uchar *buff,
my_bool *was_last_key);
extern my_off_t _ma_kpos(uint nod_flag, const uchar *after_key);
@@ -889,14 +896,12 @@ extern uint _ma_get_binary_pack_key(MARIA_KEY *key, uint page_flag,
uint nod_flag, uchar **page_pos);
uchar *_ma_skip_binary_pack_key(MARIA_KEY *key, uint page_flag,
uint nod_flag, uchar *page);
-extern uchar *_ma_get_last_key(MARIA_KEY *key, uchar *keypos, uchar *endpos);
-extern uchar *_ma_get_key(MARIA_KEY *key, uchar *page, uchar *keypos);
+extern uchar *_ma_get_last_key(MARIA_KEY *key, MARIA_PAGE *page,
+ uchar *endpos);
+extern uchar *_ma_get_key(MARIA_KEY *key, MARIA_PAGE *page, uchar *keypos);
extern uint _ma_keylength(MARIA_KEYDEF *keyinfo, const uchar *key);
extern uint _ma_keylength_part(MARIA_KEYDEF *keyinfo, const uchar *key,
HA_KEYSEG *end);
-extern uchar *_qq_move_key(MARIA_KEYDEF *keyinfo, uchar *to,
- const uchar *from);
-
extern int _ma_search_next(MARIA_HA *info, MARIA_KEY *key,
uint32 nextflag, my_off_t pos);
extern int _ma_search_first(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
@@ -909,21 +914,20 @@ extern my_off_t _ma_transparent_recpos(MARIA_SHARE *share, my_off_t pos);
extern my_off_t _ma_transaction_keypos_to_recpos(MARIA_SHARE *, my_off_t pos);
extern my_off_t _ma_transaction_recpos_to_keypos(MARIA_SHARE *, my_off_t pos);
-extern uchar *_ma_fetch_keypage(MARIA_HA *info,
- const MARIA_KEYDEF *keyinfo,
- my_off_t page, enum pagecache_page_lock lock,
- int level, uchar *buff, int return_buffer,
- MARIA_PINNED_PAGE **page_link);
-extern int _ma_write_keypage(MARIA_HA *info,
- const MARIA_KEYDEF *keyinfo,
- my_off_t page, enum pagecache_page_lock lock,
- int level, uchar *buff);
+extern void _ma_page_setup(MARIA_PAGE *page, MARIA_HA *info,
+ const MARIA_KEYDEF *keyinfo, my_off_t pos,
+ uchar *buff);
+extern my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
+ const MARIA_KEYDEF *keyinfo,
+ my_off_t pos, enum pagecache_page_lock lock,
+ int level, uchar *buff,
+ my_bool return_buffer);
+extern my_bool _ma_write_keypage(MARIA_PAGE *page,
+ enum pagecache_page_lock lock, int level);
extern int _ma_dispose(MARIA_HA *info, my_off_t pos, my_bool page_not_read);
extern my_off_t _ma_new(register MARIA_HA *info, int level,
MARIA_PINNED_PAGE **page_link);
-extern my_bool _ma_compact_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
- my_off_t page_pos, uchar *page,
- TrID min_read_from);
+extern my_bool _ma_compact_keypage(MARIA_PAGE *page, TrID min_read_from);
extern uint transid_store_packed(MARIA_HA *info, uchar *to, ulonglong trid);
extern ulonglong transid_get_packed(MARIA_SHARE *share, const uchar *from);
#define transid_packed_length(data) \
@@ -931,6 +935,15 @@ extern ulonglong transid_get_packed(MARIA_SHARE *share, const uchar *from);
(uint) (257 - (uchar) (data)[0]))
#define key_has_transid(key) (*(key) & 1)
+#define page_mark_changed(info, page) \
+ dynamic_element(&(info)->pinned_pages, (page)->link_offset, \
+ MARIA_PINNED_PAGE*)->changed= 1;
+#define page_store_size(share, page) \
+ _ma_store_page_used((share), (page)->buff, (page)->size);
+#define page_store_info(share, page) \
+ _ma_store_keypage_flag((share), (page)->buff, (page)->flag); \
+ _ma_store_page_used((share), (page)->buff, (page)->size);
+
extern MARIA_KEY *_ma_make_key(MARIA_HA *info, MARIA_KEY *int_key, uint keynr,
uchar *key, const uchar *record,
MARIA_RECORD_POS filepos, ulonglong trid);