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