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

📄 tchdb.c

📁 Tokyo Cabinet的Tokyo Cabinet 是一个DBM的实现。这里的数据库由一系列key-value对的记录构成。key和value都可以是任意长度的字节序列,既可以是二进制也可以是字符
💻 C
📖 第 1 页 / 共 5 页
字号:
bool tchdbhasmutex(TCHDB *hdb){  assert(hdb);  return hdb->mmtx != NULL;}/* Synchronize updating contents on memory of a hash database object. */bool tchdbmemsync(TCHDB *hdb, bool phys){  assert(hdb);  if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return false;  }  bool err = false;  char hbuf[HDBHEADSIZ];  tchdbdumpmeta(hdb, hbuf);  memcpy(hdb->map, hbuf, HDBOPAQUEOFF);  if(phys){    size_t xmsiz = (hdb->xmsiz > hdb->msiz) ? hdb->xmsiz : hdb->msiz;    if(msync(hdb->map, xmsiz, MS_SYNC) == -1){      tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__);      err = true;    }    if(fsync(hdb->fd) == -1){      tchdbsetecode(hdb, TCESYNC, __FILE__, __LINE__, __func__);      err = true;    }  }  return !err;}/* Clear the cache of a hash tree database object. */bool tchdbcacheclear(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return false;  }  if(hdb->recc) tcmdbvanish(hdb->recc);  return true;}/* Get the number of elements of the bucket array of a hash database object. */uint64_t tchdbbnum(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->bnum;}/* Get the record alignment a hash database object. */uint32_t tchdbalign(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->align;}/* Get the maximum number of the free block pool of a a hash database object. */uint32_t tchdbfbpmax(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->fbpmax;}/* Get the size of the extra mapped memory of a hash database object. */uint64_t tchdbxmsiz(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->xmsiz;}/* Get the inode number of the database file of a hash database object. */uint64_t tchdbinode(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->inode;}/* Get the modification time of the database file of a hash database object. */time_t tchdbmtime(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->mtime;}/* Get the connection mode of a hash database object. */int tchdbomode(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->omode;}/* Get the database type of a hash database object. */uint8_t tchdbtype(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->type;}/* Get the additional flags of a hash database object. */uint8_t tchdbflags(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->flags;}/* Get the options of a hash database object. */uint8_t tchdbopts(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return hdb->opts;}/* Get the pointer to the opaque field of a hash database object. */char *tchdbopaque(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return NULL;  }  return hdb->map + HDBOPAQUEOFF;}/* Get the number of used elements of the bucket array of a hash database object. */uint64_t tchdbbnumused(TCHDB *hdb){  assert(hdb);  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  uint64_t unum = 0;  if(hdb->ba64){    uint64_t *buckets = hdb->ba64;    for(int i = 0; i < hdb->bnum; i++){      if(buckets[i]) unum++;    }  } else {    uint32_t *buckets = hdb->ba32;    for(int i = 0; i < hdb->bnum; i++){      if(buckets[i]) unum++;    }  }  return unum;}/* Set the custom codec functions of a hash database object. */bool tchdbsetcodecfunc(TCHDB *hdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop){  assert(hdb && enc && dec);  if(!HDBLOCKMETHOD(hdb, true)) return false;  if(hdb->fd >= 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    HDBUNLOCKMETHOD(hdb);    return false;  }  hdb->enc = enc;  hdb->encop = encop;  hdb->dec = dec;  hdb->decop = decop;  HDBUNLOCKMETHOD(hdb);  return true;}/* Store a record into a hash database object with a duplication handler. */bool tchdbputproc(TCHDB *hdb, const void *kbuf, int ksiz, const char *vbuf, int vsiz,                  TCPDPROC proc, void *op){  assert(hdb && kbuf && ksiz >= 0 && proc);  if(!HDBLOCKMETHOD(hdb, false)) return false;  uint8_t hash;  uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);  if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    HDBUNLOCKMETHOD(hdb);    return false;  }  if(hdb->async && !tchdbflushdrp(hdb)){    HDBUNLOCKMETHOD(hdb);    return false;  }  if(!HDBLOCKRECORD(hdb, bidx, true)){    HDBUNLOCKMETHOD(hdb);    return false;  }  if(hdb->zmode){    char *zbuf;    int osiz;    char *obuf = tchdbgetimpl(hdb, kbuf, ksiz, bidx, hash, &osiz);    if(obuf){      int nsiz;      char *nbuf = proc(obuf, osiz, &nsiz, op);      if(nbuf == (void *)-1){        bool rv = tchdboutimpl(hdb, kbuf, ksiz, bidx, hash);        TCFREE(obuf);        HDBUNLOCKRECORD(hdb, bidx);        HDBUNLOCKMETHOD(hdb);        return rv;      } else if(nbuf){        if(hdb->opts & HDBTDEFLATE){          zbuf = _tc_deflate(nbuf, nsiz, &vsiz, _TCZMRAW);        } else if(hdb->opts & HDBTBZIP){          zbuf = _tc_bzcompress(nbuf, nsiz, &vsiz);        } else if(hdb->opts & HDBTTCBS){          zbuf = tcbsencode(nbuf, nsiz, &vsiz);        } else {          zbuf = hdb->enc(nbuf, nsiz, &vsiz, hdb->encop);        }        TCFREE(nbuf);      } else {        zbuf = NULL;      }      TCFREE(obuf);    } else if(vbuf){      if(hdb->opts & HDBTDEFLATE){        zbuf = _tc_deflate(vbuf, vsiz, &vsiz, _TCZMRAW);      } else if(hdb->opts & HDBTBZIP){        zbuf = _tc_bzcompress(vbuf, vsiz, &vsiz);      } else if(hdb->opts & HDBTTCBS){        zbuf = tcbsencode(vbuf, vsiz, &vsiz);      } else {        zbuf = hdb->enc(vbuf, vsiz, &vsiz, hdb->encop);      }    } else {      tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__);      HDBUNLOCKRECORD(hdb, bidx);      HDBUNLOCKMETHOD(hdb);      return false;    }    if(!zbuf){      tchdbsetecode(hdb, TCEKEEP, __FILE__, __LINE__, __func__);      HDBUNLOCKRECORD(hdb, bidx);      HDBUNLOCKMETHOD(hdb);      return false;    }    bool rv = tchdbputimpl(hdb, kbuf, ksiz, bidx, hash, zbuf, vsiz, HDBPDOVER);    TCFREE(zbuf);    HDBUNLOCKRECORD(hdb, bidx);    HDBUNLOCKMETHOD(hdb);    return rv;  }  HDBPDPROCOP procop;  procop.proc = proc;  procop.op = op;  HDBPDPROCOP *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 = tchdbputimpl(hdb, kbuf, ksiz, bidx, hash, vbuf, vsiz, HDBPDPROC);  if(rbuf != stack) TCFREE(rbuf);  HDBUNLOCKRECORD(hdb, bidx);  HDBUNLOCKMETHOD(hdb);  return rv;}/* Get the custom codec functions of a hash database object. */void tchdbcodecfunc(TCHDB *hdb, TCCODEC *ep, void **eop, TCCODEC *dp, void **dop){  assert(hdb && ep && eop && dp && dop);  *ep = hdb->enc;  *eop = hdb->encop;  *dp = hdb->dec;  *dop = hdb->decop;}/* Retrieve the next record of a record in a hash database object. */void *tchdbgetnext(TCHDB *hdb, const void *kbuf, int ksiz, int *sp){  assert(hdb && sp);  if(!HDBLOCKMETHOD(hdb, true)) return NULL;  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    HDBUNLOCKMETHOD(hdb);    return NULL;  }  if(hdb->async && !tchdbflushdrp(hdb)){    HDBUNLOCKMETHOD(hdb);    return NULL;  }  char *rv = tchdbgetnextimpl(hdb, kbuf, ksiz, sp, NULL, NULL);  HDBUNLOCKMETHOD(hdb);  return rv;}/* Retrieve the next record of a string record in a hash database object. */char *tchdbgetnext2(TCHDB *hdb, const char *kstr){  assert(hdb);  int vsiz;  return tchdbgetnext(hdb, kstr, strlen(kstr), &vsiz);}/* Retrieve the key and the value of the next record of a record in a hash database object. */char *tchdbgetnext3(TCHDB *hdb, const char *kbuf, int ksiz, int *sp, const char **vbp, int *vsp){  assert(hdb && sp && vbp && vsp);  if(!HDBLOCKMETHOD(hdb, true)) return NULL;  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    HDBUNLOCKMETHOD(hdb);    return NULL;  }  if(hdb->async && !tchdbflushdrp(hdb)){    HDBUNLOCKMETHOD(hdb);    return NULL;  }  char *rv = tchdbgetnextimpl(hdb, kbuf, ksiz, sp, vbp, vsp);  HDBUNLOCKMETHOD(hdb);  return rv;}/* Process each record atomically of a hash database object. */bool tchdbforeach(TCHDB *hdb, TCITER iter, void *op){  assert(hdb && iter);  if(!HDBLOCKMETHOD(hdb, false)) return false;  if(hdb->fd < 0){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    HDBUNLOCKMETHOD(hdb);    return false;  }  if(hdb->async && !tchdbflushdrp(hdb)){    HDBUNLOCKMETHOD(hdb);    return false;  }  if(!HDBLOCKALLRECORDS(hdb, false)){    HDBUNLOCKMETHOD(hdb);    return false;  }  HDBTHREADYIELD(hdb);  bool rv = tchdbforeachimpl(hdb, iter, op);  HDBUNLOCKALLRECORDS(hdb);  HDBUNLOCKMETHOD(hdb);  return rv;}/* Void the transaction of a hash database object. */bool tchdbtranvoid(TCHDB *hdb){  assert(hdb);  if(!HDBLOCKMETHOD(hdb, true)) return false;  if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER) || hdb->fatal || !hdb->tran){    tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);    HDBUNLOCKMETHOD(hdb);    return false;  }  hdb->tran = false;  HDBUNLOCKMETHOD(hdb);  return true;}/************************************************************************************************* * private features *************************************************************************************************//* Get a natural prime number not less than a floor number.   `num' specified the floor number.   The return value is a prime number not less than the floor number. */static uint64_t tcgetprime(uint64_t num){  uint64_t primes[] = {    1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 43, 47, 53, 59, 61, 71, 79, 83,    89, 103, 109, 113, 127, 139, 157, 173, 191, 199, 223, 239, 251, 283, 317, 349,    383, 409, 443, 479, 509, 571, 631, 701, 761, 829, 887, 953, 1021, 1151, 1279,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -