#include "cbt.h" #include "pr.h" extern bfile *curbf; bdelete(bf, key) bfile *bf; mbuf key; { dkey *dold, *dnew; hdr *b; int svlen, dellen; char *ffree; if(bf == NULL) return(EOF); if(notran(bf)) return(EOF); if(!bf->rdwrt) { errno = BNOWRITE; return(EOF); } if(bseek(bf, key) != FOUND) return(NOTFOUND); b = bf->path[0]; dold = bf->rdptr.rptr; if(bf->rdptr.rnum + 1 >= b->kcnt) { nfree(b) += dold->dlen + (treeonly(bf)? 0: sizeof(lfaddr)); --b->kcnt; mustwrite(bf, 0) = 1; if(b->hlev == 0 && b->kcnt <= 0 || b->hlev > 0 && b->kcnt < 0) { mustwrite(bf, 0) = 0; ndelete(1, key); } if(b->kcnt < 0) b->kcnt = 0; (void) bseek(bf, key); return(FOUND); } if(treeonly(bf)) ffree = (char *)&nfree(b) - nfree(b); else ffree = (char *)lfadr(b, b->kcnt - 1) - nfree(b); svlen = dold->dlen; dnew = (dkey *)((char *)dold + dold->dlen); if(dnew->dcom <= dold->dcom) { mvgbt((char *)dold, (char *)dnew, ffree - (char *)dnew); if(!treeonly(bf)) rmlfadr(b, bf->rdptr.rnum); b->kcnt--; mustwrite(bf, 0) = 1; nfree(b) += svlen + (treeonly(bf)? 0: sizeof(lfaddr)); (void) bseek(bf, key); return(FOUND); } dellen = dnew->dcom - dold->dcom; /* writing over dold */ dold->dlen = dnew->dlen + dellen; mvgbt(dold->dkey + dellen, dnew->dkey, ffree - dnew->dkey); if(!treeonly(bf)) rmlfadr(b, bf->rdptr.rnum); b->kcnt--; mustwrite(bf, 0) = 1; nfree(b) += svlen - dellen + (treeonly(bf)? 0: sizeof(lfaddr)); (void) bseek(bf, key); return(FOUND); } rmlfadr(b, n) hdr *b; unsigned int n; { mvgbt((char *)lfadr(b, b->kcnt - 2), (char *)lfadr(b, b->kcnt - 1), (int)sizeof(lfaddr) * (b->kcnt - 1 - n)); } rmndadr(b, n) hdr *b; unsigned short n; { mvgbt((char *)ndadr(b, b->kcnt - 1), (char *)ndadr(b, b->kcnt), (int)sizeof(ndaddr) * (b->kcnt - n)); } ndelete(lev, key) mbuf key; { hdr *b; int svlen, dellen; unsigned short n; private x; char *ffree; dkey *dold, *dnew; if(lev > curbf->height) { b = curbf->path[curbf->height]; b->hlev = 0; curbf->height = 0; mustwrite(curbf, 0) = 1; curbf->loc[0] = 0; nfree(b) = NDSZ - sizeof(hdr) - sizeof(trailer); b->kcnt = 0; mvgbt((char *)curbf->path[0], (char *)b, NDSZ); return; } b = curbf->path[lev]; n = xscan(b, key, &x); if(x.match == EOF) { if(b->kcnt <= 0) { mustwrite(curbf, lev) = 0; ndelete(lev+1, key); return; } b->kcnt--; nfree(b) += sizeof(ndaddr) + x.d->dlen; mustwrite(curbf, lev) = 1; return; } dold = x.d; dnew = (dkey *)((char *)dold + dold->dlen); ffree = (char *)ndadr(b, b->kcnt) - nfree(b); svlen = dold->dlen; if(n + 1 >= b->kcnt || dnew->dcom <= dold->dcom) { mvgbt((char *)dold, (char *)dnew, ffree - (char *)dnew); rmndadr(b, n); b->kcnt--; mustwrite(curbf, lev) = 1; nfree(b) += sizeof(ndaddr) + svlen; return; } dellen = dnew->dcom - dold->dcom; /* writing over dold */ dold->dlen = dnew->dlen + dellen; mvgbt(dold->dkey + dellen, dnew->dkey, ffree - dnew->dkey); rmndadr(b, n); b->kcnt--; mustwrite(curbf, lev) = 1; nfree(b) += sizeof(ndaddr) + svlen - dellen; }