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; }
/* Initialize the file system structure from disk */ int fs_init(mem_sblock_t sbp) { blocknum_t inode_bitmap_size; blocknum_t block_bitmap_size; blocknum_t i; sbp->filesys_lock = semaphore_new(1); if (NULL == sbp->filesys_lock) { return -1; } fs_lock(sbp); sblock_get(maindisk, sbp); sblock_put(sbp); if (sblock_isvalid(sbp) != 1) { sblock_print(sbp); kprintf("File system is not recognized. "); kprintf("Recommend running './mkfs <blocks>'.\n"); return -2; } inode_bitmap_size = sbp->inode_bitmap_last - sbp->inode_bitmap_first + 1; sbp->inode_bitmap = malloc(inode_bitmap_size * DISK_BLOCK_SIZE); block_bitmap_size = sbp->block_bitmap_last - sbp->block_bitmap_first + 1; sbp->block_bitmap = malloc(block_bitmap_size * DISK_BLOCK_SIZE); if (NULL == sbp->block_bitmap || NULL == sbp->inode_bitmap) { semaphore_V(sbp->filesys_lock); return -1; } /* Get disk bitmap */ for (i = sbp->inode_bitmap_first; i <= sbp->inode_bitmap_last; ++i) { bpull(i, (char*) sbp->inode_bitmap + (i - sbp->inode_bitmap_first) * DISK_BLOCK_SIZE); } for (i = sbp->block_bitmap_first; i <= sbp->block_bitmap_last; ++i) { bpull(i, (char*) sbp->block_bitmap + (i - sbp->block_bitmap_first) * DISK_BLOCK_SIZE); } /* Count free inodes and free blocks */ mainsb->free_inodes = bitmap_count_zero(mainsb->inode_bitmap, mainsb->total_inodes); mainsb->free_blocks = bitmap_count_zero(mainsb->block_bitmap, mainsb->disk_num_blocks); fs_unlock(sbp); return 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; }
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()); }
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(); }