Пример #1
0
int btcls(BTA* b)
{
    int ioerr;
  
    bterr("",0,NULL);

    if ((ioerr=bvalap("BTCLS",b)) != 0) return(ioerr);

    btact = b;      /* set context pointer */


    /* Undo any locks and flush buffers before closing file */
    while (btact->lckcnt > 0) bulock();
    
    /* close index file and free context memory */
    ioerr = fclose(btact->idxunt);
    if (ioerr != 0) {
        bterr("BTCLS",QCLSIO,btact->idxfid);
    }
    else {
        btact->idxunt = NULL;
        bacfre(btact);
    }
    return(btgerr());
}
Пример #2
0
int bgtslt()
{
    int idx, i;

    idx = -1;
    /* any slots free? */
    for (i=0;i<ZMXBLK;i++) {
#if DEBUG >= 2
        printf("bgtslt: cntrl[%d].inmem = " ZINTFMT "\n",
               i,((btact->cntrl)+i)->inmem);
#endif
        if (((btact->cntrl)+i)->inmem < 0) {
            idx = i;
            break;
        }
    }
    if (idx < 0 ) {
        /* nope, need to free a memory block (least recently used)  */
        idx = bqhead();
    }
    if (idx < 0)
        bterr("BGTSLT",QNOMEM,NULL);
    else {
        /* flush block to disk if slot not empty */
        if (((btact->cntrl)+idx)->inmem >= 0)
            if (bwrblk(((btact->cntrl)+idx)->inmem) != 0)
                bterr("BGTSLT",QWRBLK,itostr(((btact->cntrl)+idx)->inmem));
    }
#if DEBUG >= 2
    printf("bgtslt: found idx of %d\n",idx);
#endif
    return(idx);
}
Пример #3
0
int btinit()
{
    int i,cnt=0,blksz;
    static int btinited = FALSE;

    if (btinited) {
        bterr("BTINIT",QINERR,NULL);
        return(QINERR);
    }

    /* ensure ZBLKSZ is a power of 2 */
    blksz = ZBLKSZ;
    for (i=0;i<(ZBYTEW*sizeof(int));i++) {
        if ((blksz & 0x1) == 1) cnt++;
        blksz = blksz>>1;
    }
    if (cnt != 1) {
        bterr("BTINIT",QBLKSZERR,itostr(ZBLKSZ));
        return(QBLKSZERR);
    }
    
    for (i=0;i<ZMXACT;i++) {
        btat[i].idxunt = NULL;
        btat[i].idxfid[0] = '\0';
        btat[i].cntrl = NULL;
        btat[i].memrec = NULL;
        btat[i].cntxt = NULL;
        btat[i].fd = -1;
    }

    btinited = TRUE;
    return(0);
}
Пример #4
0
BTint bgtinf(BTint blk,int type)
{
    BTint val;
    int ioerr,idx;

    val = 0;
    if (type >= ZINFSZ)
        bterr("BGTINF",QINFER,NULL);
    else {
        ioerr = brdblk(blk,&idx);
        if (idx < 0) {
            bterr("BGTINF",QRDBLK,itostr((long) blk));
        }
        else {
            switch (type) {
                case ZBTYPE:
                    val = ((btact->memrec)+idx)->infblk[ZBTYPE] & MASK;
                    break;
                case ZBTVER:
                    val = ((btact->memrec)+idx)->infblk[ZBTYPE] >>
                        ((ZBPW/2)*ZBYTEW);
                    break;
                default:
                    val = ((btact->memrec)+idx)->infblk[type];
            }
        }
    }
    return(val);
}
Пример #5
0
int brepky(BTint blk,int loc,char *key,BTint val,BTint link1,BTint link2)
{
    int idx,ioerr;

    if (loc >= ZMXKEY || loc < 0) {
        bterr("BREPKY",QLOCTB,itostr(loc));
    }
    else {
        ioerr = brdblk(blk,&idx);
        if (idx < 0) {
            bterr("BREPKY",QRDBLK,itostr(blk));
        }
        else {
            strcpy(((btact->memrec)+idx)->keyblk[loc],key);
            ((btact->memrec)+idx)->valblk[loc] = val;
            ((btact->memrec)+idx)->lnkblk[loc] = link1;
            ((btact->memrec)+idx)->lnkblk[loc+1] = link2;
            ((btact->cntrl)+idx)->writes++;
#if DEBUG >= 1
            printf("BREPKY: Replaced target at blk: " ZINTFMT ", pos: %d\n",
                   blk,loc);
            printf(" ..using '%s', val = " ZINTFMT ", llink = " ZINTFMT
                   ", rlink = " ZINTFMT "\n",
                        key,val,link1,link2);
#endif
        }
    }
    return(0);
}
Пример #6
0
void balblk() 
{
    BTint val,llink,rlink,cblk;
    int nkeys,cnkeys,result,diff;
    char tkey[ZKYLEN];

    cblk = btact->cntxt->lf.lfblk;
    /* get parent block */
    btact->cntxt->lf.lfpos = bpull();
    btact->cntxt->lf.lfblk = bpull();
    nkeys = bgtinf(btact->cntxt->lf.lfblk,ZNKEYS);
    cnkeys = bgtinf(cblk,ZNKEYS);
    if (btact->cntxt->lf.lfpos < nkeys) {
        /* check right sister block */
        bsrhbk(btact->cntxt->lf.lfblk,tkey,&btact->cntxt->lf.lfpos,&val,
               &llink,&rlink,&result);
        if (result != 0) {
            bterr("BALBLK",QBALSE,NULL);
            goto fin;
        }
        nkeys = bgtinf(rlink,ZNKEYS);
        diff = cnkeys-nkeys;
        if (abs(diff) > (int)(ZMXKEY/2)) {
            balbk1(cblk,rlink,diff,tkey,val);
            goto fin;
        }
    }
    if (btact->cntxt->lf.lfpos > 0) {
        /* check left sister block */
        btact->cntxt->lf.lfpos--;
        bsrhbk(btact->cntxt->lf.lfblk,tkey,&btact->cntxt->lf.lfpos,
               &val,&llink,&rlink,&result);
        if (result != 0) {
            bterr("BALBLK",QBALSE,NULL);
            goto fin;
        }
        nkeys = bgtinf(llink,ZNKEYS);
        diff = nkeys-cnkeys;
        if (abs(diff) > (int)(ZMXKEY/2)) {
            balbk1(llink,cblk,diff,tkey,val);
            goto fin;
        }
        btact->cntxt->lf.lfpos++;
    }
    /* no balancing possible; restore original environment */
    bpush(btact->cntxt->lf.lfblk);
    bpush(btact->cntxt->lf.lfpos);
    btact->cntxt->lf.lfblk = cblk;
fin:
    return;
}
Пример #7
0
int binsky(BTA *b, char *key,BTint val)
{
    BTint lval,dups_allowed;
    int status;
    KEYENT keyent;
    
    bterr("",0,NULL);
    if ((status=bvalap("BINSKY",b)) != 0) return(status);

    btact = b;
    if (btact->shared) {
        if (!block()) {
            bterr("BINSKY",QBUSY,NULL);
            goto fin;
        }
    }

    if (b->cntxt->super.smode != 0) {
        /* read only, can't insert */
        bterr("BINSKY",QNOWRT,NULL);
    }
    else {
        dups_allowed = bgtinf(btact->cntxt->super.scroot,ZMISC);
        strncpy(keyent.key,key,ZKYLEN);
        keyent.key[ZKYLEN-1] = '\0';
        keyent.val = val;
        keyent.dup = ZNULL;
        status = bfndky(b,keyent.key,&lval);
        if (status == QNOKEY || (status == 0 && dups_allowed)) {
            /* QNOKEY is not an error in this context; remove it */
            bterr("",0,NULL);
            if (status == 0) {
                /* inserting duplicate key */
                btdupkey(key,val);
            }
            else {
                bleaf(1);
                bputky(btact->cntxt->lf.lfblk,&keyent,ZNULL,ZNULL);
            }
        }
        else {
            bterr("BINSKY",QDUP,key);
        }
    }
fin:
    if (btact->shared) bulock();
    return(btgerr());
}
Пример #8
0
/*
  btsync: sync memory blocks with B tree index file
    
  returns zero if no errors, error code otherwise
*/
int btsync()
{
    int i,ioerr;

    if (btact->idxunt != NULL) {
        /* write out all in-memory blocks */
        for (i=0;i<ZMXBLK;i++) {
            ioerr = bwrblk(((btact->cntrl)+i)->inmem);
            if (ioerr != 0) {
                bterr("BTSYNC",QWRBLK,itostr(((btact->cntrl)+i)->inmem));
                goto fin;
            }
        } 
        /* write super block if necessary */
        if (btact->cntxt->super.smod != 0) {
            if ( bwrsup() != 0) goto fin;
            btact->cntxt->super.smod = 0;
        }
    }

    /* force writes to disk */
    fflush(btact->idxunt);

    /* re-initialise control blocks to ensure blocks will be re-read
       from disk */
    initcntrl(btact);
    
fin:
    return(btgerr());
}
Пример #9
0
int bulock(void)
{
    if (btact->lckcnt > 1) {
        /* don't unlock if lock request nested (only top level will
         * unlock) */
#if DEBUG >= 2
        fprintf(stderr,"BULOCK: soft unlock - lckcnt %d\n",btact->lckcnt);
#endif      
        btact->lckcnt--;
        return(0);
    }
    else if (btact->lckcnt == 1) {
#if DEBUG >= 2
        fprintf(stderr,"BULOCK: hard unlock - lckcnt %d\n",btact->lckcnt);
#endif
    
        /* write any changed in-memory blocks to file */
        btsync();
    
        if (btact->fd >= 0) {
            lck.l_type = F_UNLCK;
            if (fcntl(btact->fd,F_SETLK,&lck) == -1) {
                bterr("BULOCK",QUNLCK,NULL);
            }
        }
        btact->lckcnt = 0;
    }
    
    return(0);
}   
Пример #10
0
int context_ok(char* fun)
{
    if (btact->cntxt->lf.lfblk == ZNULL || btact->cntxt->lf.lfpos == ZNULL
        || !btact->cntxt->lf.lfexct) {
        bterr(fun,QBADCTXT,NULL);
        return FALSE;
    }
    return TRUE;
}
Пример #11
0
int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
{
	BT_DBG("hcon %p reason %d", hcon, reason);

	if (hcon->type != SCO_LINK)
		return 0;

	sco_conn_del(hcon, bterr(reason));
	return 0;
}
Пример #12
0
static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
{
	BT_DBG("hcon %p reason %d", hcon, reason);

	if (hcon->type != ACL_LINK)
		return 0;

	l2cap_conn_del(hcon, bterr(reason));
	return 0;
}
Пример #13
0
int bqmove(int idx)
{
    int i;
    
#if DEBUG >= 4
    printf("Before move of idx %d:  lruh: %d, lrut: %d\n",idx,btact->cntxt->lru.lruh,btact->cntxt->lru.lrut);
    for (i=0;i<ZMXBLK;i++) printf("lrunxt[%d] = %d  ",i,((btact->cntrl)+i)->lrunxt);
    printf("\n");
#endif
    if (idx < 0) {
        bterr("BQMOVE",QBADIX,itostr(idx));
        goto fin;
    }
    if (idx == btact->cntxt->lru.lrut) return(0);
     
    if (idx == btact->cntxt->lru.lruh)
        btact->cntxt->lru.lruh = ((btact->cntrl)+idx)->lrunxt;
    else {
        i = btact->cntxt->lru.lruh;
        while (i>=0) {
            if (((btact->cntrl)+i)->lrunxt == idx) break;
            i = ((btact->cntrl)+i)->lrunxt;
        }
        if (i >= 0)
            ((btact->cntrl)+i)->lrunxt = ((btact->cntrl)+idx)->lrunxt;
        else {
            bterr("BQMOVE",QLRUER,itostr(idx));
        }
    }
    ((btact->cntrl)+btact->cntxt->lru.lrut)->lrunxt = idx;
    ((btact->cntrl)+idx)->lrunxt = -1;
    btact->cntxt->lru.lrut = idx;
#if DEBUG >= 4
    printf("After move:  lruh: %d, lrut: %d\n",btact->cntxt->lru.lruh,
           btact->cntxt->lru.lrut);
    for (i=0;i<ZMXBLK;i++) printf("lrunxt[%d] = %d  ",i,
                                  ((btact->cntrl)+i)->lrunxt);
    printf("\n");
#endif
fin:
    return(0);
}
Пример #14
0
int block(void)
{
    int i, ierr;
    
    if (btact->lckcnt > 0 ) {
        btact->lckcnt++;
#if DEBUG >= 2
        fprintf(stderr,"BLOCK: soft lock - lcknt %d\n",btact->lckcnt);
#endif      
        return (TRUE);  /* lock already in use for this process */
    }

    lck.l_type = F_WRLCK;
    if (signal(SIGALRM,sigalrm_handler) == SIG_ERR) {
        bterr("BLOCK",QBADAL,NULL);
        return(FALSE);
    }   

    /* save current signal mask in environment; enables proper repeat
     * behaviour when repetive calls to block are made */
    if (sigsetjmp(env_alrm,1) != 0) {
        /* get here when alarm goes off; couldn't lock file */
        signal(SIGALRM,SIG_DFL);
        alarm(0);
        return(FALSE);
    }

    alarm(ZSLEEP);
    
    if (fcntl(btact->fd,F_SETLKW,&lck) == -1) {
        signal(SIGALRM,SIG_DFL);
        alarm(0);
        return(FALSE); 
    }
    alarm(0); 
    
#if DEBUG >= 2
    fprintf(stderr,"BLOCK: hard lock - lcknt %d\n",btact->lckcnt);
#endif
    if (btact->shared && btact->cntxt->super.scroot != ZNULL) {
        /* ensure super block info is up-to-date */
        brdsup(); 
        /* ensure current root is in memory and locked */
        /* if not creating new index file (when scroot is ZNULL) */
        ierr = brdblk(btact->cntxt->super.scroot,&i);
        if (ierr == 0) {
            bsetbs(btact->cntxt->super.scroot,1);
        }
    }
    btact->lckcnt = 1;
    return(TRUE);
}
Пример #15
0
static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
{
	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);

	if (hcon->type != ACL_LINK)
		return 0;

	if (!status) {
		struct l2cap_conn *conn;

		conn = l2cap_conn_add(hcon, status);
		if (conn)
			l2cap_conn_ready(conn);
	} else 
		l2cap_conn_del(hcon, bterr(status));
	
	return 0;
}
Пример #16
0
int bsetbk(BTint blk,BTint type,BTint misc,BTint nxblk,BTint nkeys,
           BTint nblks,BTint dupblk)
{
    int ioerr,idx;
    
    ioerr = brdblk(blk,&idx);
    if (idx < 0) {
        bterr("BSETBK",QRDBLK,itostr(blk));
    }
    else {
        bstinf(blk,ZBTYPE,type);
        ((btact->memrec)+idx)->infblk[ZMISC] = misc;
        ((btact->memrec)+idx)->infblk[ZNXBLK] = nxblk;
        ((btact->memrec)+idx)->infblk[ZNKEYS] = nkeys;
        ((btact->memrec)+idx)->infblk[ZNBLKS] = nblks;
        ((btact->memrec)+idx)->infblk[ZNXDUP] = dupblk;
        ((btact->cntrl)+idx)->writes++;
    }
    return(0);
}
Пример #17
0
int bwrblk(BTint blk)
{
    BTint pos;
    int i,ioerr;
    
    ioerr = 0;
    for (i=0;i<ZMXBLK;i++)
        if (((btact->cntrl)+i)->inmem == blk) break;

    if (i == ZMXBLK) {
        bterr("BWRBLK",QWRMEM,itostr(blk));
    }
    else {
        if (((btact->cntrl)+i)->writes != 0) {
            pos = fseeko(btact->idxunt,blk*ZBLKSZ,SEEK_SET);
            if (pos >= 0) {
                if ((ioerr = fwrite((btact->memrec)+i,sizeof(char),
                        ZBLKSZ, btact->idxunt)) == ZBLKSZ) {
                    btact->cntxt->stat.xphywr++;
                    ioerr = 0;
#if DEBUG > 0
                    fprintf(stderr,"BWRBLK: writing block " ZINTFMT
                            ", from idx %d\n",blk,i);
#endif                  
                }
                else {
                    ioerr = -1;
                }
            }
            else {
                ioerr = -1;
            }
            
        }
        else {
             btact->cntxt->stat.xlogwr++;
        }
    }
    ((btact->cntrl)+i)->writes = 0;
    return(ioerr);
}
Пример #18
0
int bputky(BTint blk,char *key,BTint val,BTint link1,BTint link2)
{
    int i,idx,ioerr;
    char lkey[ZKYLEN];
    
#if DEBUG >= 1
    fprintf(stderr,
            "bputky: blk = " ZINTFMT ", key = %s, val = " ZINTMFT
            ", link1 = " ZINTFMT ", link2 = " ZINTFMT "\n",
            blk,key,val,link1,link2);
#endif
    ioerr = brdblk(blk,&idx);
    if (idx < 0) {
        bterr("BPUTKY",QRDBLK,itostr(blk));
    }
    else {
        /* get local copy of key, truncated if necessary */
        strncpy(lkey,key,ZKYLEN);
        lkey[ZKYLEN-1] = '\0';
        if (((btact->memrec)+idx)->infblk[ZNKEYS] == ZMXKEY) {
            bterr("BPUTKY",QBLKFL,itostr(blk));
            goto fin;
        }
        if (((btact->memrec)+idx)->infblk[ZNKEYS] == 0) {
            /* block empty */
            strcpy(((btact->memrec)+idx)->keyblk[0],lkey);
            ((btact->memrec)+idx)->valblk[0] = val;
            ((btact->memrec)+idx)->lnkblk[0] = link1;
            ((btact->memrec)+idx)->lnkblk[1] = link2;
        }
        else {  
            for (i=((btact->memrec)+idx)->infblk[ZNKEYS];i>0;i--) {
                if (strcmp(key,((btact->memrec)+idx)->keyblk[i-1]) < 0) {
                    /* move info to make room */
                    strcpy(((btact->memrec)+idx)->keyblk[i],
                        ((btact->memrec)+idx)->keyblk[i-1]);
                    ((btact->memrec)+idx)->valblk[i] = 
                        ((btact->memrec)+idx)->valblk[i-1];
                    ((btact->memrec)+idx)->lnkblk[i+1] = 
                        ((btact->memrec)+idx)->lnkblk[i];
                }
                else break;
            }
            /* move left link if inserting in first position */
            if (i == 0) ((btact->memrec)+idx)->lnkblk[1] = 
                ((btact->memrec)+idx)->lnkblk[0];
            strcpy(((btact->memrec)+idx)->keyblk[i],lkey);
            ((btact->memrec)+idx)->valblk[i] = val;
            if (link1 == ZNULL && link2 == ZNULL) {
                /* inserting a leaf key */
                ((btact->memrec)+idx)->lnkblk[i] = ZNULL;
                ((btact->memrec)+idx)->lnkblk[i+1] = ZNULL;
            }
            else {
                /* if inserting in first pos, then use llink */
                if (i == 0) ((btact->memrec)+idx)->lnkblk[0] = link1;
                /* rlink is inserted if ZERO or positive */
                if (link2 >= 0) ((btact->memrec)+idx)->lnkblk[i+1] = link2;
            }
        }
    }
    ((btact->memrec)+idx)->infblk[ZNKEYS]++;
    ((btact->cntrl)+idx)->writes++;
fin:
    return(0);
}
Пример #19
0
int bnxtky(BTA* b,char *key,BTint *val)
{
    int idx,nkeys,status;
    int found;

    bterr("",0,NULL);
    if ((status=bvalap("BNXTKY",b)) != 0) return(status);

    btact = b;          /* set global context pointer */

    if (btact->shared) {
        if (!block()) {
            bterr("BNXTKY",QBUSY,NULL);
            goto fin;
        }
    }
    
    /* handle duplicate positioning */
    found = btduppos(ZNEXT,val);
    if (found > 0) {
        goto fin;
    }
    else if (found == 0) {
        strncpy(key,btact->cntxt->lf.lfkey,ZKYLEN);
        key[ZKYLEN-1] = '\0';
        goto fin;
    }
            
    if (btact->shared && btact->cntxt->lf.lfblk != ZNULL) {
        /* position to last found key via bfndky, since context could
         * have been invalidated by concurrent updates by other users.
         * Note we don't care if the key is found or not, so the error
         * status is always cleared. */
        status = bfndky(btact,btact->cntxt->lf.lfkey,val);
        bterr("",0,NULL);
    }
    
    found = FALSE;
    while (btact->cntxt->lf.lfblk != ZNULL && !found) {
        status = brdblk(btact->cntxt->lf.lfblk,&idx);
        if (idx < 0) {
            bterr("BNXTKY",QRDBLK,itostr(btact->cntxt->lf.lfblk));
            break;
        }
        nkeys = bgtinf(btact->cntxt->lf.lfblk,ZNKEYS);
#if DEBUG >= 1
        printf("BNXTKY: lfblk: " ZINTFMT ", lfpos: %d, nkeys: %d\n",
               btact->cntxt->lf.lfblk,btact->cntxt->lf.lfpos,nkeys);
#endif
        if (btact->cntxt->lf.lfpos >= nkeys || nkeys == 0) {
            /* finished with this block (or no key was found at all),
             * get parent from stack */
            btact->cntxt->lf.lfpos = bpull();
            btact->cntxt->lf.lfblk = bpull();
            btact->cntxt->lf.lfexct = FALSE; 
            continue;
        }

        if (!btact->cntxt->lf.lfexct) {
            btact->cntxt->lf.lfexct = TRUE;
        }
        else {
            btact->cntxt->lf.lfpos++;
            /* invalidate existing dup chain */
            btact->cntxt->lf.draddr = ZNULL; 
            idx = bleaf(0);
            if (idx < 0) continue;
        }
        
        if (btact->cntxt->lf.lfpos < nkeys) {
            found = TRUE;
            strncpy(key,
                    ((btact->memrec)+idx)->keyblk[btact->cntxt->lf.lfpos].key,
                    ZKYLEN);
            key[ZKYLEN-1] = '\0';
            /* remember found key (need for shared mode) */
            strncpy(btact->cntxt->lf.lfkey,key,ZKYLEN);
            btact->cntxt->lf.lfkey[ZKYLEN-1] = '\0';
            *val = ((btact->memrec)+idx)->keyblk[btact->cntxt->lf.lfpos].val;
            btduppos(ZNEXT,val);
        }
    }
    if (btact->cntxt->lf.lfblk == ZNULL) {
        /* end of index reached */
        bclrlf();
        bterr("BNXTKY",QNOKEY,NULL);
    }
fin:
    if (btact->shared) bulock();
    return btgerr();
}
Пример #20
0
KEYENT* bsrhbk(BTint blk, char *key, int *loc, BTint *val, BTint *link1,
               BTint *link2, int *result)
{
    int quit,idx,lo,hi,md,ioerr,nkeys;
    KEYENT* keyentp = NULL;
    
    ioerr = brdblk(blk,&idx);
    if (idx < 0) {
        bterr("BSRHBK",QRDBLK,itostr(blk));
        goto fin;
    }
    nkeys = ((btact->memrec)+idx)->infblk[ZNKEYS];
#if DEBUG > 0
    printf("BSRHBK: blk: " ZINTFMT ", nkeys: %d\n",blk,nkeys);
    printf("BSRHBK: loc: %d, val: " ZINTFMT ", link1: " ZINTFMT ", link2: "
           ZINTFMT "\n",*loc,*val,*link1,*link2);
#endif  
    if (*loc >= 0) {
        if (*loc >= nkeys) {
            /* requested loc not in block range */
            *result = -1;
            goto fin;
        }
        else {
            *result = 0;
            strncpy(key,((btact->memrec)+idx)->keyblk[*loc].key,ZKYLEN);
            key[ZKYLEN-1] = '\0';
        }
    }
    else {
        /* binary search */
        *loc = -1; /* init location at impossible position */
        *result = -1;
        quit = FALSE;
        lo = 0;
        hi = nkeys-1;
        md = -1;
        while (lo <= hi && !quit) {
            quit = (lo == hi);
            md = (lo+hi)/2;
            *result = strcmp(key,((btact->memrec)+idx)->keyblk[md].key);
#if DEBUG >= 2
            printf("key: \"%s\" vs \"%s\"\n",key,
                   ((btact->memrec)+idx)->keyblk[md].key);
            printf("lo: %d, hi: %d, md: %d\n",lo,hi,md);
            printf("result: %d, quit: %d\n",*result,quit);
#endif
            if (*result > 0) {
                lo = md+1;
            }
            else  if (*result < 0) {
                hi = md-1;
            }
            else {
                break;
            }
        }
        *loc = md;
    }

    if (*loc < 0) {
        *val = 0;
        *link1 = ZNULL;
        *link2 = ZNULL;
    }
    else {
        *val = ((btact->memrec)+idx)->keyblk[*loc].val;
        *link1 = ((btact->memrec)+idx)->lnkblk[*loc];
        *link2 = ((btact->memrec)+idx)->lnkblk[*loc+1];
        keyent = ((btact->memrec)+idx)->keyblk[*loc];
        keyentp = &keyent;
#if DEBUG >=2
        fprintf(stderr,"BSRHBK: val: " ZINTFMT ", link1: " ZINTFMT ", link2: "
                ZINTFMT "\n",*val,*link1,*link2);
#endif      
    }
fin:
    return keyentp;
}
Пример #21
0
/* Checks structure of index file, from current root.  Returns number
 * of keys found or ZNULL if structure is damaged (either empty blocks
 * that are non-root, or inconsistent leaf depth). */
