Ejemplo n.º 1
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);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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();
}
Ejemplo n.º 8
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);
}