⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcbdb.c

📁 Tokyo Cabinet的Tokyo Cabinet 是一个DBM的实现。这里的数据库由一系列key-value对的记录构成。key和value都可以是任意长度的字节序列,既可以是二进制也可以是字符
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -