diff options
Diffstat (limited to 'storage/maria/ma_rt_index.c')
| -rw-r--r-- | storage/maria/ma_rt_index.c | 482 |
1 files changed, 235 insertions, 247 deletions
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; } |
