?? tcbdb.c
字號(hào):
/* Synchronize updating contents on memory of a B+ tree database object. */bool tcbdbmemsync(TCBDB *bdb, bool phys){ assert(bdb); if(!bdb->open || !bdb->wmode){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return false; } bool err = false; bool clk = BDBLOCKCACHE(bdb); const char *vbuf; int vsiz; TCMAP *leafc = bdb->leafc; tcmapiterinit(leafc); while((vbuf = tcmapiternext(leafc, &vsiz)) != NULL){ int rsiz; BDBLEAF *leaf = (BDBLEAF *)tcmapiterval(vbuf, &rsiz); if(leaf->dirty && !tcbdbleafsave(bdb, leaf)) err = true; } TCMAP *nodec = bdb->nodec; tcmapiterinit(nodec); while((vbuf = tcmapiternext(nodec, &vsiz)) != NULL){ int rsiz; BDBNODE *node = (BDBNODE *)tcmapiterval(vbuf, &rsiz); if(node->dirty && !tcbdbnodesave(bdb, node)) err = true; } if(clk) BDBUNLOCKCACHE(bdb); tcbdbdumpmeta(bdb); if(!tchdbmemsync(bdb->hdb, phys)) err = true; return !err;}/* Clear the cache of a B+ tree database object. */bool tcbdbcacheclear(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return false; } bool err = false; if(TCMAPRNUM(bdb->leafc) > 0){ bool clk = BDBLOCKCACHE(bdb); TCMAP *leafc = bdb->leafc; tcmapiterinit(leafc); int rsiz; const void *buf; while((buf = tcmapiternext(leafc, &rsiz)) != NULL){ if(!tcbdbleafcacheout(bdb, (BDBLEAF *)tcmapiterval(buf, &rsiz))) err = true; } if(clk) BDBUNLOCKCACHE(bdb); } if(TCMAPRNUM(bdb->nodec) > 0){ bool clk = BDBLOCKCACHE(bdb); TCMAP *nodec = bdb->nodec; tcmapiterinit(nodec); int rsiz; const void *buf; while((buf = tcmapiternext(nodec, &rsiz)) != NULL){ if(!tcbdbnodecacheout(bdb, (BDBNODE *)tcmapiterval(buf, &rsiz))) err = true; } if(clk) BDBUNLOCKCACHE(bdb); } return !err;}/* Get the comparison function of a B+ tree database object. */TCCMP tcbdbcmpfunc(TCBDB *bdb){ assert(bdb); return bdb->cmp;}/* Get the opaque object for the comparison function of a B+ tree database object. */void *tcbdbcmpop(TCBDB *bdb){ assert(bdb); return bdb->cmpop;}/* Get the maximum number of cached leaf nodes of a B+ tree database object. */uint32_t tcbdblmemb(TCBDB *bdb){ assert(bdb); return bdb->lmemb;}/* Get the maximum number of cached non-leaf nodes of a B+ tree database object. */uint32_t tcbdbnmemb(TCBDB *bdb){ assert(bdb); return bdb->nmemb;}/* Get the number of the leaf nodes of B+ tree database object. */uint64_t tcbdblnum(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return bdb->lnum;}/* Get the number of the non-leaf nodes of B+ tree database object. */uint64_t tcbdbnnum(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return bdb->nnum;}/* Get the number of elements of the bucket array of a B+ tree database object. */uint64_t tcbdbbnum(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbbnum(bdb->hdb);}/* Get the record alignment of a B+ tree database object. */uint32_t tcbdbalign(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbalign(bdb->hdb);}/* Get the maximum number of the free block pool of a B+ tree database object. */uint32_t tcbdbfbpmax(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbfbpmax(bdb->hdb);}/* Get the inode number of the database file of a B+ tree database object. */uint64_t tcbdbinode(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbinode(bdb->hdb);}/* Get the modification time of the database file of a B+ tree database object. */time_t tcbdbmtime(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbmtime(bdb->hdb);}/* Get the additional flags of a B+ tree database object. */uint8_t tcbdbflags(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbflags(bdb->hdb);}/* Get the options of a B+ tree database object. */uint8_t tcbdbopts(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return bdb->opts;}/* Get the pointer to the opaque field of a B+ tree database object. */char *tcbdbopaque(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return NULL; } return bdb->opaque + BDBOPAQUESIZ;}/* Get the number of used elements of the bucket array of a B+ tree database object. */uint64_t tcbdbbnumused(TCBDB *bdb){ assert(bdb); if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return 0; } return tchdbbnumused(bdb->hdb);}/* Set the maximum size of each leaf node. */bool tcbdbsetlsmax(TCBDB *bdb, uint32_t lsmax){ assert(bdb); if(bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return false; } bdb->lsmax = (lsmax > 0) ? tclmax(lsmax, BDBMINLSMAX) : BDBDEFLSMAX; return true;}/* Set the capacity number of records. */bool tcbdbsetcapnum(TCBDB *bdb, uint64_t capnum){ assert(bdb); if(bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); return false; } bdb->capnum = capnum; return true;}/* Set the custom codec functions of a B+ tree database object. */bool tcbdbsetcodecfunc(TCBDB *bdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop){ assert(bdb && enc && dec); if(!BDBLOCKMETHOD(bdb, true)) return false; if(bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } bool rv = tchdbsetcodecfunc(bdb->hdb, enc, encop, dec, decop); BDBUNLOCKMETHOD(bdb); return rv;}/* Store a new record into a B+ tree database object with backward duplication. */bool tcbdbputdupback(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ assert(bdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } bool rv = tcbdbputimpl(bdb, kbuf, ksiz, vbuf, vsiz, BDBPDDUPB); BDBUNLOCKMETHOD(bdb); return rv;}/* Store a record into a B+ tree database object with a duplication handler. */bool tcbdbputproc(TCBDB *bdb, const void *kbuf, int ksiz, const char *vbuf, int vsiz, TCPDPROC proc, void *op){ assert(bdb && kbuf && ksiz >= 0 && proc); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } BDBPDPROCOP procop; procop.proc = proc; procop.op = op; BDBPDPROCOP *procptr = &procop; char stack[TCNUMBUFSIZ*2]; char *rbuf; if(ksiz <= sizeof(stack) - sizeof(procptr)){ rbuf = stack; } else { TCMALLOC(rbuf, ksiz + sizeof(procptr)); } char *wp = rbuf; memcpy(wp, &procptr, sizeof(procptr)); wp += sizeof(procptr); memcpy(wp, kbuf, ksiz); kbuf = rbuf + sizeof(procptr); bool rv = tcbdbputimpl(bdb, kbuf, ksiz, vbuf, vsiz, BDBPDPROC); if(rbuf != stack) TCFREE(rbuf); BDBUNLOCKMETHOD(bdb); return rv;}/* Store a new string record into a B+ tree database object with backward duplication. */bool tcbdbputdupback2(TCBDB *bdb, const char *kstr, const char *vstr){ assert(bdb && kstr && vstr); return tcbdbputdupback(bdb, kstr, strlen(kstr), vstr, strlen(vstr));}/* Move a cursor object to the rear of records corresponding a key. */bool tcbdbcurjumpback(BDBCUR *cur, const void *kbuf, int ksiz){ assert(cur && kbuf && ksiz >= 0); TCBDB *bdb = cur->bdb; if(!BDBLOCKMETHOD(bdb, false)) return false; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } bool rv = tcbdbcurjumpimpl(cur, kbuf, ksiz, false); BDBUNLOCKMETHOD(bdb); return rv;}/* Move a cursor object to the rear of records corresponding a key string. */bool tcbdbcurjumpback2(BDBCUR *cur, const char *kstr){ assert(cur && kstr); return tcbdbcurjumpback(cur, kstr, strlen(kstr));}/* Process each record atomically of a B+ tree database object. */bool tcbdbforeach(TCBDB *bdb, TCITER iter, void *op){ assert(bdb && iter); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } BDBTHREADYIELD(bdb); bool rv = tcbdbforeachimpl(bdb, iter, op); BDBUNLOCKMETHOD(bdb); return rv;}/************************************************************************************************* * private features *************************************************************************************************//* Clear all members. `bdb' specifies the B+ tree database object. */static void tcbdbclear(TCBDB *bdb){ assert(bdb); bdb->mmtx = NULL; bdb->cmtx = NULL; bdb->hdb = NULL; bdb->opaque = NULL; bdb->open = false; bdb->wmode = false; bdb->lmemb = BDBDEFLMEMB; bdb->nmemb = BDBDEFNMEMB; bdb->opts = 0; bdb->root = 0; bdb->first = 0; bdb->last = 0; bdb->lnum = 0; bdb->nnum = 0; bdb->rnum = 0; bdb->leafc = NULL; bdb->nodec = NULL; bdb->cmp = NULL; bdb->cmpop = NULL; bdb->lcnum = BDBDEFLCNUM; bdb->ncnum = BDBDEFNCNUM; bdb->lsmax = BDBDEFLSMAX; bdb->lschk = 0; bdb->capnum = 0; bdb->hist = NULL; bdb->hnum = 0; bdb->hleaf = 0; bdb->lleaf = 0; bdb->tran = false; bdb->rbopaque = NULL; bdb->clock = 0; bdb->cnt_saveleaf = -1; bdb->cnt_loadleaf = -1; bdb->cnt_killleaf = -1; bdb->cnt_adjleafc = -1; bdb->cnt_savenode = -1; bdb->cnt_loadnode = -1; bdb->cnt_adjnodec = -1; TCDODEBUG(bdb->cnt_saveleaf = 0); TCDODEBUG(bdb->cnt_loadleaf = 0); TCDODEBUG(bdb->cnt_killleaf = 0); TCDODEBUG(bdb->cnt_adjleafc = 0); TCDODEBUG(bdb->cnt_savenode = 0); TCDODEBUG(bdb->cnt_loadnode = 0); TCDODEBUG(bdb->cnt_adjnodec = 0);}/* Serialize meta data into the opaque field. `bdb' specifies the B+ tree database object. */static void tcbdbdumpmeta(TCBDB *bdb){ assert(bdb); memset(bdb->opaque, 0, 64); char *wp = bdb->opaque; if(bdb->cmp == tccmplexical){ *(uint8_t *)(wp++) = 0x0; } else if(bdb->cmp == tccmpdecimal){ *(uint8_t *)(wp++) = 0x1; } else if(bdb->cmp == tccmpint32){ *(uint8_t *)(wp++) = 0x2; } else if(bdb->cmp == tccmpint64){ *(uint8_t *)(wp++) = 0x3; } else { *(uint8_t *)(wp++) = 0xff; } wp += 7; uint32_t lnum; lnum = bdb->lmemb; lnum = TCHTOIL(lnum); memcpy(wp, &lnum, sizeof(lnum)); wp += sizeof(lnum); lnum = bdb->nmemb; lnum = TCHTOIL(lnum); memcpy(wp, &lnum, sizeof(lnum)); wp += sizeof(lnum); uint64_t llnum; llnum = bdb->root; llnum = TCHTOILL(llnum); memcpy(wp, &llnum, sizeof(llnum)); wp += sizeof(llnum);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -