📄 villa.c
字号:
} if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } } return TRUE;}/* Move the cursor to the last record. */int vlcurlast(VILLA *villa){ VLLEAF *leaf; VLREC *recp; assert(villa); villa->curleaf = villa->last; if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } while(CB_LISTNUM(leaf->recs) < 1){ villa->curleaf = leaf->prev; if(villa->curleaf == -1){ villa->curleaf = -1; dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } } villa->curknum = CB_LISTNUM(leaf->recs) - 1; recp = (VLREC *)CB_LISTVAL(leaf->recs, villa->curknum, NULL); villa->curvnum = recp->rest ? CB_LISTNUM(recp->rest) : 0; return TRUE;}/* Move the cursor to the previous record. */int vlcurprev(VILLA *villa){ VLLEAF *leaf; VLREC *recp; assert(villa); if(villa->curleaf == -1){ dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf)) || CB_LISTNUM(leaf->recs) < 1){ villa->curleaf = -1; return FALSE; } recp = (VLREC *)CB_LISTVAL(leaf->recs, villa->curknum, NULL); villa->curvnum--; if(villa->curvnum < 0){ villa->curknum--; if(villa->curknum < 0){ villa->curleaf = leaf->prev; if(villa->curleaf == -1){ villa->curleaf = -1; dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } while(CB_LISTNUM(leaf->recs) < 1){ villa->curleaf = leaf->prev; if(villa->curleaf == -1){ dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } } villa->curknum = CB_LISTNUM(leaf->recs) - 1; recp = (VLREC *)CB_LISTVAL(leaf->recs, villa->curknum, NULL); villa->curvnum = recp->rest ? CB_LISTNUM(recp->rest) : 0; } recp = (VLREC *)CB_LISTVAL(leaf->recs, villa->curknum, NULL); villa->curvnum = recp->rest ? CB_LISTNUM(recp->rest) : 0; } if(!villa->tran && !vlcacheadjust(villa)) return FALSE; return TRUE;}/* Move the cursor to the next record. */int vlcurnext(VILLA *villa){ VLLEAF *leaf; VLREC *recp; assert(villa); if(villa->curleaf == -1){ dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf)) || CB_LISTNUM(leaf->recs) < 1){ villa->curleaf = -1; return FALSE; } recp = (VLREC *)CB_LISTVAL(leaf->recs, villa->curknum, NULL); villa->curvnum++; if(villa->curvnum > (recp->rest ? CB_LISTNUM(recp->rest) : 0)){ villa->curknum++; villa->curvnum = 0; } if(villa->curknum >= CB_LISTNUM(leaf->recs)){ villa->curleaf = leaf->next; villa->curknum = 0; villa->curvnum = 0; if(villa->curleaf == -1){ dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } while(CB_LISTNUM(leaf->recs) < 1){ villa->curleaf = leaf->next; villa->curknum = 0; villa->curvnum = 0; if(villa->curleaf == -1){ dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } } } if(!villa->tran && !vlcacheadjust(villa)) return FALSE; return TRUE;}/* Move the cursor to positon around a record. */int vlcurjump(VILLA *villa, const char *kbuf, int ksiz, int jmode){ VLLEAF *leaf; VLREC *recp; int pid, index; assert(villa && kbuf); if(ksiz < 0) ksiz = strlen(kbuf); if((pid = vlsearchleaf(villa, kbuf, ksiz, NULL, NULL)) == -1){ villa->curleaf = -1; return FALSE; } if(!(leaf = vlleafload(villa, pid))){ villa->curleaf = -1; return FALSE; } while(CB_LISTNUM(leaf->recs) < 1){ villa->curleaf = (jmode == VL_JFORWARD) ? leaf->next : leaf->prev; if(villa->curleaf == -1){ dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } } if(!(recp = vlrecsearch(villa, leaf, kbuf, ksiz, &index))){ if(jmode == VL_JFORWARD){ villa->curleaf = leaf->id; if(index >= CB_LISTNUM(leaf->recs)) index--; villa->curknum = index; villa->curvnum = 0; recp = (VLREC *)CB_LISTVAL(leaf->recs, index, NULL); if(villa->cmp(kbuf, ksiz, CB_DATUMPTR(recp->key), CB_DATUMSIZE(recp->key)) < 0) return TRUE; villa->curvnum = (recp->rest ? CB_LISTNUM(recp->rest) : 0); return vlcurnext(villa); } else { villa->curleaf = leaf->id; if(index >= CB_LISTNUM(leaf->recs)) index--; villa->curknum = index; recp = (VLREC *)CB_LISTVAL(leaf->recs, index, NULL); villa->curvnum = (recp->rest ? CB_LISTNUM(recp->rest) : 0); if(villa->cmp(kbuf, ksiz, CB_DATUMPTR(recp->key), CB_DATUMSIZE(recp->key)) > 0) return TRUE; villa->curvnum = 0; return vlcurprev(villa); } } if(jmode == VL_JFORWARD){ villa->curleaf = pid; villa->curknum = index; villa->curvnum = 0; } else { villa->curleaf = pid; villa->curknum = index; villa->curvnum = (recp->rest ? CB_LISTNUM(recp->rest) : 0); } return TRUE;}/* Get the key of the record where the cursor is. */char *vlcurkey(VILLA *villa, int *sp){ VLLEAF *leaf; VLREC *recp; const char *kbuf; int ksiz; assert(villa); if(villa->curleaf == -1){ dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } recp = (VLREC *)CB_LISTVAL(leaf->recs, villa->curknum, NULL); kbuf = CB_DATUMPTR(recp->key); ksiz = CB_DATUMSIZE(recp->key); if(sp) *sp = ksiz; return cbmemdup(kbuf, ksiz);}/* Get the value of the record where the cursor is. */char *vlcurval(VILLA *villa, int *sp){ VLLEAF *leaf; VLREC *recp; const char *kbuf; int ksiz; assert(villa); if(villa->curleaf == -1){ dpecode = DP_ENOITEM; return FALSE; } if(!(leaf = vlleafload(villa, villa->curleaf))){ villa->curleaf = -1; return FALSE; } recp = (VLREC *)CB_LISTVAL(leaf->recs, villa->curknum, NULL); if(villa->curvnum < 1){ kbuf = CB_DATUMPTR(recp->first); ksiz = CB_DATUMSIZE(recp->first); } else { kbuf = cblistval(recp->rest, villa->curvnum - 1, &ksiz); } if(sp) *sp = ksiz; return cbmemdup(kbuf, ksiz);}/* Set the tuning parameters for performance. */void vlsettuning(VILLA *villa, int lrecmax, int nidxmax, int lcnum, int ncnum){ assert(villa); if(lrecmax < 1) lrecmax = VL_DEFLRECMAX; if(lrecmax < 3) lrecmax = 3; if(nidxmax < 1) nidxmax = VL_DEFNIDXMAX; if(nidxmax < 4) nidxmax = 4; if(lcnum < 1) lcnum = VL_DEFLCNUM; if(lcnum < VL_CACHEOUT * 2) lcnum = VL_CACHEOUT * 2; if(ncnum < 1) ncnum = VL_DEFNCNUM; if(ncnum < VL_CACHEOUT * 2) ncnum = VL_CACHEOUT * 2; villa->leafrecmax = lrecmax; villa->nodeidxmax = nidxmax; villa->leafcnum = lcnum; villa->nodecnum = ncnum;}/* Synchronize updating contents with the file and the device. */int vlsync(VILLA *villa){ int err, pid; const char *tmp; assert(villa); if(!villa->wmode){ dpecode = DP_EMODE; return FALSE; } if(villa->tran){ dpecode = DP_EMISC; return FALSE; } err = FALSE; cbmapiterinit(villa->leafc); while((tmp = cbmapiternext(villa->leafc, NULL)) != NULL){ pid = *(int *)tmp; if(!vlleafcacheout(villa, pid)) err = TRUE; } cbmapiterinit(villa->nodec); while((tmp = cbmapiternext(villa->nodec, NULL)) != NULL){ pid = *(int *)tmp; if(!vlnodecacheout(villa, pid)) err = TRUE; } if(!dpsetalign(villa->depot, 0)) err = TRUE; if(!vldpputnum(villa->depot, VL_ROOTKEY, villa->root)) err = TRUE; if(!vldpputnum(villa->depot, VL_LASTKEY, villa->last)) err = TRUE; if(!vldpputnum(villa->depot, VL_LNUMKEY, villa->lnum)) err = TRUE; if(!vldpputnum(villa->depot, VL_NNUMKEY, villa->nnum)) err = TRUE; if(!vldpputnum(villa->depot, VL_RNUMKEY, villa->rnum)) err = TRUE; if(!dpsync(villa->depot)) err = TRUE; return err ? FALSE : TRUE;}/* Optimize a database. */int vloptimize(VILLA *villa){ int err; assert(villa); if(!villa->wmode){ dpecode = DP_EMODE; return FALSE; } if(villa->tran){ dpecode = DP_EMISC; return FALSE; } err = FALSE; if(!vlsync(villa)) return FALSE; if(!dpsetalign(villa->depot, VL_OPTALIGN)) err = TRUE; if(!dpoptimize(villa->depot, -1)) err = TRUE; return err ? FALSE : TRUE;}/* Get the name of a database. */char *vlname(VILLA *villa){ assert(villa); return dpname(villa->depot);}/* Get the size of a database file. */int vlfsiz(VILLA *villa){ return dpfsiz(villa->depot);}/* Get the number of the leaf nodes of B+ tree. */int vllnum(VILLA *villa){ assert(villa); return villa->lnum;}/* Get the number of the non-leaf nodes of B+ tree. */int vlnnum(VILLA *villa){ assert(villa); return villa->nnum;}/* Get the number of the records stored in a database. */int vlrnum(VILLA *villa){ assert(villa); return villa->rnum;}/* Check whether a database handle is a writer or not. */int vlwritable(VILLA *villa){ assert(villa); return villa->wmode;}/* Check whether a database has a fatal error or not. */int vlfatalerror(VILLA *villa){ assert(villa); return dpfatalerror(villa->depot);}/* Get the inode number of a database file. */int vlinode(VILLA *villa){ assert(villa); return dpinode(villa->depot);}/* Begin the transaction. */int vltranbegin(VILLA *villa){ int err, pid; const char *tmp; VLLEAF *leaf; VLNODE *node; assert(villa); if(!villa->wmode){ dpecode = DP_EMODE; return FALSE; } if(villa->tran){ dpecode = DP_EMISC; return FALSE; } err = FALSE; cbmapiterinit(villa->leafc); while((tmp = cbmapiternext(villa->leafc, NULL)) != NULL){ pid = *(int *)tmp; leaf = (VLLEAF *)cbmapget(villa->leafc, (char *)&pid, sizeof(int), NULL); if(leaf->dirty){ if(!vlleafsave(villa, leaf)) err = TRUE; } } cbmapiterinit(villa->nodec); while((tmp = cbmapiternext(villa->nodec, NULL)) != NULL){ pid = *(int *)tmp; node = (VLNODE *)cbmapget(villa->nodec, (char *)&pid, sizeof(int), NULL); if(node->dirty){ if(!vlnodesave(villa, node)) err = TRUE; } } if(!dpsetalign(villa->depot, 0)) err = TRUE; if(!vldpputnum(villa->depot, VL_ROOTKEY, villa->root)) err = TRUE; if(!vldpputnum(villa->depot, VL_LASTKEY, villa->last)) err = TRUE; if(!vldpputnum(villa->depot, VL_LNUMKEY, villa->lnum)) err = TRUE; if(!vldpputnum(villa->depot, VL_NNUMKEY, villa->nnum)) err = TRUE; if(!vldpputnum(villa->depot, VL_RNUMKEY, villa->rnum)) err = TRUE; if(!dpmemsync(villa->depot)) err = TRUE; villa->tran = TRUE; villa->rbroot = villa->root; villa->rblast = villa->last; villa->rblnum = villa->lnum; villa->rbnnum = villa->nnum; villa->rbrnum = villa->rnum; return err ? FALSE : TRUE;}/* Commit the transaction. */int vltrancommit(VILLA *villa){ int err, pid; const char *tmp; VLLEAF *leaf; VLNODE *node; assert(villa);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -