Annotation of researchv10no/cmd/btree/gbt/bwrite.c, revision 1.1

1.1     ! root        1: #include "cbt.h"
        !             2: #include "pr.h"
        !             3: 
        !             4: typedef union {
        !             5:        ndaddr na;
        !             6:        lfaddr la;
        !             7: } addr;
        !             8: static char splitting[MXHT+1];
        !             9: extern bfile *curbf;
        !            10: extern ndaddr oldnode(), newnode();
        !            11: extern char *malloc();
        !            12: 
        !            13: extern long brecwrite();
        !            14: 
        !            15: bwrite(bf, key, rec) mbuf key, rec; bfile *bf;
        !            16: {      addr u;
        !            17:        int n;
        !            18:        if(bf == NULL)
        !            19:                return(EOF);
        !            20:        if(!bf->rdwrt) {
        !            21:                errno = BNOWRITE;
        !            22:                return(EOF);
        !            23:        }
        !            24:        if(notran(bf))
        !            25:                return(EOF);
        !            26:        if(key.mlen > MAXKLEN)
        !            27:                return(EOF);
        !            28:        if(!treeonly(bf)) {
        !            29:                u.la.llen = rec.mlen;
        !            30:                u.la.lloc = brecwrite(rec);
        !            31:                if(u.la.lloc == EOF)
        !            32:                        return(EOF);
        !            33:        }
        !            34:        if(desce(bf, key, (private *)NULL) == EOF)
        !            35:                return(EOF);
        !            36:        n = xinsert(0, key, u);
        !            37:        (void) bseek(bf, key);
        !            38:        return(n);
        !            39: }
        !            40: 
        !            41: fixpath(bf)
        !            42: bfile *bf;
        !            43: {      addr u;
        !            44:        hdr *b;
        !            45:        int i, n, j;
        !            46:        for(i = 0; i < bf->height; i++) {
        !            47:                if(!mustwrite(bf, i))
        !            48:                        continue;
        !            49:                n = bf->loc[i];
        !            50:                if((u.na = oldnode(i)) == EOF)
        !            51:                        return(EOF);
        !            52:                b = bf->path[i+1];
        !            53:                for(j = 0; j <= b->kcnt; j++)
        !            54:                        if(*ndadr(b, j) == n)
        !            55:                                break;
        !            56:                if(j > b->kcnt){ /* curtains, the parent doesn't point to us */
        !            57:                        errno = BFATAL;
        !            58:                        return(EOF);
        !            59:                }
        !            60:                *ndadr(b, j) = u.na;
        !            61:                mustwrite(bf, i + 1) = 1;
        !            62:        }
        !            63:        return(0);
        !            64: }
        !            65: 
        !            66: xinsert(lev, key, u) mbuf key; addr u;
        !            67: {      private x;
        !            68:        int n, dellen;
        !            69:        hdr *b = curbf->path[lev];
        !            70:        char ba[NDSZ], bb[NDSZ];
        !            71:        dkey *dx, *dy;
        !            72:        if(splitting[lev])
        !            73:                if(desce(curbf, key, (private *)NULL) == EOF)
        !            74:                        return(EOF);
        !            75:        n = xscan(b, key, &x);
        !            76:        if(x.match == FOUND) {
        !            77:                if(treeonly(curbf))
        !            78:                        return(FOUND);
        !            79:                else if(lev)
        !            80:                        *ndadr(b, n) = u.na;
        !            81:                else
        !            82:                        *lfadr(b, n) = u.la;
        !            83:                mustwrite(curbf, lev) = 1;
        !            84:                return(FOUND);
        !            85:        }
        !            86:        dx = (dkey *)ba;
        !            87:        dy = (dkey *)bb;
        !            88:        dellen = newx(&x, key, dx, dy);
        !            89:        if(lev)
        !            90:                dellen += sizeof(ndaddr);
        !            91:        else if(!treeonly(curbf))
        !            92:                dellen += sizeof(lfaddr);
        !            93:        if(dellen > nfree(b)) {
        !            94:                if(nsplit(lev) == EOF)
        !            95:                        return(EOF);
        !            96:                splitting[lev] = 1;
        !            97:                n = xinsert(lev, key, u);
        !            98:                splitting[lev] = 0;
        !            99:                return(n);
        !           100:        }
        !           101:        b = curbf->path[lev];   /* with thanks to brian meekings */
        !           102:        addaddr(b, n, u);
        !           103:        newkeys(b, &x, dx, dy);
        !           104:        b->kcnt++;
        !           105:        nfree(b) -= dellen;
        !           106:        mustwrite(curbf, lev) = 1;
        !           107:        return(NOTFOUND);
        !           108: }
        !           109: 
        !           110: newx(x, key, c, d) private *x; mbuf key; dkey *c, *d;
        !           111: {      int i, j;
        !           112:        if(x->match != EOF)
        !           113:                c->dcom = x->ocom;
        !           114:        else    c->dcom = x->ncom;
        !           115:        i = key.mlen - c->dcom;
        !           116:        c->dlen = DKEYSZ + i;
        !           117:        mvgbt(c->dkey, key.mdata + c->dcom, i);
        !           118:        if(x->match == EOF)
        !           119:                return(c->dlen);
        !           120:        j = x->ncom - x->d->dcom;
        !           121:        d->dcom = x->ncom;
        !           122:        d->dlen = x->d->dlen - j;
        !           123:        mvgbt(d->dkey, x->d->dkey + j, d->dlen - DKEYSZ);
        !           124:        return(c->dlen - j);
        !           125: }
        !           126: 
        !           127: addaddr(b, n, u)
        !           128: hdr *b;
        !           129: addr u;
        !           130: {
        !           131:        if(b->hlev) {
        !           132:                mvgbt((char *)ndadr(b, b->kcnt + 1),
        !           133:                        (char *)ndadr(b, b->kcnt),
        !           134:                        sizeof(ndaddr) * (b->kcnt + 1 - n) );
        !           135:                *ndadr(b, n) = u.na;
        !           136:                return;
        !           137:        }
        !           138:        if(treeonly(curbf))
        !           139:                return;
        !           140:        mvgbt((char *)lfadr(b, b->kcnt), (char *)lfadr(b, b->kcnt - 1),
        !           141:                sizeof(lfaddr) * (b->kcnt - n));
        !           142:        *lfadr(b, n) = u.la;
        !           143: }
        !           144: 
        !           145: newkeys(b, x, c, d)
        !           146: hdr *b;
        !           147: private *x;
        !           148: dkey *c, *d;
        !           149: {      int n;
        !           150:        char *ffree;
        !           151:        if(b->hlev)
        !           152:                ffree = (char *)ndadr(b, b->kcnt) - nfree(b);
        !           153:        else if(treeonly(curbf))
        !           154:                ffree = (char *)&nfree(b) - nfree(b);
        !           155:        else
        !           156:                ffree = (char *)lfadr(b, b->kcnt - 1) - nfree(b);
        !           157:        if(x->match != EOF) {
        !           158:                n = c->dlen + d->dlen;
        !           159:                n -= x->d->dlen;
        !           160:                mvgbt((char *)x->d + n, (char *)x->d, ffree - (char *)x->d);
        !           161:                mvgbt((char *)x->d, (char *)c, c->dlen);
        !           162:                mvgbt((char *)x->d + c->dlen, (char *)d, d->dlen);
        !           163:        }
        !           164:        else if(b->kcnt > 0)
        !           165:                mvgbt((char *)x->d + x->d->dlen, (char *)c, c->dlen);
        !           166:        else
        !           167:                mvgbt((char *)x->d, (char *)c, c->dlen);
        !           168: }
        !           169: 
        !           170: nsplit(lev)
        !           171: {      dkey *tod, *fromd;
        !           172:        char prefix[MAXKLEN + 10];
        !           173:        hdr *b = curbf->path[lev];
        !           174:        mbuf key;
        !           175:        addr u;
        !           176:        union {
        !           177:                lfaddr *la;
        !           178:                ndaddr *na;
        !           179:        } from, to;
        !           180:        int mvd, x, i, count, n;
        !           181:        hdr *ha;
        !           182:        char a[NDSZ];
        !           183: 
        !           184:        x = (NDSZ - sizeof(hdr) - sizeof(trailer)) / 2;
        !           185:        ha = (hdr *) a;
        !           186:        mvd = count = 0;
        !           187:        tod = (dkey *)(ha + 1);
        !           188:        fromd = (dkey *)(b + 1);
        !           189:        if(lev == 0) {
        !           190:                to.la = lfadr(ha, 0);
        !           191:                from.la = lfadr(b, 0);
        !           192:        }
        !           193:        else {
        !           194:                to.na = ndadr(ha, 0);
        !           195:                from.na = ndadr(b, 0);
        !           196:        }
        !           197:        *ha = *b;
        !           198:        n = (b->kcnt + 1)/2;
        !           199:        if(lev && b->kcnt - n <= 1)
        !           200:                n--;
        !           201:        for(; count < n && mvd <= x; count++) {
        !           202:                mvgbt((char *)tod, (char *)fromd, fromd->dlen);
        !           203:                mvd += fromd->dlen;
        !           204:                tod = (dkey *)((char *)tod + fromd->dlen);
        !           205:                fromd = (dkey *)((char *)fromd + fromd->dlen);
        !           206:                if(lev) {
        !           207:                        *to.na-- = *from.na--;
        !           208:                        mvd += sizeof(ndaddr);
        !           209:                }
        !           210:                else if(!treeonly(curbf)) {
        !           211:                        *to.la-- = *from.la--;
        !           212:                        mvd += sizeof(lfaddr);
        !           213:                }
        !           214:        }
        !           215:        if(lev) {       /* another pointer for non-leaves */
        !           216:                *to.na-- = *from.na--;
        !           217:                mvd += sizeof(ndaddr);
        !           218:        }
        !           219:        ha->kcnt = count;
        !           220:        nfree(ha) = NDSZ - sizeof(hdr) - sizeof(trailer) - mvd;
        !           221:        /* if lev == 0, we promote the last key, else the next key */
        !           222:        key.mlen = lastkey(ha, prefix);
        !           223:        if(lev) {
        !           224:                mvgbt(prefix + fromd->dcom, fromd->dkey, fromd->dlen - DKEYSZ);
        !           225:                key.mlen = fromd->dcom + fromd->dlen - DKEYSZ;
        !           226:                count++;
        !           227:                fromd = (dkey *)((char *)fromd + fromd->dlen);
        !           228:        }
        !           229:        u.na = newnode(ha);
        !           230:        if(u.na == EOF) {       /* error while splitting */
        !           231:                curbf->fatal++;
        !           232:                return(EOF);
        !           233:        }
        !           234:        key.mdata = prefix;
        !           235:        /* other half */
        !           236:        if(lev == 0)
        !           237:                to.la = lfadr(ha, 0);
        !           238:        else
        !           239:                to.na = ndadr(ha, 0);
        !           240:        tod = (dkey *)(ha + 1);
        !           241:        tod->dcom = 0;
        !           242:        tod->dlen = fromd->dlen + fromd->dcom;
        !           243:        mvgbt(tod->dkey, prefix, fromd->dcom);
        !           244:        mvgbt(tod->dkey + fromd->dcom, fromd->dkey, fromd->dlen - DKEYSZ);
        !           245:        mvd = tod->dlen;
        !           246:        fromd = (dkey *)((char *)fromd + fromd->dlen);
        !           247:        tod = (dkey *)((char *)tod + tod->dlen);
        !           248:        if(lev) {
        !           249:                *to.na-- = *from.na--;
        !           250:                mvd += sizeof(ndaddr);
        !           251:        }
        !           252:        else if(!treeonly(curbf)) {
        !           253:                *to.la-- = *from.la--;
        !           254:                mvd += sizeof(lfaddr);
        !           255:        }
        !           256:        count++;
        !           257:        for(i = 1; count < b->kcnt; i++, count++) {
        !           258:                mvgbt((char *)tod, (char *)fromd, fromd->dlen);
        !           259:                mvd += fromd->dlen;
        !           260:                tod = (dkey *)((char *)tod + tod->dlen);
        !           261:                fromd = (dkey *)((char *)fromd + fromd->dlen);
        !           262:                if(lev) {
        !           263:                        *to.na-- = *from.na--;
        !           264:                        mvd += sizeof(ndaddr);
        !           265:                }
        !           266:                else if(!treeonly(curbf)) {
        !           267:                        *to.la-- = *from.la--;
        !           268:                        mvd += sizeof(lfaddr);
        !           269:                }
        !           270: 
        !           271:        }
        !           272:        if(lev) {
        !           273:                *to.na-- = *from.na--;
        !           274:                mvd += sizeof(ndaddr);
        !           275:        }
        !           276:        ha->kcnt = i;
        !           277:        nfree(ha) = NDSZ - sizeof(hdr) - sizeof(trailer) - mvd;
        !           278:        mvgbt((char *)b, (char *)ha, NDSZ);
        !           279:        mustwrite(curbf, lev) = 1;
        !           280:        if(lev < curbf->height) {
        !           281:                if(xinsert(lev + 1, key, u) == EOF) {
        !           282:                        curbf->fatal++;
        !           283:                        return(EOF);
        !           284:                }
        !           285:        }
        !           286:        else
        !           287:                return(newroot(u, key, b));
        !           288:        return(0);
        !           289: }
        !           290: 
        !           291: newroot(u, key, b)
        !           292: addr u;
        !           293: mbuf key;
        !           294: hdr *b;
        !           295: {      hdr *x;
        !           296:        dkey *d;
        !           297:        if(curbf->height >= MXHT) {
        !           298:                errno = BTALL;
        !           299:                curbf->fatal++;
        !           300:                return(EOF);
        !           301:        }
        !           302:        if((x = curbf->path[b->hlev + 1] = (hdr *)malloc(NDSZ)) == NULL) {
        !           303:                errno = BNOMEM;
        !           304:                curbf->fatal++;
        !           305:                return(EOF);
        !           306:        }
        !           307:        *x = *b;
        !           308:        x->hlev++;
        !           309:        d = (dkey *)(x + 1);
        !           310:        d->dlen = DKEYSZ + key.mlen;
        !           311:        d->dcom = 0;
        !           312:        mvgbt(d->dkey, key.mdata, key.mlen);
        !           313:        *ndadr(x, 0) = u.na;
        !           314:        *ndadr(x, 1) = curbf->loc[b->hlev] = newnode(b);
        !           315:        x->kcnt = 1;
        !           316:        nfree(x) = NDSZ - sizeof(hdr) - sizeof(trailer) - DKEYSZ
        !           317:                - key.mlen - 2 * sizeof(ndaddr);
        !           318:        mustwrite(curbf, ++curbf->height) = 1;
        !           319:        return(0);
        !           320: }
        !           321: 
        !           322: lastkey(b, s)
        !           323: hdr *b;
        !           324: char *s;
        !           325: {      int i, n;
        !           326:        dkey *p;
        !           327:        p = (dkey *)(b + 1);
        !           328:        for(n = i = 0; i < b->kcnt; i++) {
        !           329:                mvgbt(s + p->dcom, p->dkey, p->dlen - DKEYSZ);
        !           330:                n = p->dlen + p->dcom - DKEYSZ;
        !           331:                p = (dkey *)((char *) p + p->dlen);
        !           332:        }
        !           333:        return(n);
        !           334: }
        !           335: 
        !           336: static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bwrite.c\n"};
        !           337: /*0010010000010101*/

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.