int flags;
u_int32_t flags;
__ham_c_del(cursor, flags)	DBC *cursor;	int flags;{	DB *ldbp;	HTAB *hashp;	HASH_CURSOR *hcp;	HASH_CURSOR save_curs;	db_pgno_t ppgno, chg_pgno;	int ret, t_ret;	DEBUG_LWRITE(cursor->dbp, cursor->txn, "ham_c_del", NULL, NULL, flags);	ldbp = cursor->dbp;	if (F_ISSET(cursor->dbp, DB_AM_THREAD) &&	    (ret = __db_gethandle(cursor->dbp, __ham_hdup, &ldbp)) != 0)		return (ret);	hashp = (HTAB *)ldbp->internal;	hcp = (HASH_CURSOR *)cursor->internal;	save_curs = *hcp;	if ((ret = __db_cdelchk(ldbp, flags,	    F_ISSET(ldbp, DB_AM_RDONLY), IS_VALID(hcp))) != 0)		return (ret);	if (F_ISSET(hcp, H_DELETED))		return (DB_NOTFOUND);	SET_LOCKER(hashp->dbp, cursor->txn);	GET_META(hashp->dbp, hashp);	hashp->hash_accesses++;	if ((ret = __ham_get_cpage(hashp, hcp, DB_LOCK_WRITE)) != 0)		goto out;	if (F_ISSET(hcp, H_ISDUP) && hcp->dpgno != PGNO_INVALID) {		/*		 * We are about to remove a duplicate from offpage.		 *		 * There are 4 cases.		 * 1. We will remove an item on a page, but there are more		 *    items on that page.		 * 2. We will remove the last item on a page, but there is a		 *    following page of duplicates.		 * 3. We will remove the last item on a page, this page was the		 *    last page in a duplicate set, but there were dups before		 *    it.		 * 4. We will remove the last item on a page, removing the last		 *    duplicate.		 * In case 1 hcp->dpagep is unchanged.		 * In case 2 hcp->dpagep comes back pointing to the next dup		 *     page.		 * In case 3 hcp->dpagep comes back NULL.		 * In case 4 hcp->dpagep comes back NULL.		 *		 * Case 4 results in deleting the pair off the master page.		 * The normal code for doing this knows how to delete the		 * duplicates, so we will handle this case in the normal code.		 */		ppgno = PREV_PGNO(hcp->dpagep);		if (ppgno == PGNO_INVALID &&		    NEXT_PGNO(hcp->dpagep) == PGNO_INVALID &&		    NUM_ENT(hcp->dpagep) == 1)			goto normal;		/* Remove item from duplicate page. */		chg_pgno = hcp->dpgno;		if ((ret = __db_drem(hashp->dbp,		    &hcp->dpagep, hcp->dndx, __ham_del_page)) != 0)			goto out;		if (hcp->dpagep == NULL) {			if (ppgno != PGNO_INVALID) {		/* Case 3 */				hcp->dpgno = ppgno;				if ((ret = __ham_get_cpage(hashp, hcp,				    DB_LOCK_READ)) != 0)					goto out;				hcp->dndx = NUM_ENT(hcp->dpagep);				F_SET(hcp, H_DELETED);			} else {				/* Case 4 */				ret = __ham_del_pair(hashp, hcp, 1);				hcp->dpgno = PGNO_INVALID;				/*				 * Delpair updated the cursor queue, so we				 * don't have to do that here.				 */				chg_pgno = PGNO_INVALID;			}		} else if (PGNO(hcp->dpagep) != hcp->dpgno) {			hcp->dndx = 0;				/* Case 2 */			hcp->dpgno = PGNO(hcp->dpagep);			if (ppgno == PGNO_INVALID)				memcpy(HOFFDUP_PGNO(P_ENTRY(hcp->pagep,				    H_DATAINDEX(hcp->bndx))),				    &hcp->dpgno, sizeof(db_pgno_t));			F_SET(hcp, H_DELETED);		} else						/* Case 1 */			F_SET(hcp, H_DELETED);		if (chg_pgno != PGNO_INVALID)			__ham_c_update(hcp, chg_pgno, 0, 0, 1);	} else if (F_ISSET(hcp, H_ISDUP)) {			/* on page */		if (hcp->dup_off == 0 && DUP_SIZE(hcp->dup_len) ==		    LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx))			ret = __ham_del_pair(hashp, hcp, 1);		else {			DBT repldbt;			repldbt.flags = 0;			F_SET(&repldbt, DB_DBT_PARTIAL);			repldbt.doff = hcp->dup_off;			repldbt.dlen = DUP_SIZE(hcp->dup_len);			repldbt.size = 0;			ret = __ham_replpair(hashp, hcp, &repldbt, 0);			hcp->dup_tlen -= DUP_SIZE(hcp->dup_len);			F_SET(hcp, H_DELETED);			__ham_c_update(hcp, hcp->pgno,			    DUP_SIZE(hcp->dup_len), 0, 1);		}	} else		/* Not a duplicate */normal:		ret = __ham_del_pair(hashp, hcp, 1);out:	if ((t_ret = __ham_item_done(hashp, hcp, ret == 0)) != 0 && ret == 0)		t_ret = ret;	if (ret != 0)		*hcp = save_curs;	RELEASE_META(hashp->dbp, hashp);	if (F_ISSET(cursor->dbp, DB_AM_THREAD))		__db_puthandle(ldbp);	return (ret);}