?? tcbdb.c
字號:
tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } bool rv = tcbdboutimpl(bdb, kbuf, ksiz); BDBUNLOCKMETHOD(bdb); return rv;}/* Remove a string record of a B+ tree database object. */bool tcbdbout2(TCBDB *bdb, const char *kstr){ assert(bdb && kstr); return tcbdbout(bdb, kstr, strlen(kstr));}/* Remove records of a B+ tree database object. */bool tcbdbout3(TCBDB *bdb, const void *kbuf, int ksiz){ assert(bdb && kbuf && ksiz >= 0); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } bool rv = tcbdboutlist(bdb, kbuf, ksiz); BDBUNLOCKMETHOD(bdb); return rv;}/* Retrieve a record in a B+ tree database object. */void *tcbdbget(TCBDB *bdb, const void *kbuf, int ksiz, int *sp){ assert(bdb && kbuf && ksiz >= 0 && sp); if(!BDBLOCKMETHOD(bdb, false)) return NULL; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return NULL; } const char *vbuf = tcbdbgetimpl(bdb, kbuf, ksiz, sp); char *rv; if(vbuf){ TCMEMDUP(rv, vbuf, *sp); } else { rv = NULL; } bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; BDBUNLOCKMETHOD(bdb); if(adj && BDBLOCKMETHOD(bdb, true)){ if(!bdb->tran && !tcbdbcacheadjust(bdb)){ TCFREE(rv); rv = NULL; } BDBUNLOCKMETHOD(bdb); } return rv;}/* Retrieve a string record in a B+ tree database object. */char *tcbdbget2(TCBDB *bdb, const char *kstr){ assert(bdb && kstr); int vsiz; return tcbdbget(bdb, kstr, strlen(kstr), &vsiz);}/* Retrieve a record in a B+ tree database object and write the value into a buffer. */const void *tcbdbget3(TCBDB *bdb, const void *kbuf, int ksiz, int *sp){ assert(bdb && kbuf && ksiz >= 0 && sp); if(!BDBLOCKMETHOD(bdb, false)) return NULL; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return NULL; } const char *rv = tcbdbgetimpl(bdb, kbuf, ksiz, sp); bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; BDBUNLOCKMETHOD(bdb); if(adj && BDBLOCKMETHOD(bdb, true)){ if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = NULL; BDBUNLOCKMETHOD(bdb); } return rv;}/* Retrieve records in a B+ tree database object. */TCLIST *tcbdbget4(TCBDB *bdb, const void *kbuf, int ksiz){ assert(bdb && kbuf && ksiz >= 0); if(!BDBLOCKMETHOD(bdb, false)) return NULL; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return NULL; } TCLIST *rv = tcbdbgetlist(bdb, kbuf, ksiz); bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; BDBUNLOCKMETHOD(bdb); if(adj && BDBLOCKMETHOD(bdb, true)){ if(!bdb->tran && !tcbdbcacheadjust(bdb)){ if(rv) tclistdel(rv); rv = NULL; } BDBUNLOCKMETHOD(bdb); } return rv;}/* Get the number of records corresponding a key in a B+ tree database object. */int tcbdbvnum(TCBDB *bdb, const void *kbuf, int ksiz){ assert(bdb && kbuf && ksiz >= 0); if(!BDBLOCKMETHOD(bdb, false)) return 0; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return 0; } int rv = tcbdbgetnum(bdb, kbuf, ksiz); bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; BDBUNLOCKMETHOD(bdb); if(adj && BDBLOCKMETHOD(bdb, true)){ if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = 0; BDBUNLOCKMETHOD(bdb); } return rv;}/* Get the number of records corresponding a string key in a B+ tree database object. */int tcbdbvnum2(TCBDB *bdb, const char *kstr){ assert(bdb && kstr); return tcbdbvnum(bdb, kstr, strlen(kstr));}/* Get the size of the value of a record in a B+ tree database object. */int tcbdbvsiz(TCBDB *bdb, const void *kbuf, int ksiz){ assert(bdb && kbuf && ksiz >= 0); int vsiz; if(!tcbdbget3(bdb, kbuf, ksiz, &vsiz)) return -1; return vsiz;}/* Get the size of the value of a string record in a B+ tree database object. */int tcbdbvsiz2(TCBDB *bdb, const char *kstr){ assert(bdb && kstr); return tcbdbvsiz(bdb, kstr, strlen(kstr));}/* Get keys of ranged records in a B+ tree database object. */TCLIST *tcbdbrange(TCBDB *bdb, const void *bkbuf, int bksiz, bool binc, const void *ekbuf, int eksiz, bool einc, int max){ assert(bdb); TCLIST *keys = tclistnew(); if(!BDBLOCKMETHOD(bdb, false)) return keys; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return keys; } tcbdbrangeimpl(bdb, bkbuf, bksiz, binc, ekbuf, eksiz, einc, max, keys); bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; BDBUNLOCKMETHOD(bdb); if(adj && BDBLOCKMETHOD(bdb, true)){ tcbdbcacheadjust(bdb); BDBUNLOCKMETHOD(bdb); } return keys;}/* Get string keys of ranged records in a B+ tree database object. */TCLIST *tcbdbrange2(TCBDB *bdb, const char *bkstr, bool binc, const char *ekstr, bool einc, int max){ assert(bdb); return tcbdbrange(bdb, bkstr, bkstr ? strlen(bkstr) : 0, binc, ekstr, ekstr ? strlen(ekstr) : 0, einc, max);}/* Get forward matching keys in a B+ tree database object. */TCLIST *tcbdbfwmkeys(TCBDB *bdb, const void *pbuf, int psiz, int max){ assert(bdb && pbuf && psiz >= 0); TCLIST *keys = tclistnew(); if(!BDBLOCKMETHOD(bdb, false)) return keys; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return keys; } tcbdbrangefwm(bdb, pbuf, psiz, max, keys); bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; BDBUNLOCKMETHOD(bdb); if(adj && BDBLOCKMETHOD(bdb, true)){ tcbdbcacheadjust(bdb); BDBUNLOCKMETHOD(bdb); } return keys;}/* Get forward matching string keys in a B+ tree database object. */TCLIST *tcbdbfwmkeys2(TCBDB *bdb, const char *pstr, int max){ assert(bdb && pstr); return tcbdbfwmkeys(bdb, pstr, strlen(pstr), max);}/* Add an integer to a record in a B+ tree database object. */int tcbdbaddint(TCBDB *bdb, const void *kbuf, int ksiz, int num){ assert(bdb && kbuf && ksiz >= 0); if(!BDBLOCKMETHOD(bdb, true)) return INT_MIN; if(!bdb->open || !bdb->wmode){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return INT_MIN; } bool rv = tcbdbputimpl(bdb, kbuf, ksiz, (char *)&num, sizeof(num), BDBPDADDINT); BDBUNLOCKMETHOD(bdb); return rv ? num : INT_MIN;}/* Add a real number to a record in a B+ tree database object. */double tcbdbadddouble(TCBDB *bdb, const void *kbuf, int ksiz, double num){ assert(bdb && kbuf && ksiz >= 0); if(!BDBLOCKMETHOD(bdb, true)) return nan(""); if(!bdb->open || !bdb->wmode){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return nan(""); } bool rv = tcbdbputimpl(bdb, kbuf, ksiz, (char *)&num, sizeof(num), BDBPDADDDBL); BDBUNLOCKMETHOD(bdb); return rv ? num : nan("");}/* Synchronize updated contents of a B+ tree database object with the file and the device. */bool tcbdbsync(TCBDB *bdb){ assert(bdb); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode || bdb->tran){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } bool rv = tcbdbmemsync(bdb, true); BDBUNLOCKMETHOD(bdb); return rv;}/* Optimize the file of a B+ tree database object. */bool tcbdboptimize(TCBDB *bdb, int32_t lmemb, int32_t nmemb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){ assert(bdb); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode || bdb->tran){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } BDBTHREADYIELD(bdb); bool rv = tcbdboptimizeimpl(bdb, lmemb, nmemb, bnum, apow, fpow, opts); BDBUNLOCKMETHOD(bdb); return rv;}/* Remove all records of a B+ tree database object. */bool tcbdbvanish(TCBDB *bdb){ assert(bdb); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode || bdb->tran){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } BDBTHREADYIELD(bdb); bool rv = tcbdbvanishimpl(bdb); BDBUNLOCKMETHOD(bdb); return rv;}/* Copy the database file of a B+ tree database object. */bool tcbdbcopy(TCBDB *bdb, const char *path){ assert(bdb && path); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } BDBTHREADYIELD(bdb); TCLIST *lids = tclistnew(); TCLIST *nids = tclistnew(); const char *vbuf; int vsiz; TCMAP *leafc = bdb->leafc; tcmapiterinit(leafc); while((vbuf = tcmapiternext(leafc, &vsiz)) != NULL){ TCLISTPUSH(lids, vbuf, vsiz); } TCMAP *nodec = bdb->nodec; tcmapiterinit(nodec); while((vbuf = tcmapiternext(nodec, &vsiz)) != NULL){ TCLISTPUSH(nids, vbuf, vsiz); } BDBUNLOCKMETHOD(bdb); bool err = false; int ln = TCLISTNUM(lids); for(int i = 0; i < ln; i++){ vbuf = TCLISTVALPTR(lids, i); if(BDBLOCKMETHOD(bdb, true)){ BDBTHREADYIELD(bdb); if(bdb->open){ int rsiz; BDBLEAF *leaf = (BDBLEAF *)tcmapget(bdb->leafc, vbuf, sizeof(leaf->id), &rsiz); if(leaf && leaf->dirty && !tcbdbleafsave(bdb, leaf)) err = true; } else { err = true; } BDBUNLOCKMETHOD(bdb); } else { err = true; } } ln = TCLISTNUM(nids); for(int i = 0; i < ln; i++){ vbuf = TCLISTVALPTR(nids, i); if(BDBLOCKMETHOD(bdb, true)){ if(bdb->open){ int rsiz; BDBNODE *node = (BDBNODE *)tcmapget(bdb->nodec, vbuf, sizeof(node->id), &rsiz); if(node && node->dirty && !tcbdbnodesave(bdb, node)) err = true; } else { err = true; } BDBUNLOCKMETHOD(bdb); } else { err = true; } } tclistdel(nids); tclistdel(lids); if(!tcbdbtranbegin(bdb)) err = true; if(BDBLOCKMETHOD(bdb, false)){ BDBTHREADYIELD(bdb); if(!tchdbcopy(bdb->hdb, path)) err = true; BDBUNLOCKMETHOD(bdb); } else { err = true; } if(!tcbdbtrancommit(bdb)) err = true; return !err;}/* Begin the transaction of a B+ tree database object. */bool tcbdbtranbegin(TCBDB *bdb){ assert(bdb); for(double wsec = 1.0 / sysconf(_SC_CLK_TCK); true; wsec *= 2){ if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } if(!bdb->tran) break; BDBUNLOCKMETHOD(bdb); if(wsec > 1.0) wsec = 1.0; tcsleep(wsec); } if(!tcbdbmemsync(bdb, false)){ BDBUNLOCKMETHOD(bdb); return false; } if(!tchdbtranbegin(bdb->hdb)){ BDBUNLOCKMETHOD(bdb); return false; } bdb->tran = true; TCMEMDUP(bdb->rbopaque, bdb->opaque, BDBOPAQUESIZ); BDBUNLOCKMETHOD(bdb); return true;}/* Commit the transaction of a B+ tree database object. */bool tcbdbtrancommit(TCBDB *bdb){ assert(bdb); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode || !bdb->tran){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } TCFREE(bdb->rbopaque); bdb->tran = false; bdb->rbopaque = NULL; bool err = false; if(!tcbdbmemsync(bdb, false)) err = true; if(!tcbdbcacheadjust(bdb)) err = true; if(err){ tchdbtranabort(bdb->hdb); } else if(!tchdbtrancommit(bdb->hdb)){ err = true; } BDBUNLOCKMETHOD(bdb); return !err;}/* Abort the transaction of a B+ tree database object. */bool tcbdbtranabort(TCBDB *bdb){ assert(bdb); if(!BDBLOCKMETHOD(bdb, true)) return false; if(!bdb->open || !bdb->wmode || !bdb->tran){ tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); BDBUNLOCKMETHOD(bdb); return false; } tcbdbcachepurge(bdb); memcpy(bdb->opaque, bdb->rbopaque, BDBOPAQUESIZ); tcbdbloadmeta(bdb); TCFREE(bdb->rbopaque); bdb->tran = false; bdb->rbopaque = NULL; bdb->hleaf = 0; bdb->lleaf = 0; bdb->clock++; bool err = false;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -