- // can we do a simple merge entirely
- // between siblings on the parent page?
-
- if( slot < parent->page->cnt ) {
- // find our right neighbor
- // right must exist because the stopper prevents
- // the rightmost page from deleting
-
- for( idx = slot; idx++ < parent->page->cnt; )
- if( !slotptr(parent->page, idx)->dead )
- break;
-
- sibling->page_no = bt_getid (slotptr (parent->page, idx)->id);
-
- bt_lockpage (BtLockDelete, set->latch);
- bt_lockpage (BtLockWrite, set->latch);
-
- // merge right if sibling shows up in
- // our parent and is not being killed
-
- if( sibling->page_no == bt_getid (set->page->right) ) {
- sibling->latch = bt_pinlatch (bt, sibling->page_no);
- bt_lockpage (BtLockParent, sibling->latch);
- bt_lockpage (BtLockDelete, sibling->latch);
- bt_lockpage (BtLockWrite, sibling->latch);
-
- if( sibling->pool = bt_pinpool (bt, sibling->page_no) )
- sibling->page = bt_page (bt, sibling->pool, sibling->page_no);
- else
- return bt->err;
-
- if( !sibling->page->kill )
- return bt_mergeright(bt, set, parent, sibling, slot, idx);
-
- // try again later
-
- bt_unlockpage (BtLockWrite, sibling->latch);
- bt_unlockpage (BtLockParent, sibling->latch);
- bt_unlockpage (BtLockDelete, sibling->latch);
- bt_unpinlatch (sibling->latch);
- bt_unpinpool (sibling->pool);
- }
-
- bt_unlockpage (BtLockDelete, set->latch);
- bt_unlockpage (BtLockWrite, set->latch);
- bt_unlockpage (BtLockWrite, parent->latch);
- bt_unpinlatch (parent->latch);
- bt_unpinpool (parent->pool);
-#ifdef linux
- sched_yield();
-#else
- SwitchToThread();
-#endif
- goto retry;
- }
-
- // find our left neighbor in our parent page
-
- for( idx = slot; --idx; )
- if( !slotptr(parent->page, idx)->dead )
- break;
-
- // if no left neighbor, delete ourselves and our parent
-
- if( !idx ) {
- bt_lockpage (BtLockAccess, set->latch);
- bt_lockpage (BtLockWrite, set->latch);
- bt_unlockpage (BtLockAccess, set->latch);
-
- rparent->page_no = bt_getid (parent->page->right);
- rparent->latch = bt_pinlatch (bt, rparent->page_no);
-
- bt_lockpage (BtLockAccess, rparent->latch);
- bt_lockpage (BtLockWrite, rparent->latch);
- bt_unlockpage (BtLockAccess, rparent->latch);
-
- if( rparent->pool = bt_pinpool (bt, rparent->page_no) )
- rparent->page = bt_page (bt, rparent->pool, rparent->page_no);
- else
- return bt->err;
-
- if( !rparent->page->kill ) {
- sibling->page_no = bt_getid (set->page->right);
- sibling->latch = bt_pinlatch (bt, sibling->page_no);
-
- bt_lockpage (BtLockAccess, sibling->latch);
- bt_lockpage (BtLockWrite, sibling->latch);
- bt_unlockpage (BtLockAccess, sibling->latch);
-
- if( sibling->pool = bt_pinpool (bt, sibling->page_no) )
- sibling->page = bt_page (bt, sibling->pool, sibling->page_no);
- else
- return bt->err;
-
- if( !sibling->page->kill )
- return bt_removeparent (bt, set, parent, sibling, rparent, lvl+1);