mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
Added MARIA_PAGE structure to keep all information about a maria key page.
This allowed me to remove a lot of parameters to functions, local variables, duplicate code and identical constructs. It should also make the code easier to read. Changed all marking of page as changed to use offset instead of pointers; This removed one theoretical problem where dynamic_array may have been moved between two calls. In addition I changed some functions from return my_bool include/maria.h: Changes to use MARIA_PAGE storage/maria/ma_check.c: Changes to use MARIA_PAGE Folded lines longer > 79 characters storage/maria/ma_delete.c: Changes to use MARIA_PAGE Changed _ma_ck_delete(), ma_log_delete(), ma_write_undo_key_delete() and _ma_ck_real_delete() to return type my_bool Removed some calls to maria_print_error() as the caller (maria_delete() and maria_write()) also prints the error storage/maria/ma_ft_update.c: Fix needed as _ma_ck_delete() now returns my_bool New parameter for ma_write_keypage. storage/maria/ma_key_recover.c: Changes to use MARIA_PAGE storage/maria/ma_key_recover.h: Updated function prototypes storage/maria/ma_page.c: Changes to use MARIA_PAGE Added _ma_page_setup() for old functions that doesn't (yet) use MARIA_PAGE natively storage/maria/ma_range.c: Changes to use MARIA_PAGE storage/maria/ma_rt_index.c: Changes to use MARIA_PAGE Changed maria_rtree_delete() and maria_rtree_real_delete() to return type my_bool Removed one 'if (node_flag) as this was always true Changed lable 'err1' to 'err' as there was no other error lables Moved allocation of page_buff outside of loop for fewer alloc/free calls Changed n_pages and m_pages to uint as 65000 pages is more than enough storage/maria/ma_rt_index.h: Updated function prototypes storage/maria/ma_rt_key.c: Changes to use MARIA_PAGE storage/maria/ma_rt_key.h: Updated function prototypes storage/maria/ma_rt_mbr.c: Changes to use MARIA_PAGE storage/maria/ma_rt_mbr.h: Updated function prototypes storage/maria/ma_rt_split.c: Changes to use MARIA_PAGE storage/maria/ma_search.c: Changes to use MARIA_PAGE storage/maria/ma_write.c: Changes to use MARIA_PAGE Changed _ma_ck_write_btree_with_log(), _ma_ck_real_write_btree(), ma_enlarge_root() to use return type my_bool Don't set *root to HA_OFFSET_ERROR in case of error Removed maria_print_error() calls as caller will do this Simplified logic in balance_page by introducing pointers to left and right pages storage/maria/maria_chk.c: Changes to use MARIA_PAGE storage/maria/maria_def.h: Changes to use MARIA_PAGE Removed some not used macros Added macros for MARIA_PAGE handling
This commit is contained in:
parent
dd406c1e7e
commit
d6bdf03375
19 changed files with 1483 additions and 1345 deletions
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -44,14 +44,50 @@
|
|||
#include "trnman.h"
|
||||
#include "ma_key_recover.h"
|
||||
|
||||
/* Fetch a key-page in memory */
|
||||
/**
|
||||
Fill MARIA_PAGE structure for usage with _ma_write_keypage
|
||||
*/
|
||||
|
||||
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)
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
ReinsertList.pages[j].level++;
|
||||
DBUG_PRINT("rtree", ("keys from page: %lu now level: %d",
|
||||
(ulong) ReinsertList.pages[i].offs,
|
||||
ReinsertList.pages[i].level));
|
||||
my_afree(page_buf);
|
||||
goto err;
|
||||
}
|
||||
if (res)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue