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

📄 tcutil.c

📁 高性能嵌入式数据库在高并发的环境下使用最好是64位系统比较好
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Create a map object with specifying the number of the buckets. */TCMAP *tcmapnew2(uint32_t bnum){  if(bnum < 1) bnum = 1;  TCMAP *map;  TCMALLOC(map, sizeof(*map));  TCMAPREC **buckets;  if(bnum >= TCMAPZMMINSIZ / sizeof(*buckets)){    buckets = tczeromap(bnum * sizeof(*buckets));  } else {    TCCALLOC(buckets, bnum, sizeof(*buckets));  }  map->buckets = buckets;  map->first = NULL;  map->last = NULL;  map->cur = NULL;  map->bnum = bnum;  map->rnum = 0;  map->msiz = 0;  return map;}/* Copy a map object. */TCMAP *tcmapdup(const TCMAP *map){  assert(map);  TCMAP *nmap = tcmapnew2(tclmax(tclmax(map->bnum, map->rnum), TCMAPBNUM));  TCMAPREC *rec = map->first;  while(rec){    char *dbuf = (char *)rec + sizeof(*rec);    tcmapput(nmap, dbuf, rec->ksiz, dbuf + rec->ksiz + TCALIGNPAD(rec->ksiz), rec->vsiz);    rec = rec->next;  }  return nmap;}/* Close a map object. */void tcmapdel(TCMAP *map){  assert(map);  TCMAPREC *rec = map->first;  while(rec){    TCMAPREC *next = rec->next;    TCFREE(rec);    rec = next;  }  if(map->bnum >= TCMAPZMMINSIZ / sizeof(map->buckets[0])){    tczerounmap(map->buckets);  } else {    TCFREE(map->buckets);  }  TCFREE(map);}/* Store a record into a map object. */void tcmapput(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz){  assert(map && kbuf && ksiz >= 0 && vbuf && vsiz >= 0);  unsigned int hash;  TCMAPHASH1(hash, kbuf, ksiz);  int bidx = hash % map->bnum;  TCMAPREC *rec = map->buckets[bidx];  TCMAPREC **entp = map->buckets + bidx;  TCMAPHASH2(hash, kbuf, ksiz);  while(rec){    if(hash > rec->hash){      entp = &(rec->left);      rec = rec->left;    } else if(hash < rec->hash){      entp = &(rec->right);      rec = rec->right;    } else {      char *dbuf = (char *)rec + sizeof(*rec);      int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz);      if(kcmp < 0){        entp = &(rec->left);        rec = rec->left;      } else if(kcmp > 0){        entp = &(rec->right);        rec = rec->right;      } else {        map->msiz += vsiz - rec->vsiz;        int psiz = TCALIGNPAD(ksiz);        if(vsiz > rec->vsiz){          TCMAPREC *old = rec;          TCREALLOC(rec, rec, sizeof(*rec) + ksiz + psiz + vsiz + 1);          if(rec != old){            if(map->first == old) map->first = rec;            if(map->last == old) map->last = rec;            if(map->cur == old) map->cur = rec;            if(*entp == old) *entp = rec;            if(rec->prev) rec->prev->next = rec;            if(rec->next) rec->next->prev = rec;            dbuf = (char *)rec + sizeof(*rec);          }        }        memcpy(dbuf + ksiz + psiz, vbuf, vsiz);        dbuf[ksiz+psiz+vsiz] = '\0';        rec->vsiz = vsiz;        return;      }    }  }  int psiz = TCALIGNPAD(ksiz);  map->msiz += ksiz + vsiz;  TCMALLOC(rec, sizeof(*rec) + ksiz + psiz + vsiz + 1);  char *dbuf = (char *)rec + sizeof(*rec);  memcpy(dbuf, kbuf, ksiz);  dbuf[ksiz] = '\0';  rec->ksiz = ksiz;  memcpy(dbuf + ksiz + psiz, vbuf, vsiz);  dbuf[ksiz+psiz+vsiz] = '\0';  rec->vsiz = vsiz;  rec->hash = hash;  rec->left = NULL;  rec->right = NULL;  rec->prev = map->last;  rec->next = NULL;  *entp = rec;  if(!map->first) map->first = rec;  if(map->last) map->last->next = rec;  map->last = rec;  map->rnum++;}/* Store a string record into a map object. */void tcmapput2(TCMAP *map, const char *kstr, const char *vstr){  assert(map && kstr && vstr);  tcmapput(map, kstr, strlen(kstr), vstr, strlen(vstr));}/* Store a record of the value of two regions into a map object. */void tcmapput3(TCMAP *map, const void *kbuf, int ksiz,               const void *fvbuf, int fvsiz, const void *lvbuf, int lvsiz){  assert(map && kbuf && ksiz >= 0 && fvbuf && fvsiz >= 0 && lvbuf && lvsiz >= 0);  unsigned int hash;  TCMAPHASH1(hash, kbuf, ksiz);  int bidx = hash % map->bnum;  TCMAPREC *rec = map->buckets[bidx];  TCMAPREC **entp = map->buckets + bidx;  TCMAPHASH2(hash, kbuf, ksiz);  while(rec){    if(hash > rec->hash){      entp = &(rec->left);      rec = rec->left;    } else if(hash < rec->hash){      entp = &(rec->right);      rec = rec->right;    } else {      char *dbuf = (char *)rec + sizeof(*rec);      int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz);      if(kcmp < 0){        entp = &(rec->left);        rec = rec->left;      } else if(kcmp > 0){        entp = &(rec->right);        rec = rec->right;      } else {        int vsiz = fvsiz + lvsiz;        map->msiz += vsiz - rec->vsiz;        int psiz = TCALIGNPAD(ksiz);        ksiz += psiz;        if(vsiz > rec->vsiz){          TCMAPREC *old = rec;          TCREALLOC(rec, rec, sizeof(*rec) + ksiz + vsiz + 1);          if(rec != old){            if(map->first == old) map->first = rec;            if(map->last == old) map->last = rec;            if(map->cur == old) map->cur = rec;            if(*entp == old) *entp = rec;            if(rec->prev) rec->prev->next = rec;            if(rec->next) rec->next->prev = rec;            dbuf = (char *)rec + sizeof(*rec);          }        }        memcpy(dbuf + ksiz, fvbuf, fvsiz);        memcpy(dbuf + ksiz + fvsiz, lvbuf, lvsiz);        dbuf[ksiz+vsiz] = '\0';        rec->vsiz = vsiz;        return;      }    }  }  int vsiz = fvsiz + lvsiz;  int psiz = TCALIGNPAD(ksiz);  map->msiz += ksiz + vsiz;  TCMALLOC(rec, sizeof(*rec) + ksiz + psiz + vsiz + 1);  char *dbuf = (char *)rec + sizeof(*rec);  memcpy(dbuf, kbuf, ksiz);  dbuf[ksiz] = '\0';  rec->ksiz = ksiz;  ksiz += psiz;  memcpy(dbuf + ksiz, fvbuf, fvsiz);  memcpy(dbuf + ksiz + fvsiz, lvbuf, lvsiz);  dbuf[ksiz+vsiz] = '\0';  rec->vsiz = vsiz;  rec->hash = hash;  rec->left = NULL;  rec->right = NULL;  rec->prev = map->last;  rec->next = NULL;  *entp = rec;  if(!map->first) map->first = rec;  if(map->last) map->last->next = rec;  map->last = rec;  map->rnum++;}/* Store a new record into a map object. */bool tcmapputkeep(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz){  assert(map && kbuf && ksiz >= 0 && vbuf && vsiz >= 0);  unsigned int hash;  TCMAPHASH1(hash, kbuf, ksiz);  int bidx = hash % map->bnum;  TCMAPREC *rec = map->buckets[bidx];  TCMAPREC **entp = map->buckets + bidx;  TCMAPHASH2(hash, kbuf, ksiz);  while(rec){    if(hash > rec->hash){      entp = &(rec->left);      rec = rec->left;    } else if(hash < rec->hash){      entp = &(rec->right);      rec = rec->right;    } else {      char *dbuf = (char *)rec + sizeof(*rec);      int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz);      if(kcmp < 0){        entp = &(rec->left);        rec = rec->left;      } else if(kcmp > 0){        entp = &(rec->right);        rec = rec->right;      } else {        return false;      }    }  }  int psiz = TCALIGNPAD(ksiz);  map->msiz += ksiz + vsiz;  TCMALLOC(rec, sizeof(*rec) + ksiz + psiz + vsiz + 1);  char *dbuf = (char *)rec + sizeof(*rec);  memcpy(dbuf, kbuf, ksiz);  dbuf[ksiz] = '\0';  rec->ksiz = ksiz;  memcpy(dbuf + ksiz + psiz, vbuf, vsiz);  dbuf[ksiz+psiz+vsiz] = '\0';  rec->vsiz = vsiz;  rec->hash = hash;  rec->left = NULL;  rec->right = NULL;  rec->prev = map->last;  rec->next = NULL;  *entp = rec;  if(!map->first) map->first = rec;  if(map->last) map->last->next = rec;  map->last = rec;  map->rnum++;  return true;}/* Store a new string record into a map object. */bool tcmapputkeep2(TCMAP *map, const char *kstr, const char *vstr){  assert(map && kstr && vstr);  return tcmapputkeep(map, kstr, strlen(kstr), vstr, strlen(vstr));}/* Concatenate a value at the end of the value of the existing record in a map object. */void tcmapputcat(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz){  assert(map && kbuf && ksiz >= 0 && vbuf && vsiz >= 0);  unsigned int hash;  TCMAPHASH1(hash, kbuf, ksiz);  int bidx = hash % map->bnum;  TCMAPREC *rec = map->buckets[bidx];  TCMAPREC **entp = map->buckets + bidx;  TCMAPHASH2(hash, kbuf, ksiz);  while(rec){    if(hash > rec->hash){      entp = &(rec->left);      rec = rec->left;    } else if(hash < rec->hash){      entp = &(rec->right);      rec = rec->right;    } else {      char *dbuf = (char *)rec + sizeof(*rec);      int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz);      if(kcmp < 0){        entp = &(rec->left);        rec = rec->left;      } else if(kcmp > 0){        entp = &(rec->right);        rec = rec->right;      } else {        map->msiz += vsiz;        int psiz = TCALIGNPAD(ksiz);        int asiz = sizeof(*rec) + ksiz + psiz + rec->vsiz + vsiz + 1;        int unit = (asiz <= TCMAPCSUNIT) ? TCMAPCSUNIT : TCMAPCBUNIT;        asiz = (asiz - 1) + unit - (asiz - 1) % unit;        TCMAPREC *old = rec;        TCREALLOC(rec, rec, asiz);        if(rec != old){          if(map->first == old) map->first = rec;          if(map->last == old) map->last = rec;          if(map->cur == old) map->cur = rec;          if(*entp == old) *entp = rec;          if(rec->prev) rec->prev->next = rec;          if(rec->next) rec->next->prev = rec;          dbuf = (char *)rec + sizeof(*rec);        }        memcpy(dbuf + ksiz + psiz + rec->vsiz, vbuf, vsiz);        rec->vsiz += vsiz;        dbuf[ksiz+psiz+rec->vsiz] = '\0';        return;      }    }  }  int psiz = TCALIGNPAD(ksiz);  int asiz = sizeof(*rec) + ksiz + psiz + vsiz + 1;  int unit = (asiz <= TCMAPCSUNIT) ? TCMAPCSUNIT : TCMAPCBUNIT;  asiz = (asiz - 1) + unit - (asiz - 1) % unit;  map->msiz += ksiz + vsiz;  TCMALLOC(rec, asiz);  char *dbuf = (char *)rec + sizeof(*rec);  memcpy(dbuf, kbuf, ksiz);  dbuf[ksiz] = '\0';  rec->ksiz = ksiz;  memcpy(dbuf + ksiz + psiz, vbuf, vsiz);  dbuf[ksiz+psiz+vsiz] = '\0';  rec->vsiz = vsiz;  rec->hash = hash;  rec->left = NULL;  rec->right = NULL;  rec->prev = map->last;  rec->next = NULL;  *entp = rec;  if(!map->first) map->first = rec;  if(map->last) map->last->next = rec;  map->last = rec;  map->rnum++;}/* Concatenate a string value at the end of the value of the existing record in a map object. */void tcmapputcat2(TCMAP *map, const char *kstr, const char *vstr){  assert(map && kstr && vstr);  tcmapputcat(map, kstr, strlen(kstr), vstr, strlen(vstr));}/* Remove a record of a map object. */bool tcmapout(TCMAP *map, const void *kbuf, int ksiz){  assert(map && kbuf && ksiz >= 0);  unsigned int hash;  TCMAPHASH1(hash, kbuf, ksiz);  int bidx = hash % map->bnum;  TCMAPREC *rec = map->buckets[bidx];  TCMAPREC **entp = map->buckets + bidx;  TCMAPHASH2(hash, kbuf, ksiz);  while(rec){    if(hash > rec->hash){      entp = &(rec->left);      rec = rec->left;    } else if(hash < rec->hash){      entp = &(rec->right);      rec = rec->right;    } else {      char *dbuf = (char *)rec + sizeof(*rec);      int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz);      if(kcmp < 0){        entp = &(rec->left);        rec = rec->left;      } else if(kcmp > 0){        entp = &(rec->right);        rec = rec->right;      } else {        map->rnum--;        map->msiz -= rec->ksiz + rec->vsiz;        if(rec->prev) rec->prev->next = rec->next;        if(rec->next) rec->next->prev = rec->prev;        if(rec == map->first) map->first = rec->next;        if(rec == map->last) map->last = rec->prev;        if(rec == map->cur) map->cur = rec->next;        if(rec->left && !rec->right){          *entp = rec->left;        } else if(!rec->left && rec->right){          *entp = rec->right;        } else if(!rec->left && !rec->left){          *entp = NULL;        } else {          *entp = rec->left;          TCMAPREC *tmp = *entp;          while(tmp->right){            tmp = tmp->right;          }          tmp->right = rec->right;        }        TCFREE(rec);        return true;      }    }  }  return false;}/* Remove a string record of a map object. */bool tcmapout2(TCMAP *map, const char *kstr){  assert(map && kstr);  return tcmapout(map, kstr, strlen(kstr));}/* Retrieve a record in a map object. */const void *tcmapget(const TCMAP *map, const void *kbuf, int ksiz, int *sp){  assert(map && kbuf && ksiz >= 0 && sp);  unsigned int hash;  TCMAPHASH1(hash, kbuf, ksiz);  TCMAPREC *rec = map->buckets[hash%map->bnum];  TCMAPHASH2(hash, kbuf, ksiz);  while(rec){    if(hash > rec->hash){      rec = rec->left;    } else if(hash < rec->hash){      rec = rec->right;    } else {      char *dbuf = (char *)rec + sizeof(*rec);      int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz);      if(kcmp < 0){        rec = rec->left;      } else if(kcmp > 0){        rec = rec->right;      } else {        *sp = rec->vsiz;        return dbuf + rec->ksiz + TCALIGNPAD(rec->ksiz);      }    }  }  return NULL;}/* Retrieve a string record in a map object. */const char *tcmapget2(const TCMAP *map, const char *kstr){  assert(map && kstr);  int ksiz = strlen(kstr);  unsigned int hash;  TCMAPHASH1(hash, kstr, ksiz);  TCMAPREC *rec = map->buckets[hash%map->bnum];  TCMAPHASH2(hash, kstr, ksiz);  while(rec){    if(hash > rec->hash){      rec = rec->left;    } else if(hash < rec->hash){      rec = rec->right;    } else {      char *dbuf = (char *)rec + sizeof(*rec);      int kcmp = TCKEYCMP(kstr, ksiz, dbuf, rec->ksiz);      if(kcmp < 0){        rec = rec->left;      } else if(kcmp > 0){        rec = rec->right;      } else {

⌨️ 快捷键说明

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