BTint btkeys(BTA* b,int stats)
{
    BTint tblks = 0,
        tnkeys = 0,
        empty_blk = ZNULL,
        blkno = ZNULL;
    BTint val,link1,link2;
    int ioerr,idx,result,loc = 0;
    int blk_depth[STKMAX+1];
    int leaf_depth = -1,balanced = TRUE;
    char key[ZKYLEN];

    
    bterr("",0,NULL);
    if ((ioerr=bvalap("BTKEYS",b)) != 0) return(ioerr);

    if (btact->shared) {
        if (!block()) {
            bterr("BTKEYS",QBUSY,NULL);
            goto fin;
        }
    }
    
    btact = b;          /* set context pointer */
    
    if (btact->idxunt == NULL) {
        bterr("BTKEYS",QNOBTF,NULL);
        goto fin;
    }

    for (idx=0;idx<=STKMAX;idx++) blk_depth[idx] = 0;
    
    tblks = 0; tnkeys = 0; blkno = ZNULL;
    do {
        int depth,nkeys;
        bnxtbk(&blkno);
        depth =  btstk_depth()/2;
        tblks++;
        blk_depth[depth]++;
        ioerr = brdblk(blkno,&idx);
        nkeys = bgtinf(blkno,ZNKEYS);
        if (nkeys == 0 && empty_blk == ZNULL) {
            if (bgtinf(blkno,ZBTYPE) != ZROOT) empty_blk = blkno;
        }
        else {
            bsrhbk(blkno,key,&loc,&val,&link1,&link2,&result);
            if (link1 == ZNULL) {
                if (leaf_depth < 0) {
                    leaf_depth = depth;
                }
                else if (leaf_depth != depth) {
                    balanced = FALSE;
                    if (depth > leaf_depth) leaf_depth = depth;
                }
            }
            nkeys = btcntkeys(blkno);
            if (nkeys == ZNULL) return FALSE;
            tnkeys += nkeys;
        }
    } while (blkno != btact->cntxt->super.scroot);

    if (stats) {
        printf("Block stats:\n");
        if (empty_blk != ZNULL) {
            printf("At least one non-root block has no keys.  "
                   "First encountered was " ZINTFMT "\n",empty_blk);
        }
        printf("Index balanced: %s\n",(balanced)?"YES":"NO");
        printf("Max leaf depth: %d\n",leaf_depth);
        printf("Depth   Number of blocks\n");
        for (idx=0;idx<=leaf_depth;idx++) {
            printf("%5d %18d\n",idx,blk_depth[idx]);
        }       
    }
    
  fin:
    return (empty_blk != ZNULL || !balanced)?ZNULL:tnkeys;
}
Пример #22
0
void bdemte(BTint *cblk)
{
    BTint newblk,val,link1,link2,jblk,llink,rlink;
    int nkeys,type,result;
    int rblke;
    char tkey[ZKYLEN];

    nkeys = bgtinf(btact->cntxt->lf.lfblk,ZNKEYS);
    if (nkeys == 0) {
        type = bgtinf(btact->cntxt->lf.lfblk,ZBTYPE);
        if (type != ZROOT) {
            /* pull parent */
            btact->cntxt->lf.lfpos = bpull();
            btact->cntxt->lf.lfblk = bpull();
            nkeys = bgtinf(btact->cntxt->lf.lfblk,ZNKEYS);
            if (btact->cntxt->lf.lfpos != 0) { 
                /* ensure that empty block is on the right */
                rblke = TRUE;
                btact->cntxt->lf.lfpos--;
            }
            else {
                /* first block empty, so can't put on right */
                rblke = FALSE;
            }
            bsrhbk(btact->cntxt->lf.lfblk,tkey,&btact->cntxt->lf.lfpos,&val,
                   &link1,&link2,&result);
            if (result != 0) {
                bterr("BDEMTE",QDEMSE,NULL);
                goto fin;
            }
#if DEBUG >= 1
            printf("BDEMTE: Demoting key %s from blk: " ZINTFMT "\n",tkey,
                   btact->cntxt->lf.lfblk);
#endif
            /* remove key from original block */
            bremky(btact->cntxt->lf.lfblk,btact->cntxt->lf.lfpos);
            /* prepare for split check */
            if (rblke) 
                jblk = link1;
            else
                jblk = link2;
        
            /* if target block for demotion is full, split it */
            nkeys = bgtinf(jblk,ZNKEYS);
            if (nkeys == ZMXKEY) {
                bsptbk(jblk,&newblk);
                if (newblk == ZNULL) {
                    bterr("BDEMTE",QDEMSP,NULL);
                    goto fin;
                }
                if (rblke) {
                    link1 = newblk;
                }
            }
            if (!rblke) {
                /* copy keys from right block to empty left block */
                nkeys = bgtinf(link2,ZNKEYS);
                bsetbs(link1,1);
                bcpybk(link1,link2,0,0,nkeys);
                bstinf(link1,ZNKEYS,nkeys);
                bsetbs(link1,0);
                llink = *cblk;
                rlink = ZNULL; /* 0 replaced by ZNULL for C */
            }
            else {
                llink = ZNULL;  /* 0 replaced by ZNULL for C */
                rlink = *cblk;
            }
            bputky(link1,tkey,val,llink,rlink);
            bmkfre(link2);
            /* set new potentially dangling block */
            *cblk = link1;
        }
        else { 
            /* empty block is root; copy keys from child and then free
             * the child block */
            nkeys = bgtinf(*cblk,ZNKEYS);
            bcpybk(btact->cntxt->lf.lfblk,*cblk,0,0,nkeys);
            bstinf(btact->cntxt->lf.lfblk,ZNKEYS,nkeys);
            bmkfre(*cblk);
            *cblk = ZNULL;
        }
    }
    else {
        *cblk = ZNULL;
    }
fin:
    return;
}
Пример #23
0
int bfndky(BTA *b,char *key,BTint *val)
{
    BTint cblk, link1, link2, newblk;
    int index, result, nkeys, status;
    char lkey[ZKYLEN];
    
    bterr("",0,NULL);
    status = QNOKEY;
    if ((result=bvalap("BFNDKY",b)) != 0) return(result);

    btact = b;      /* set context pointer */

    if (btact->shared) {
        if (!block()) {
            bterr("BFNDKY",QBUSY,NULL);
            goto fin;
        }
    }

    /* take local copy of key, truncating if necessary */
    strncpy(lkey,key,ZKYLEN);
    lkey[ZKYLEN-1] = '\0';
    
    /* initialise stack etc */
    btact->cntxt->lf.lfexct = FALSE;
    cblk = btact->cntxt->super.scroot;
    bstkin();
    btact->cntxt->lf.lfblk = -1;
    btact->cntxt->lf.lfpos = -1;
    strcpy(btact->cntxt->lf.lfkey,lkey);

    while (cblk >= 0) {
#if DEBUG >= 2
        fprintf(stderr,"BFNDKY: searching block " ZINTFMT "\n",cblk);
#endif      
        nkeys = bgtinf(cblk,ZNKEYS);
        if (nkeys == ZMXKEY && btact->cntxt->super.smode == 0) {
            /* split if block full and updating permitted */
            bsptbk(cblk,&newblk);
            if (newblk < 0) {
                bterr("BFNDKY",QSPLIT,NULL);
                break;
            }
            /* if split occured, then must re-examine parent */
            if (cblk != btact->cntxt->super.scroot) {
                index  = btact->cntxt->lf.lfpos;
                cblk = btact->cntxt->lf.lfblk;
                btact->cntxt->lf.lfpos = bpull();
                btact->cntxt->lf.lfblk = bpull();
            }
        }
        else {
            index = -1;
            bpush(btact->cntxt->lf.lfblk);
            bpush(btact->cntxt->lf.lfpos);
            bsrhbk(cblk,lkey,&index,val,&link1,&link2,&result);
            btact->cntxt->lf.lfblk = cblk;
            btact->cntxt->lf.lfpos = index; /* if block is empty, leave lfpos at -1 */
            if (result < 0) {
                /* must examine left block */
                cblk = link1;
                continue;
            }
            else if (result > 0) {
                /* must examine right block */
                cblk = link2;
                /* increment index to indicate this key "visited" */
                btact->cntxt->lf.lfpos++;
                continue;
            }
            else {
                status = 0;
                btact->cntxt->lf.lfexct = TRUE;
                break;
            }
        }
    }  
fin:
    if (btact->shared) bulock();
    /* non-zero status indicates no such key found */
    if (status) bterr("BFNDKY",QNOKEY,lkey);
    return(btgerr());
}