+ bt_unlockpage(BtLockWrite, lset);
+ bt_unpinlatch (lset);
+ bt_unpinpool (lpool);
+
+ // release our node's delete lock
+
+ bt_unlockpage(BtLockDelete, set);
+
+lmergexit:
+ bt_unlockpage (BtLockWrite, pset);
+ bt_unpinpool (ppool);
+
+ // do we need to post parent's fence key in its parent?
+
+ if( !postfence || parent == ROOT_page ) {
+ bt_unpinlatch (pset);
+ bt->found = 1;
+ return bt->err = 0;
+ }
+
+ // interlock parent fence post
+
+ bt_lockpage (BtLockParent, pset);
+
+ // load parent's parent page
+posttry:
+ if( !(slot = bt_loadpage (bt, fencekey+1, *fencekey, lvl+2, BtLockWrite)) )
+ return bt->err;
+
+ if( !(slot = bt_cleanpage (bt, bt->page, *fencekey, slot)) )
+ if( bt_splitpage (bt, bt->page, bt->pool, bt->set, bt->page_no) )
+ return bt->err;
+ else
+ goto posttry;
+
+ page = bt->page;
+
+ page->min -= *postkey + 1;
+ ((unsigned char *)page)[page->min] = *postkey;
+ memcpy ((unsigned char *)page + page->min +1, postkey + 1, *postkey );
+ slotptr(page, slot)->off = page->min;
+
+ bt_unlockpage (BtLockParent, pset);
+ bt_unpinlatch (pset);
+
+ bt_unlockpage (BtLockWrite, bt->set);
+ bt_unpinlatch (bt->set);
+ bt_unpinpool (bt->pool);
+
+ bt->found = 1;
+ return bt->err = 0;
+}
+
+// find and delete key on page by marking delete flag bit
+// if page becomes empty, delete it from the btree
+
+BTERR bt_deletekey (BtDb *bt, unsigned char *key, uint len)
+{
+BtLatchSet *set;
+BtPool *pool;
+BtPage page;
+uid page_no;
+BtKey ptr;
+uint slot;
+
+ if( !(slot = bt_loadpage (bt, key, len, 0, BtLockWrite)) )
+ return bt->err;