+ bt_lockpage(BtLockDelete, rset);
+ bt_lockpage(BtLockWrite, rset);
+
+ // pull contents of right page into our empty page
+
+ memcpy (page, rpage, bt->mgr->page_size);
+
+ // ready to release right parent lock
+ // now that we have a new page in place
+
+ if( ppage->act == 1 ) {
+ bt_unlockpage (BtLockWrite, rpset);
+ bt_unpinlatch (rpset);
+ bt_unpinpool (rppool);
+ }
+
+ // add killed right block to free chain
+ // lock latch mgr
+
+ bt_spinwritelock(bt->mgr->latchmgr->lock, 0);
+
+ // store free chain in allocation page second right
+
+ bt_putid(rpage->right, bt_getid(bt->mgr->latchmgr->alloc[1].right));
+ bt_putid(bt->mgr->latchmgr->alloc[1].right, right);
+
+ // unlock latch mgr and right page
+
+ bt_unlockpage(BtLockDelete, rset);
+ bt_unlockpage(BtLockWrite, rset);
+ bt_unpinlatch (rset);
+ bt_unpinpool (rpool);
+
+ bt_spinreleasewrite(bt->mgr->latchmgr->lock, 0);
+
+ // delete our obsolete fence key from our parent
+
+ slotptr(ppage, slot)->dead = 1;
+ ppage->dirty = 1;
+
+ // if our parent now empty
+ // remove it from the tree
+
+ if( ppage->act-- == 1 )
+ if( bt_mergeleft (bt, ppage, ppool, pset, parent, lvl+1) )
+ return bt->err;
+
+rmergexit:
+ bt_unlockpage (BtLockWrite, pset);
+ bt_unpinlatch (pset);
+ bt_unpinpool (ppool);
+
+ bt->found = 1;
+ return bt->err = 0;
+}
+
+// remove empty page from the B-tree
+// try merging left first. If no left
+// sibling, then merge right.
+
+// call with page loaded and locked,
+// return with page locked.
+
+BTERR bt_mergeleft (BtDb *bt, BtPage page, BtPool *pool, BtLatchSet *set, uid page_no, uint lvl)
+{
+unsigned char fencekey[256], postkey[256];
+uint slot, idx, postfence = 0;
+BtLatchSet *lset, *pset;
+BtPool *lpool, *ppool;
+BtPage lpage, ppage;
+uid left, parent;
+BtKey ptr;
+
+ ptr = keyptr(page, page->cnt);
+ memcpy(fencekey, ptr, ptr->len + 1);
+ bt_unlockpage (BtLockWrite, set);
+
+ // load and lock our parent
+
+retry:
+ if( !(slot = bt_loadpage (bt, fencekey+1, *fencekey, lvl+1, BtLockWrite)) )