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

📄 tctdb.c

📁 Tokyo Cabinet的Tokyo Cabinet 是一个DBM的实现。这里的数据库由一系列key-value对的记录构成。key和value都可以是任意长度的字节序列,既可以是二进制也可以是字符
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    getnum++;    int flags = proc(pkbuf, pksiz, cols, op);    if(flags & TDBQPPUT){      if(tctdbputimpl(tdb, pkbuf, pksiz, cols, TDBPDOVER)){        putnum++;      } else {        err = true;      }    } else if(flags & TDBQPOUT){      if(tctdboutimpl(tdb, pkbuf, pksiz)){        outnum++;      } else {        err = true;      }    }    tcmapdel(cols);    if(flags & TDBQPSTOP) break;  }  tclistdel(res);  tcxstrprintf(qry->hint, "post treatment: get=%lld, put=%lld, out=%lld\n",               (long long)getnum, (long long)putnum, (long long)outnum);  TDBUNLOCKMETHOD(tdb);  return !err;}/* Get the hint of a query object. */const char *tctdbqryhint(TDBQRY *qry){  assert(qry);  return tcxstrptr(qry->hint);}/************************************************************************************************* * features for experts *************************************************************************************************//* Set the error code of a table database object. */void tctdbsetecode(TCTDB *tdb, int ecode, const char *filename, int line, const char *func){  assert(tdb && filename && line >= 1 && func);  tchdbsetecode(tdb->hdb, ecode, filename, line, func);}/* Set the file descriptor for debugging output. */void tctdbsetdbgfd(TCTDB *tdb, int fd){  assert(tdb && fd >= 0);  tchdbsetdbgfd(tdb->hdb, fd);}/* Get the file descriptor for debugging output. */int tctdbdbgfd(TCTDB *tdb){  assert(tdb);  return tchdbdbgfd(tdb->hdb);}/* Check whether mutual exclusion control is set to a table database object. */bool tctdbhasmutex(TCTDB *tdb){  assert(tdb);  return tdb->mmtx != NULL;}/* Synchronize updating contents on memory of a table database object. */bool tctdbmemsync(TCTDB *tdb, bool phys){  assert(tdb);  if(!tdb->open || !tdb->wmode){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return false;  }  bool err = false;  if(!tchdbmemsync(tdb->hdb, phys)) err = true;  TDBIDX *idxs = tdb->idxs;  int inum = tdb->inum;  for(int i = 0; i < inum; i++){    TDBIDX *idx = idxs + i;    switch(idx->type){    case TDBITLEXICAL:    case TDBITDECIMAL:      if(!tcbdbmemsync(idx->db, phys)){        tctdbsetecode(tdb, tcbdbecode(idx->db), __FILE__, __LINE__, __func__);        err = true;      }      break;    }  }  return !err;}/* Get the number of elements of the bucket array of a table database object. */uint64_t tctdbbnum(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tchdbbnum(tdb->hdb);}/* Get the record alignment of a table database object. */uint32_t tctdbalign(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tchdbalign(tdb->hdb);}/* Get the maximum number of the free block pool of a table database object. */uint32_t tctdbfbpmax(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tchdbfbpmax(tdb->hdb);}/* Get the inode number of the database file of a table database object. */uint64_t tctdbinode(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tchdbinode(tdb->hdb);}/* Get the modification time of the database file of a table database object. */time_t tctdbmtime(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tchdbmtime(tdb->hdb);}/* Get the additional flags of a table database object. */uint8_t tctdbflags(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tchdbflags(tdb->hdb);}/* Get the options of a table database object. */uint8_t tctdbopts(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tdb->opts;}/* Get the pointer to the opaque field of a table database object. */char *tctdbopaque(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return NULL;  }  return tchdbopaque(tdb->hdb) + TDBOPAQUESIZ;}/* Get the number of used elements of the bucket array of a table database object. */uint64_t tctdbbnumused(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tchdbbnumused(tdb->hdb);}/* Get the number of column indices of a table database object. */int tctdbinum(TCTDB *tdb){  assert(tdb);  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return tdb->inum;}/* Get the seed of unique ID unumbers of a table database object. */int64_t tctdbuidseed(TCTDB *tdb){  assert(tdb);  if(!TDBLOCKMETHOD(tdb, false)) return -1;  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    TDBUNLOCKMETHOD(tdb);    return -1;  }  int64_t rv = tctdbgenuidimpl(tdb, 0);  TDBUNLOCKMETHOD(tdb);  return rv;}/* Set the seed of unique ID unumbers of a table database object. */bool tctdbsetuidseed(TCTDB *tdb, int64_t seed){  assert(tdb && seed >= 0);  if(!TDBLOCKMETHOD(tdb, true)) return -1;  if(!tdb->open || !tdb->wmode){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    TDBUNLOCKMETHOD(tdb);    return false;  }  tctdbgenuidimpl(tdb, -seed - 1);  TDBUNLOCKMETHOD(tdb);  return true;}/* Set the custom codec functions of a table database object. */bool tctdbsetcodecfunc(TCTDB *tdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop){  assert(tdb && enc && dec);  if(!TDBLOCKMETHOD(tdb, true)) return false;  if(tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    TDBUNLOCKMETHOD(tdb);    return false;  }  bool rv = tchdbsetcodecfunc(tdb->hdb, enc, encop, dec, decop);  TDBUNLOCKMETHOD(tdb);  return rv;}/* Process each record atomically of a table database object. */bool tctdbforeach(TCTDB *tdb, TCITER iter, void *op){  assert(tdb && iter);  if(!TDBLOCKMETHOD(tdb, false)) return false;  if(!tdb->open){    tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);    TDBUNLOCKMETHOD(tdb);    return false;  }  TDBTHREADYIELD(tdb);  bool rv = tctdbforeachimpl(tdb, iter, op);  TDBUNLOCKMETHOD(tdb);  return rv;}/* Convert a string into the index type number. */int tctdbstrtoindextype(const char *str){  assert(str);  int type = -1;  int flags = 0;  if(*str == '+'){    flags |= TDBITKEEP;    str++;  }  if(!tcstricmp(str, "LEX") || !tcstricmp(str, "LEXICAL") || !tcstricmp(str, "STR")){    type = TDBITLEXICAL;  } else if(!tcstricmp(str, "DEC") || !tcstricmp(str, "DECIMAL") || !tcstricmp(str, "NUM")){    type = TDBITDECIMAL;  } else if(!tcstricmp(str, "OPT") || !tcstricmp(str, "OPTIMIZE")){    type = TDBITOPT;  } else if(!tcstricmp(str, "VOID") || !tcstricmp(str, "NULL")){    type = TDBITVOID;  } else if(tcstrisnum(str)){    type = tcatoi(str);  }  return type | flags;}/* Get the count of corresponding records of a query object. */int tctdbqrycount(TDBQRY *qry){  assert(qry);  return qry->count;}/* Convert a string into the query operation number. */int tctdbqrystrtocondop(const char *str){  assert(str);  int op = -1;  int flags = 0;  if(*str == '~' || *str == '!'){    flags |= TDBQCNEGATE;    str++;  }  if(*str == '+'){    flags |= TDBQCNOIDX;    str++;  }  if(!tcstricmp(str, "STREQ")){    op = TDBQCSTREQ;  } else if(!tcstricmp(str, "STRINC")){    op = TDBQCSTRINC;  } else if(!tcstricmp(str, "STRBW")){    op = TDBQCSTRBW;  } else if(!tcstricmp(str, "STREW")){    op = TDBQCSTREW;  } else if(!tcstricmp(str, "STRAND")){    op = TDBQCSTRAND;  } else if(!tcstricmp(str, "STROR")){    op = TDBQCSTROR;  } else if(!tcstricmp(str, "STROREQ")){    op = TDBQCSTROREQ;  } else if(!tcstricmp(str, "STRRX")){    op = TDBQCSTRRX;  } else if(!tcstricmp(str, "NUMEQ")){    op = TDBQCNUMEQ;  } else if(!tcstricmp(str, "NUMGT")){    op = TDBQCNUMGT;  } else if(!tcstricmp(str, "NUMGE")){    op = TDBQCNUMGE;  } else if(!tcstricmp(str, "NUMLT")){    op = TDBQCNUMLT;  } else if(!tcstricmp(str, "NUMLE")){    op = TDBQCNUMLE;  } else if(!tcstricmp(str, "NUMBT")){    op = TDBQCNUMBT;  } else if(!tcstricmp(str, "NUMOREQ")){    op = TDBQCNUMOREQ;  } else if(tcstrisnum(str)){    op = tcatoi(str);  }  return op | flags;}/* Convert a string into the query order type number. */int tctdbqrystrtoordertype(const char *str){  assert(str);  int type = -1;  if(!tcstricmp(str, "STRASC") || !tcstricmp(str, "STR")){    type = TDBQOSTRASC;  } else if(!tcstricmp(str, "STRDESC")){    type = TDBQOSTRDESC;  } else if(!tcstricmp(str, "NUMASC") || !tcstricmp(str, "NUM")){    type = TDBQONUMASC;  } else if(!tcstricmp(str, "NUMDESC")){    type = TDBQONUMDESC;  } else if(tcstrisnum(str)){    type = tcatoi(str);  }  return type;}/************************************************************************************************* * private features *************************************************************************************************//* Clear all members.   `tdb' specifies the table database object. */static void tctdbclear(TCTDB *tdb){  assert(tdb);  tdb->mmtx = NULL;  tdb->hdb = NULL;  tdb->open = false;  tdb->wmode = false;  tdb->opts = 0;  tdb->lcnum = TDBDEFLCNUM;  tdb->ncnum = TDBDEFNCNUM;  tdb->idxs = NULL;  tdb->inum = 0;  tdb->tran = false;}/* Open a database file and connect a table database object.   `tdb' specifies the table database object.   `path' specifies the path of the internal database file.   `omode' specifies the connection mode.   If successful, the return value is true, else, it is false. */static bool tctdbopenimpl(TCTDB *tdb, const char *path, int omode){  assert(tdb && path);  TCCODEC enc, dec;  void *encop, *decop;  tchdbcodecfunc(tdb->hdb, &enc, &encop, &dec, &decop);  int homode = HDBOREADER;  int bomode = BDBOREADER;  if(omode & TDBOWRITER){    homode = HDBOWRITER;    bomode = BDBOWRITER;    if(omode & TDBOCREAT){      homode |= HDBOCREAT;      bomode |= BDBOCREAT;    }    if(omode & TDBOTRUNC){      homode |= HDBOTRUNC;      bomode |= BDBOTRUNC;    }    tdb->wmode = true;  } else {    tdb->wmode = false;  }  if(omode & TDBONOLCK){    homode |= HDBONOLCK;    bomode |= BDBONOLCK;  }  if(omode & TDBOLCKNB){    homode |= HDBOLCKNB;    bomode |= BDBOLCKNB;  }  if(omode & TDBOTSYNC){    homode |= HDBOTSYNC;    bomode |= BDBOTSYNC;  }  tchdbsettype(tdb->hdb, TCDBTTABLE);  if(!tchdbopen(tdb->hdb, path, homode)) return false;  char *tpath = tcsprintf("%s%c%s%c*", path, MYEXTCHR, TDBIDXSUFFIX, MYEXTCHR);  if((omode & TDBOWRITER) && (omode & TDBOTRUNC)){    TCLIST *paths = tcglobpat(tpath);    int pnum = TCLISTNUM(paths);    for(int i = 0; i < pnum; i++){      unlink(TCLISTVALPTR(paths, i));

⌨️ 快捷键说明

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