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

📄 tcfdb.c

📁 高性能嵌入式数据库在高并发的环境下使用最好是64位系统比较好
💻 C
📖 第 1 页 / 共 4 页
字号:
  } else if(id == FDBIDMAX){    id = fdb->max;  }  if(id < 1 || id > fdb->limid){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return false;  }  if(!FDBLOCKRECORD(fdb, false, id)){    FDBUNLOCKMETHOD(fdb);    return false;  }  int vsiz;  const void *vbuf = tcfdbgetimpl(fdb, id, &vsiz);  if(!vbuf) vsiz = -1;  FDBUNLOCKRECORD(fdb, id);  FDBUNLOCKMETHOD(fdb);  return vsiz;}/* Get the size of the value with a decimal key in a fixed-length database object. */int tcfdbvsiz2(TCFDB *fdb, const void *kbuf, int ksiz){  assert(fdb && kbuf && ksiz >= 0);  return tcfdbvsiz(fdb, tcfdbkeytoid(kbuf, ksiz));}/* Get the size of the string value with a decimal key in a fixed-length database object. */int tcfdbvsiz3(TCFDB *fdb, const char *kstr){  assert(fdb && kstr);  return tcfdbvsiz(fdb, tcfdbkeytoid(kstr, strlen(kstr)));}/* Initialize the iterator of a fixed-length database object. */bool tcfdbiterinit(TCFDB *fdb){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, true)) return false;  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return false;  }  bool rv = tcfdbiterinitimpl(fdb);  FDBUNLOCKMETHOD(fdb);  return rv;}/* Get the next ID number of the iterator of a fixed-length database object. */uint64_t tcfdbiternext(TCFDB *fdb){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, true)) return false;  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return false;  }  uint64_t rv = tcfdbiternextimpl(fdb);  FDBUNLOCKMETHOD(fdb);  return rv;}/* Get the next decimay key of the iterator of a fixed-length database object. */void *tcfdbiternext2(TCFDB *fdb, int *sp){  assert(fdb && sp);  uint64_t id = tcfdbiternextimpl(fdb);  if(id < 1) return NULL;  char kbuf[TCNUMBUFSIZ];  int ksiz = sprintf(kbuf, "%llu", (unsigned long long)id);  *sp = ksiz;  return tcmemdup(kbuf, ksiz);}/* Get the next decimay key string of the iterator of a fixed-length database object. */char *tcfdbiternext3(TCFDB *fdb){  assert(fdb);  int ksiz;  return tcfdbiternext2(fdb, &ksiz);}/* Get range matching decimal keys in a fixed-length database object. */uint64_t *tcfdbrange(TCFDB *fdb, int64_t lower, int64_t upper, int max, int *np){  assert(fdb && np);  if(!FDBLOCKMETHOD(fdb, true)) return false;  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    *np = 0;    return tcmalloc(1);  }  if(lower == FDBIDMIN) lower = fdb->min;  if(upper == FDBIDMAX) upper = fdb->max;  if(lower < 1 || lower > fdb->limid || upper < 1 || upper > fdb->limid){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    *np = 0;    return tcmalloc(1);  }  uint64_t *rv = tcfdbrangeimpl(fdb, lower, upper, max, np);  FDBUNLOCKMETHOD(fdb);  return rv;}/* Get range matching decimal keys in a fixed-length database object. */TCLIST *tcfdbrange2(TCFDB *fdb, const void *lbuf, int lsiz, const void *ubuf, int usiz, int max){  assert(fdb && lbuf && lsiz >= 0 && ubuf && usiz >= 0);  int num;  uint64_t *ids = tcfdbrange(fdb, tcfdbkeytoid(lbuf, lsiz), tcfdbkeytoid(ubuf, usiz), max, &num);  TCLIST *keys = tclistnew2(num);  for(int i = 0; i < num; i++){    char kbuf[TCNUMBUFSIZ];    int ksiz = sprintf(kbuf, "%llu", (unsigned long long)ids[i]);    TCLISTPUSH(keys, kbuf, ksiz);  }  TCFREE(ids);  return keys;}/* Get range matching decimal keys with strings in a fixed-length database object. */TCLIST *tcfdbrange3(TCFDB *fdb, const char *lstr, const char *ustr, int max){  assert(fdb && lstr && ustr);  return tcfdbrange2(fdb, lstr, strlen(lstr), ustr, strlen(ustr), max);}/* Get keys with an interval notation in a fixed-length database object. */TCLIST *tcfdbrange4(TCFDB *fdb, const void *ibuf, int isiz, int max){  assert(fdb && ibuf && isiz >= 0);  char *expr;  TCMEMDUP(expr, ibuf, isiz);  char *pv = expr;  while(*pv > '\0' && *pv <= ' '){    pv++;  }  bool linc = false;  if(*pv == '['){    linc = true;  } else if(*pv != '('){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    TCFREE(expr);    return tclistnew();  }  pv++;  char *sep = strchr(pv, ',');  if(!sep){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    TCFREE(expr);    return tclistnew();  }  *sep = '\0';  tcstrtrim(pv);  int64_t lower = tcfdbkeytoid(pv, strlen(pv));  pv = sep + 1;  bool uinc = false;  if((sep = strchr(pv, ']')) != NULL){    uinc = true;    *sep = '\0';  } else if((sep = strchr(pv, ')')) != NULL){    *sep = '\0';  } else {    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    TCFREE(expr);    return tclistnew();  }  tcstrtrim(pv);  int64_t upper = tcfdbkeytoid(pv, strlen(pv));  if(lower == FDBIDMIN){    lower = fdb->min;  } else if(lower == FDBIDPREV){    lower = fdb->min - 1;  } else if(lower == FDBIDMAX){    lower = fdb->max;  } else if(lower == FDBIDNEXT){    lower = fdb->max + 1;  }  if(!linc) lower++;  if(upper == FDBIDMIN){    upper = fdb->min;  } else if(upper == FDBIDPREV){    upper = fdb->min - 1;  } else if(upper == FDBIDMAX){    upper = fdb->max;  } else if(upper == FDBIDNEXT){    upper = fdb->max + 1;  }  if(!uinc) upper--;  TCFREE(expr);  int num;  uint64_t *ids = tcfdbrange(fdb, lower, upper, max, &num);  TCLIST *keys = tclistnew2(num);  for(int i = 0; i < num; i++){    char kbuf[TCNUMBUFSIZ];    int ksiz = sprintf(kbuf, "%llu", (unsigned long long)ids[i]);    TCLISTPUSH(keys, kbuf, ksiz);  }  TCFREE(ids);  return keys;}/* Get keys with an interval notation string in a fixed-length database object. */TCLIST *tcfdbrange5(TCFDB *fdb, const void *istr, int max){  assert(fdb && istr);  return tcfdbrange4(fdb, istr, strlen(istr), max);}/* Add an integer to a record in a fixed-length database object. */int tcfdbaddint(TCFDB *fdb, int64_t id, int num){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, id < 1)) return INT_MIN;  if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return INT_MIN;  }  if(id == FDBIDMIN){    id = fdb->min;  } else if(id == FDBIDPREV){    id = fdb->min - 1;  } else if(id == FDBIDMAX){    id = fdb->max;  } else if(id == FDBIDNEXT){    id = fdb->max + 1;  }  if(id < 1 || id > fdb->limid){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return INT_MIN;  }  if(!FDBLOCKRECORD(fdb, true, id)){    FDBUNLOCKMETHOD(fdb);    return INT_MIN;  }  bool rv = tcfdbputimpl(fdb, id, (char *)&num, sizeof(num), FDBPDADDINT);  FDBUNLOCKRECORD(fdb, id);  FDBUNLOCKMETHOD(fdb);  return rv ? num : INT_MIN;}/* Add a real number to a record in a fixed-length database object. */double tcfdbadddouble(TCFDB *fdb, int64_t id, double num){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, id < 1)) return nan("");  if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return nan("");  }  if(id == FDBIDMIN){    id = fdb->min;  } else if(id == FDBIDPREV){    id = fdb->min - 1;  } else if(id == FDBIDMAX){    id = fdb->max;  } else if(id == FDBIDNEXT){    id = fdb->max + 1;  }  if(id < 1 || id > fdb->limid){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return nan("");  }  if(!FDBLOCKRECORD(fdb, true, id)){    FDBUNLOCKMETHOD(fdb);    return nan("");  }  bool rv = tcfdbputimpl(fdb, id, (char *)&num, sizeof(num), FDBPDADDDBL);  FDBUNLOCKRECORD(fdb, id);  FDBUNLOCKMETHOD(fdb);  return rv ? num : nan("");}/* Synchronize updated contents of a fixed-length database object with the file and the device. */bool tcfdbsync(TCFDB *fdb){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, true)) return false;  if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return false;  }  bool rv = tcfdbmemsync(fdb, true);  FDBUNLOCKMETHOD(fdb);  return rv;}/* Optimize the file of a fixed-length database object. */bool tcfdboptimize(TCFDB *fdb, int32_t width, int64_t limsiz){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, true)) return false;  if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return false;  }  bool rv = tcfdboptimizeimpl(fdb, width, limsiz);  FDBUNLOCKMETHOD(fdb);  return rv;}/* Remove all records of a fixed-length database object. */bool tcfdbvanish(TCFDB *fdb){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, true)) return false;  if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return false;  }  bool rv = tcfdbvanishimpl(fdb);  FDBUNLOCKMETHOD(fdb);  return rv;}/* Copy the database file of a fixed-length database object. */bool tcfdbcopy(TCFDB *fdb, const char *path){  assert(fdb && path);  if(!FDBLOCKMETHOD(fdb, false)) return false;  if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return false;  }  if(!FDBLOCKALLRECORDS(fdb, false)){    FDBUNLOCKMETHOD(fdb);    return false;  }  bool rv = tcfdbcopyimpl(fdb, path);  FDBUNLOCKALLRECORDS(fdb);  FDBUNLOCKMETHOD(fdb);  return rv;}/* Get the file path of a fixed-length database object. */const char *tcfdbpath(TCFDB *fdb){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, false)) return NULL;  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return NULL;  }  const char *rv = fdb->path;  FDBUNLOCKMETHOD(fdb);  return rv;}/* Get the number of records of a fixed-length database object. */uint64_t tcfdbrnum(TCFDB *fdb){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, false)) return 0;  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return 0;  }  uint64_t rv = fdb->rnum;  FDBUNLOCKMETHOD(fdb);  return rv;}/* Get the size of the database file of a fixed-length database object. */uint64_t tcfdbfsiz(TCFDB *fdb){  assert(fdb);  if(!FDBLOCKMETHOD(fdb, false)) return 0;  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    FDBUNLOCKMETHOD(fdb);    return 0;  }  uint64_t rv = fdb->fsiz;  FDBUNLOCKMETHOD(fdb);  return rv;}/************************************************************************************************* * features for experts *************************************************************************************************//* Set the error code of a fixed-length database object. */void tcfdbsetecode(TCFDB *fdb, int ecode, const char *filename, int line, const char *func){  assert(fdb && filename && line >= 1 && func);  if(!fdb->fatal){    fdb->ecode = ecode;    if(fdb->mmtx) pthread_setspecific(*(pthread_key_t *)fdb->eckey, (void *)(intptr_t)ecode);  }  if(ecode != TCEINVALID && ecode != TCEKEEP && ecode != TCENOREC){    fdb->fatal = true;    if(fdb->fd >= 0 && (fdb->omode & FDBOWRITER)) tcfdbsetflag(fdb, FDBFFATAL, true);  }  if(fdb->dbgfd >= 0){    char obuf[FDBIOBUFSIZ];    int osiz = sprintf(obuf, "ERROR:%s:%d:%s:%s:%d:%s\n", filename, line, func,                       fdb->path ? fdb->path : "-", ecode, tcfdberrmsg(ecode));    tcwrite(fdb->dbgfd, obuf, osiz);  }}/* Set the file descriptor for debugging output. */void tcfdbsetdbgfd(TCFDB *fdb, int fd){  assert(fdb && fd >= 0);  fdb->dbgfd = fd;}/* Get the file descriptor for debugging output. */int tcfdbdbgfd(TCFDB *fdb){  assert(fdb);  return fdb->dbgfd;}/* Synchronize updating contents on memory of a fixed-length database object. */bool tcfdbmemsync(TCFDB *fdb, bool phys){  assert(fdb);  if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    return false;  }  bool err = false;  char hbuf[FDBHEADSIZ];  tcdumpmeta(fdb, hbuf);  memcpy(fdb->map, hbuf, FDBOPAQUEOFF);  if(phys){    if(msync(fdb->map, fdb->limsiz, MS_SYNC) == -1){      tcfdbsetecode(fdb, TCEMMAP, __FILE__, __LINE__, __func__);      err = true;    }    if(fsync(fdb->fd) == -1){      tcfdbsetecode(fdb, TCESYNC, __FILE__, __LINE__, __func__);      err = true;    }  }  return !err;}/* Get the minimum ID number of records of a fixed-length database object. */uint64_t tcfdbmin(TCFDB *fdb){  assert(fdb);  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return fdb->min;}/* Get the maximum ID number of records of a fixed-length database object. */uint64_t tcfdbmax(TCFDB *fdb){  assert(fdb);  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return fdb->max;}/* Get the width of the value of each record of a fixed-length database object. */uint64_t tcfdbwidth(TCFDB *fdb){  assert(fdb);  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return fdb->width;}/* Get the limit file size of a fixed-length database object. */uint64_t tcfdblimsiz(TCFDB *fdb){  assert(fdb);  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return fdb->limsiz;}/* Get the limit ID number of a fixed-length database object. */uint64_t tcfdblimid(TCFDB *fdb){  assert(fdb);  if(fdb->fd < 0){    tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);    return 0;  }  return fdb->limid;}

⌨️ 快捷键说明

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