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

📄 tcfdb.c

📁 Tokyo Cabinet的Tokyo Cabinet 是一个DBM的实现。这里的数据库由一系列key-value对的记录构成。key和value都可以是任意长度的字节序列,既可以是二进制也可以是字符
💻 C
📖 第 1 页 / 共 5 页
字号:
  fdb->mtime = sbuf.st_mtime;  fdb->tran = false;  fdb->walfd = -1;  fdb->walend = 0;  if(fdb->omode & FDBOWRITER) tcfdbsetflag(fdb, FDBFOPEN, true);  return true;}/* Close a fixed-length database object.   `fdb' specifies the fixed-length database object.   If successful, the return value is true, else, it is false. */static bool tcfdbcloseimpl(TCFDB *fdb){  assert(fdb);  bool err = false;  if(fdb->omode & FDBOWRITER) tcfdbsetflag(fdb, FDBFOPEN, false);  if((fdb->omode & FDBOWRITER) && !tcfdbmemsync(fdb, false)) err = true;  if(munmap(fdb->map, fdb->limsiz) == -1){    tcfdbsetecode(fdb, TCEMMAP, __FILE__, __LINE__, __func__);    err = true;  }  if(fdb->tran){    if(!tcfdbwalrestore(fdb, fdb->path)) err = true;    fdb->tran = false;  }  if(fdb->walfd >= 0){    if(close(fdb->walfd) == -1){      tcfdbsetecode(fdb, TCECLOSE, __FILE__, __LINE__, __func__);      err = true;    }    if(!fdb->fatal && !tcfdbwalremove(fdb, fdb->path)) err = true;  }  if(close(fdb->fd) == -1){    tcfdbsetecode(fdb, TCECLOSE, __FILE__, __LINE__, __func__);    err = true;  }  TCFREE(fdb->path);  fdb->path = NULL;  fdb->fd = -1;  return !err;}/* Get the previous record of a record.   `fdb' specifies the fixed-length database object.   `id' specifies the ID number.   The return value is the ID number of the previous record or 0 if no record corresponds. */static int64_t tcfdbprevid(TCFDB *fdb, int64_t id){  assert(fdb && id >= 0);  id--;  while(id >= fdb->min){    TCDODEBUG(fdb->cnt_readrec++);    unsigned char *rec = fdb->array + (id - 1) * (fdb->rsiz);    unsigned char *rp = rec;    uint32_t osiz;    uint16_t snum;    uint32_t lnum;    switch(fdb->wsiz){    case 1:      osiz = *(rp++);      break;    case 2:      memcpy(&snum, rp, sizeof(snum));      osiz = TCITOHS(snum);      rp += sizeof(snum);      break;    default:      memcpy(&lnum, rp, sizeof(lnum));      osiz = TCITOHL(lnum);      rp += sizeof(lnum);      break;    }    if(osiz > 0 || *rp != 0) return id;    id--;  }  return 0;}/* Get the next record of a record.   `fdb' specifies the fixed-length database object.   `id' specifies the ID number.   The return value is the ID number of the next record or 0 if no record corresponds. */static int64_t tcfdbnextid(TCFDB *fdb, int64_t id){  assert(fdb && id >= 0);  id++;  while(id <= fdb->max){    TCDODEBUG(fdb->cnt_readrec++);    unsigned char *rec = fdb->array + (id - 1) * (fdb->rsiz);    unsigned char *rp = rec;    uint32_t osiz;    uint16_t snum;    uint32_t lnum;    switch(fdb->wsiz){    case 1:      osiz = *(rp++);      break;    case 2:      memcpy(&snum, rp, sizeof(snum));      osiz = TCITOHS(snum);      rp += sizeof(snum);      break;    default:      memcpy(&lnum, rp, sizeof(lnum));      osiz = TCITOHL(lnum);      rp += sizeof(lnum);      break;    }    if(osiz > 0 || *rp != 0) return id;    id++;  }  return 0;}/* Store a record.   `fdb' specifies the fixed-length database object.   `id' specifies the ID number.   `vbuf' specifies the pointer to the region of the value.   `vsiz' specifies the size of the region of the value.   `dmode' specifies behavior when the key overlaps.   If successful, the return value is true, else, it is false. */static bool tcfdbputimpl(TCFDB *fdb, int64_t id, const void *vbuf, int vsiz, int dmode){  assert(fdb && id > 0);  if(vsiz > (int64_t)fdb->width) vsiz = fdb->width;  TCDODEBUG(fdb->cnt_readrec++);  unsigned char *rec = fdb->array + (id - 1) * (fdb->rsiz);  uint64_t nsiz = FDBHEADSIZ + id * fdb->rsiz;  if(nsiz > fdb->fsiz){    if(nsiz > fdb->limsiz){      tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);      return false;    }    if(!FDBLOCKATTR(fdb)) return false;    if(nsiz > fdb->fsiz){      if(vsiz < 0){        tcfdbsetecode(fdb, TCENOREC, __FILE__, __LINE__, __func__);        FDBUNLOCKATTR(fdb);        return false;      }      if(nsiz + fdb->rsiz * FDBTRUNCALW < fdb->limsiz) nsiz += fdb->rsiz * FDBTRUNCALW;      if(ftruncate(fdb->fd, nsiz) == -1){        tcfdbsetecode(fdb, TCETRUNC, __FILE__, __LINE__, __func__);        FDBUNLOCKATTR(fdb);        return false;      }      TCDODEBUG(fdb->cnt_truncfile++);      fdb->fsiz = nsiz;      unsigned char *wp = rec;      uint16_t snum;      uint32_t lnum;      switch(fdb->wsiz){      case 1:        *(wp++) = vsiz;        break;      case 2:        snum = TCHTOIS(vsiz);        memcpy(wp, &snum, sizeof(snum));        wp += sizeof(snum);        break;      default:        lnum = TCHTOIL(vsiz);        memcpy(wp, &lnum, sizeof(lnum));        wp += sizeof(lnum);        break;      }      if(vsiz > 0){        memcpy(wp, vbuf, vsiz);      } else {        *wp = 1;      }      TCDODEBUG(fdb->cnt_writerec++);      fdb->rnum++;      if(fdb->min < 1 || id < fdb->min) fdb->min = id;      if(fdb->max < 1 || id > fdb->max) fdb->max = id;      FDBUNLOCKATTR(fdb);      return true;    }    FDBUNLOCKATTR(fdb);  }  unsigned char *rp = rec;  uint32_t osiz;  uint16_t snum;  uint32_t lnum;  switch(fdb->wsiz){  case 1:    osiz = *(rp++);    break;  case 2:    memcpy(&snum, rp, sizeof(snum));    osiz = TCITOHS(snum);    rp += sizeof(snum);    break;  default:    memcpy(&lnum, rp, sizeof(lnum));    osiz = TCITOHL(lnum);    rp += sizeof(lnum);    break;  }  bool miss = osiz == 0 && *rp == 0;  if(dmode != FDBPDOVER && !miss){    if(dmode == FDBPDKEEP){      tcfdbsetecode(fdb, TCEKEEP, __FILE__, __LINE__, __func__);      return false;    }    if(dmode == FDBPDCAT){      if(fdb->tran && !tcfdbwalwrite(fdb, (char *)rec - fdb->map, fdb->width)) return false;      vsiz = tclmin(vsiz, fdb->width - osiz);      unsigned char *wp = rec;      int usiz = osiz + vsiz;      switch(fdb->wsiz){      case 1:        *(wp++) = usiz;        break;      case 2:        snum = TCHTOIS(usiz);        memcpy(wp, &snum, sizeof(snum));        wp += sizeof(snum);        break;      default:        lnum = TCHTOIL(usiz);        memcpy(wp, &lnum, sizeof(lnum));        wp += sizeof(lnum);        break;      }      if(usiz > 0){        memcpy(wp + osiz, vbuf, vsiz);      } else {        *wp = 1;      }      TCDODEBUG(fdb->cnt_writerec++);      return true;    }    if(dmode == FDBPDADDINT){      if(osiz != sizeof(int)){        tcfdbsetecode(fdb, TCEKEEP, __FILE__, __LINE__, __func__);        return false;      }      int lnum;      memcpy(&lnum, rp, sizeof(lnum));      if(*(int *)vbuf == 0){        *(int *)vbuf = lnum;        return true;      }      if(fdb->tran && !tcfdbwalwrite(fdb, (char *)rec - fdb->map, fdb->width)) return false;      lnum += *(int *)vbuf;      *(int *)vbuf = lnum;      memcpy(rp, &lnum, sizeof(lnum));      TCDODEBUG(fdb->cnt_writerec++);      return true;    }    if(dmode == FDBPDADDDBL){      if(osiz != sizeof(double)){        tcfdbsetecode(fdb, TCEKEEP, __FILE__, __LINE__, __func__);        return false;      }      double dnum;      memcpy(&dnum, rp, sizeof(dnum));      if(*(double *)vbuf == 0.0){        *(double *)vbuf = dnum;        return true;      }      if(fdb->tran && !tcfdbwalwrite(fdb, (char *)rec - fdb->map, fdb->width)) return false;      dnum += *(double *)vbuf;      *(double *)vbuf = dnum;      memcpy(rp, &dnum, sizeof(dnum));      TCDODEBUG(fdb->cnt_writerec++);      return true;    }    if(dmode == FDBPDPROC){      FDBPDPROCOP *procptr = *(FDBPDPROCOP **)((char *)vbuf - sizeof(procptr));      int nvsiz;      char *nvbuf = procptr->proc(rp, osiz, &nvsiz, procptr->op);      if(nvbuf == (void *)-1){        if(fdb->tran && !tcfdbwalwrite(fdb, (char *)rec - fdb->map, fdb->width)) return false;        memset(rec, 0, fdb->wsiz + 1);        TCDODEBUG(fdb->cnt_writerec++);        if(!FDBLOCKATTR(fdb)) return false;        fdb->rnum--;        if(fdb->rnum < 1){          fdb->min = 0;          fdb->max = 0;        } else if(fdb->rnum < 2){          if(fdb->min == id){            fdb->min = fdb->max;          } else if(fdb->max == id){            fdb->max = fdb->min;          }        } else {          if(id == fdb->min) fdb->min = tcfdbnextid(fdb, id);          if(id == fdb->max) fdb->max = tcfdbprevid(fdb, id);        }        FDBUNLOCKATTR(fdb);        return true;      }      if(!nvbuf){        tcfdbsetecode(fdb, TCEKEEP, __FILE__, __LINE__, __func__);        return false;      }      if(fdb->tran && !tcfdbwalwrite(fdb, (char *)rec - fdb->map, fdb->width)) return false;      if(nvsiz > fdb->width) nvsiz = fdb->width;      unsigned char *wp = rec;      switch(fdb->wsiz){      case 1:        *(wp++) = nvsiz;        break;      case 2:        snum = TCHTOIS(nvsiz);        memcpy(wp, &snum, sizeof(snum));        wp += sizeof(snum);        break;      default:        lnum = TCHTOIL(nvsiz);        memcpy(wp, &lnum, sizeof(lnum));        wp += sizeof(lnum);        break;      }      if(nvsiz > 0){        memcpy(wp, nvbuf, nvsiz);      } else {        *wp = 1;      }      TCFREE(nvbuf);      TCDODEBUG(fdb->cnt_writerec++);      return true;    }  }  if(vsiz < 0){    tcfdbsetecode(fdb, TCENOREC, __FILE__, __LINE__, __func__);    return false;  }  if(fdb->tran && !tcfdbwalwrite(fdb, (char *)rec - fdb->map, fdb->width)) return false;  unsigned char *wp = rec;  switch(fdb->wsiz){  case 1:    *(wp++) = vsiz;    break;  case 2:    snum = TCHTOIS(vsiz);    memcpy(wp, &snum, sizeof(snum));    wp += sizeof(snum);    break;  default:    lnum = TCHTOIL(vsiz);    memcpy(wp, &lnum, sizeof(lnum));    wp += sizeof(lnum);    break;  }  if(vsiz > 0){    memcpy(wp, vbuf, vsiz);  } else {    *wp = 1;  }  TCDODEBUG(fdb->cnt_writerec++);  if(miss){    if(!FDBLOCKATTR(fdb)) return false;    fdb->rnum++;    if(fdb->min < 1 || id < fdb->min) fdb->min = id;    if(fdb->max < 1 || id > fdb->max) fdb->max = id;    FDBUNLOCKATTR(fdb);  }  return true;}/* Remove a record of a fixed-length database object.   `fdb' specifies the fixed-length database object.   `id' specifies the ID number.   If successful, the return value is true, else, it is false. */static bool tcfdboutimpl(TCFDB *fdb, int64_t id){  assert(fdb && id >= 0);  TCDODEBUG(fdb->cnt_readrec++);  unsigned char *rec = fdb->array + (id - 1) * (fdb->rsiz);  uint64_t nsiz = FDBHEADSIZ + id * fdb->rsiz;  if(nsiz > fdb->fsiz){    tcfdbsetecode(fdb, TCENOREC, __FILE__, __LINE__, __func__);    return false;  }  unsigned char *rp = rec;  uint32_t osiz;  uint16_t snum;  uint32_t lnum;  switch(fdb->wsiz){  case 1:    osiz = *(rp++);    break;  case 2:    memcpy(&snum, rp, sizeof(snum));    osiz = TCITOHS(snum);    rp += sizeof(snum);    break;  default:    memcpy(&lnum, rp, sizeof(lnum));    osiz = TCITOHL(lnum);    rp += sizeof(lnum);    break;  }  if(osiz == 0 && *rp == 0){    tcfdbsetecode(fdb, TCENOREC, __FILE__, __LINE__, __func__);    return false;  }  if(fdb->tran && !tcfdbwalwrite(fdb, (char *)rec - fdb->map, fdb->width)) return false;  memset(rec, 0, fdb->wsiz + 1);  TCDODEBUG(fdb->cnt_writerec++);  if(!FDBLOCKATTR(fdb)) return false;  fdb->rnum--;  if(fdb->rnum < 1){    fdb->min = 0;    fdb->max = 0;  } else if(fdb->rnum < 2){    if(fdb->min == id){      fdb->min = fdb->max;    } else if(fdb->max == id){      fdb->max = fdb->min;    }  } else {    if(id == fdb->min) fdb->min = tcfdbnextid(fdb, id);    if(id == fdb->max) fdb->max = tcfdbprevid(fdb, id);  }  FDBUNLOCKATTR(fdb);  return true;}/* Retrieve a record.   `fdb' specifies the fixed-length database object.   `id' specifies the ID number.   `sp' specifies the pointer to the variable into which the size of the region of the return   value is assigned.   If successful, the return value is the pointer to the region of the value of the corresponding   record. */static const void *tcfdbgetimpl(TCFDB *fdb, int64_t id, int *sp){  assert(fdb && id >= 0 && sp);  TCDODEBUG(fdb->cnt_readrec++);  unsigned char *rec = fdb->array + (id - 1) * (fdb->rsiz);  uint64_t nsiz = FDBHEADSIZ + id * fdb->rsiz;  if(nsiz > fdb->fsiz){    tcfdbsetecode(fdb, TCENOREC, __FILE__, __LINE__, __func__);    return false;  }  unsigned char *rp = rec;  ui

⌨️ 快捷键说明

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