Commit d6bdf033 authored by Michael Widenius's avatar Michael Widenius

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
parent dd406c1e
......@@ -161,6 +161,7 @@ struct st_maria_handler; /* For referense */
typedef struct st_maria_handler MARIA_HA;
struct st_maria_s_param;
struct st_maria_keydef;
struct st_maria_page;
typedef struct st_maria_key /* Internal info about a key */
{
......@@ -194,7 +195,7 @@ typedef struct st_maria_keydef /* Key definition with open & info */
HA_KEYSEG *seg, *end;
struct st_mysql_ftparser *parser; /* Fulltext [pre]parser */
int (*bin_search)(const MARIA_KEY *key, uchar *page,
int (*bin_search)(const MARIA_KEY *key, const struct st_maria_page *page,
uint32 comp_flag, uchar **ret_pos, uchar *buff,
my_bool *was_last_key);
uint (*get_key)(MARIA_KEY *key, uint page_flag, uint nod_flag,
......@@ -207,7 +208,7 @@ typedef struct st_maria_keydef /* Key definition with open & info */
void (*store_key)(struct st_maria_keydef *keyinfo, uchar *key_pos,
struct st_maria_s_param *s_temp);
my_bool (*ck_insert)(MARIA_HA *inf, MARIA_KEY *key);
int (*ck_delete)(MARIA_HA *inf, MARIA_KEY *klen);
my_bool (*ck_delete)(MARIA_HA *inf, MARIA_KEY *klen);
MARIA_KEY *(*make_key)(MARIA_HA *info, MARIA_KEY *int_key, uint keynr,
uchar *key, const uchar *record,
MARIA_RECORD_POS filepos, ulonglong trid);
......
This diff is collapsed.
This diff is collapsed.
......@@ -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);
......
This diff is collapsed.
......@@ -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 @@ static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
/* 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;
......
This diff is collapsed.
......@@ -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));
......
This diff is collapsed.
This diff is collapsed.
......@@ -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 @@ static int maria_sort_records(HA_CHECK *param,
/* 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;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment