?? cdb_make.c
字號:
/* basic cdb creation routines * * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru. * Public domain. */#include "common/setup_before.h"#include <stdio.h>#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif# ifdef HAVE_MEMORY_H# include <memory.h># endif#endif#include "common/xalloc.h"#include "cdb_int.h"#include "common/setup_after.h"voidcdb_pack(unsigned num, unsigned char buf[4]){ buf[0] = num & 255; num >>= 8; buf[1] = num & 255; num >>= 8; buf[2] = num & 255; buf[3] = num >> 8;}intcdb_make_start(struct cdb_make *cdbmp, FILE *fd){ memset(cdbmp, 0, sizeof(*cdbmp)); cdbmp->cdb_fd = fd; cdbmp->cdb_dpos = 2048; cdbmp->cdb_bpos = cdbmp->cdb_buf + 2048; return 0;}static intewrite(FILE *fd, const char *buf, int len){ while(len) { int l = fwrite(buf, 1, len, fd); if (l < 0 && errno != EINTR) return -1; len -= l; buf += l; } return 0;}int_cdb_make_write(struct cdb_make *cdbmp, const char *ptr, unsigned len){ unsigned l = sizeof(cdbmp->cdb_buf) - (cdbmp->cdb_bpos - cdbmp->cdb_buf); cdbmp->cdb_dpos += len; if (len > l) { memcpy(cdbmp->cdb_bpos, ptr, l); if (ewrite(cdbmp->cdb_fd, cdbmp->cdb_buf, sizeof(cdbmp->cdb_buf)) < 0) return -1; ptr += l; len -= l; l = len / sizeof(cdbmp->cdb_buf); if (l) { l *= sizeof(cdbmp->cdb_buf); if (ewrite(cdbmp->cdb_fd, ptr, l) < 0) return -1; ptr += l; len -= l; } cdbmp->cdb_bpos = cdbmp->cdb_buf; } if (len) { memcpy(cdbmp->cdb_bpos, ptr, len); cdbmp->cdb_bpos += len; } return 0;}static intcdb_make_finish_internal(struct cdb_make *cdbmp){ unsigned hcnt[256]; /* hash table counts */ unsigned hpos[256]; /* hash table positions */ struct cdb_rec *htab; unsigned char *p; struct cdb_rl *rl; unsigned hsize; unsigned t, i; if (((0xffffffff - cdbmp->cdb_dpos) >> 3) < cdbmp->cdb_rcnt) return errno = ENOMEM, -1; /* count htab sizes and reorder reclists */ hsize = 0; for (t = 0; t < 256; ++t) { struct cdb_rl *rlt = NULL; i = 0; rl = cdbmp->cdb_rec[t]; while(rl) { struct cdb_rl *rln = rl->next; rl->next = rlt; rlt = rl; i += rl->cnt; rl = rln; } cdbmp->cdb_rec[t] = rlt; if (hsize < (hcnt[t] = i << 1)) hsize = hcnt[t]; } /* allocate memory to hold max htable */ htab = (struct cdb_rec*)xmalloc((hsize + 2) * sizeof(struct cdb_rec)); if (!htab) return errno = ENOENT, -1; p = (unsigned char *)htab; htab += 2; /* build hash tables */ for (t = 0; t < 256; ++t) { unsigned len, hi; hpos[t] = cdbmp->cdb_dpos; if ((len = hcnt[t]) == 0) continue; for (i = 0; i < len; ++i) htab[i].hval = htab[i].rpos = 0; for (rl = cdbmp->cdb_rec[t]; rl; rl = rl->next) for (i = 0; i < rl->cnt; ++i) { hi = (rl->rec[i].hval >> 8) % len; while(htab[hi].rpos) if (++hi == len) hi = 0; htab[hi] = rl->rec[i]; } for (i = 0; i < len; ++i) { cdb_pack(htab[i].hval, p + (i << 3)); cdb_pack(htab[i].rpos, p + (i << 3) + 4); } if (_cdb_make_write(cdbmp, p, len << 3) < 0) { xfree(p); return -1; } } xfree(p); if (cdbmp->cdb_bpos != cdbmp->cdb_buf && ewrite(cdbmp->cdb_fd, cdbmp->cdb_buf, cdbmp->cdb_bpos - cdbmp->cdb_buf) != 0) return -1; p = cdbmp->cdb_buf; for (t = 0; t < 256; ++t) { cdb_pack(hpos[t], p + (t << 3)); cdb_pack(hcnt[t], p + (t << 3) + 4); } rewind(cdbmp->cdb_fd); if (ewrite(cdbmp->cdb_fd, p, 2048) != 0) return -1; return 0;}static voidcdb_make_free(struct cdb_make *cdbmp){ unsigned t; for(t = 0; t < 256; ++t) { struct cdb_rl *rl = cdbmp->cdb_rec[t]; while(rl) { struct cdb_rl *tm = rl; rl = rl->next; xfree(tm); } }}intcdb_make_finish(struct cdb_make *cdbmp){ int r = cdb_make_finish_internal(cdbmp); cdb_make_free(cdbmp); return r;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -