📄 dbz.c
字号:
register char *sepp; DEBUG(("fetch: (%s)\n", key.dptr)); output.dptr = NULL; output.dsize = 0; prevp = FRESH; /* Key is supposed to be less than DBZMAXKEY */ keysize = key.dsize; if (keysize >= DBZMAXKEY) { keysize = DBZMAXKEY; DEBUG(("keysize is %d - truncated to %d\n", key.dsize, DBZMAXKEY)); } if (pagf == NULL) { DEBUG(("fetch: database not open!\n")); return(output); } else if (basef == NULL) { /* basef didn't exist yet */ basef = latebase(); if (basef == NULL) return(output); } cmplen = keysize; sepp = &conf.fieldsep; if (key.dptr[keysize-1] == '\0') { cmplen--; sepp = &buffer[keysize-1]; } start(&srch, &key, FRESH); while ((key_ptr = search(&srch)) != NOTFOUND) { DEBUG(("got 0x%lx\n", key_ptr)); /* fetch the key */ if (fseek(basef, key_ptr, SEEK_SET) != 0) { DEBUG(("fetch: seek failed\n")); return(output); } if (fread((POINTER)buffer, 1, keysize, basef) != keysize) { DEBUG(("fetch: read failed\n")); return(output); } /* try it */ buffer[keysize] = '\0'; /* terminated for DEBUG */ (void) mapcase(buffer, buffer, keysize); DEBUG(("fetch: buffer (%s) looking for (%s) size = %d\n", buffer, key.dptr, keysize)); if (memcmp((POINTER)key.dptr, (POINTER)buffer, cmplen) == 0 && (*sepp == conf.fieldsep || *sepp == '\0')) { /* we found it */ output.dptr = (char *)&key_ptr; output.dsize = SOF; DEBUG(("fetch: successful\n")); return(output); } } /* we didn't find it */ DEBUG(("fetch: failed\n")); prevp = &srch; /* remember where we stopped */ return(output);}/* - latebase - try to open a base file that wasn't there at the start */static FILE *latebase(){ register FILE *it; if (basefname == NULL) { DEBUG(("latebase: name foulup\n")); return(NULL); } it = fopen(basefname, "r"); if (it == NULL) { DEBUG(("latebase: still can't open base\n")); } else { DEBUG(("latebase: late open succeeded\n")); free((POINTER)basefname); basefname = NULL;#ifdef _IOFBF (void) setvbuf(it, basebuf, _IOFBF, sizeof(basebuf));#endif } if (it != NULL) CloseOnExec((int)fileno(it), 1); return(it);}/* - dbzstore - store() with case mapping built in */intdbzstore(key, data)datum key;datum data;{ char buffer[DBZMAXKEY + 1]; datum mappedkey; register size_t keysize; DEBUG(("dbzstore: (%s)\n", key.dptr)); /* Key is supposed to be less than DBZMAXKEY */ keysize = key.dsize; if (keysize >= DBZMAXKEY) { DEBUG(("dbzstore: key size too big (%d)\n", key.dsize)); return(-1); } mappedkey.dptr = mapcase(buffer, key.dptr, keysize); buffer[keysize] = '\0'; /* just a debug aid */ mappedkey.dsize = keysize; return(store(mappedkey, data));}/* - store - add an entry to the database */int /* 0 success, -1 failure */store(key, data)datum key;datum data;{ of_t value; if (pagf == NULL) { DEBUG(("store: database not open!\n")); return(-1); } else if (basef == NULL) { /* basef didn't exist yet */ basef = latebase(); if (basef == NULL) return(-1); } if (pagronly) { DEBUG(("store: database open read-only\n")); return(-1); } if (data.dsize != SOF) { DEBUG(("store: value size wrong (%d)\n", data.dsize)); return(-1); } if (key.dsize >= DBZMAXKEY) { DEBUG(("store: key size too big (%d)\n", key.dsize)); return(-1); } /* copy the value in to ensure alignment */ (void) memcpy((POINTER)&value, (POINTER)data.dptr, SOF); DEBUG(("store: (%s, %ld)\n", key.dptr, (long)value)); if (!okayvalue(value)) { DEBUG(("store: reserved bit or overflow in 0x%lx\n", value)); return(-1); } /* find the place, exploiting previous search if possible */ start(&srch, &key, prevp); while (search(&srch) != NOTFOUND) continue; prevp = FRESH; conf.used[0]++; DEBUG(("store: used count %ld\n", conf.used[0])); written = 1; return(set(&srch, value));}/* - dbzincore - control attempts to keep .pag file in core */int /* old setting */dbzincore(value)int value;{ register int old = incore;#ifndef MMAP incore = value;#endif return(old);}/* - dbzwritethrough - write through the pag file in core */int /* old setting */dbzwritethrough(value)int value;{ register int old = writethrough; writethrough = value; return(old);}/* - dbztagmask - calculate the correct tagmask for the given base file size */longdbztagmask(size)register long size;{ register long m; register long tagmask; register int i; if (size <= 0) return(0L); /* silly size */ for (m = 1, i = 0; m < size; i++, m <<= 1) continue; if (m < (1 << TAGSHIFT)) return(0L); /* not worth tagging */ tagmask = (~(unsigned long)0) >> (i + 1); tagmask = tagmask << i; return(tagmask);}/* - getconf - get configuration from .dir file */static int /* 0 success, -1 failure */getconf(df, pf, cp)register FILE *df; /* NULL means just give me the default */register FILE *pf; /* NULL means don't care about .pag */register struct dbzconfig *cp;{ register int c; register int i; int err = 0; c = (df != NULL) ? getc(df) : EOF; if (c == EOF) { /* empty file, no configuration known */ cp->olddbz = 0; if (df != NULL && pf != NULL && getc(pf) != EOF) cp->olddbz = 1; cp->tsize = DEFSIZE; cp->fieldsep = '\t'; for (i = 0; i < NUSEDS; i++) cp->used[i] = 0; cp->valuesize = SOF; mybytemap(cp->bytemap); cp->casemap = DEFCASE; cp->tagenb = TAGENB; cp->tagmask = TAGMASK; cp->tagshift = TAGSHIFT; DEBUG(("getconf: defaults (%ld, %c, (0x%lx/0x%lx<<%d))\n", cp->tsize, cp->casemap, cp->tagenb, cp->tagmask, cp->tagshift)); return(0); } (void) ungetc(c, df); /* first line, the vital stuff */ if (getc(df) != 'd' || getc(df) != 'b' || getc(df) != 'z') err = -1; if (getno(df, &err) != dbzversion) err = -1; cp->tsize = getno(df, &err); cp->fieldsep = (int)getno(df, &err); while ((c = getc(df)) == ' ') continue; cp->casemap = c; cp->tagenb = getno(df, &err); cp->tagmask = getno(df, &err); cp->tagshift = getno(df, &err); cp->valuesize = getno(df, &err); if (cp->valuesize != SOF) { DEBUG(("getconf: wrong of_t size (%d)\n", cp->valuesize)); err = -1; cp->valuesize = SOF; /* to protect the loops below */ } for (i = 0; i < cp->valuesize; i++) cp->bytemap[i] = getno(df, &err); if (getc(df) != '\n') err = -1;#ifdef DBZDEBUG DEBUG(("size %ld, sep %d, cmap %c, tags 0x%lx/0x%lx<<%d, ", cp->tsize, cp->fieldsep, cp->casemap, cp->tagenb, cp->tagmask, cp->tagshift)); DEBUG(("bytemap (%d)", cp->valuesize)); for (i = 0; i < cp->valuesize; i++) { DEBUG((" %d", cp->bytemap[i])); } DEBUG(("\n"));#endif /* second line, the usages */ for (i = 0; i < NUSEDS; i++) cp->used[i] = getno(df, &err); if (getc(df) != '\n') err = -1; DEBUG(("used %ld %ld %ld...\n", cp->used[0], cp->used[1], cp->used[2])); if (err < 0) { DEBUG(("getconf error\n")); return(-1); } return(0);}/* - getno - get a long */static longgetno(f, ep)FILE *f;int *ep;{ register char *p;# define MAXN 50 char getbuf[MAXN]; register int c; while ((c = getc(f)) == ' ') continue; if (c == EOF || c == '\n') { DEBUG(("getno: missing number\n")); *ep = -1; return(0); } p = getbuf; *p++ = c; while ((c = getc(f)) != EOF && c != '\n' && c != ' ') if (p < &getbuf[MAXN-1]) *p++ = c; if (c == EOF) { DEBUG(("getno: EOF\n")); *ep = -1; } else (void) ungetc(c, f); *p = '\0'; if (strspn(getbuf, "-1234567890") != strlen(getbuf)) { DEBUG(("getno: `%s' non-numeric\n", getbuf)); *ep = -1; } return(atol(getbuf));}/* - putconf - write configuration to .dir file */static int /* 0 success, -1 failure */putconf(f, cp)register FILE *f;register struct dbzconfig *cp;{ register int i; register int ret = 0; if (fseek(f, (of_t)0, SEEK_SET) != 0) { DEBUG(("fseek failure in putconf\n")); ret = -1; } (void) fprintf(f, "dbz %d %ld %d %c %ld %ld %d %d", dbzversion, cp->tsize, cp->fieldsep, cp->casemap, cp->tagenb, cp->tagmask, cp->tagshift, cp->valuesize); for (i = 0; i < cp->valuesize; i++) (void) fprintf(f, " %d", cp->bytemap[i]); (void) fprintf(f, "\n"); for (i = 0; i < NUSEDS; i++) (void) fprintf(f, "%ld%c", cp->used[i], (i < NUSEDS-1) ? ' ' : '\n'); (void) fflush(f); if (ferror(f)) ret = -1; DEBUG(("putconf status %d\n", ret)); return(ret);}/* - getcore - try to set up an in-core copy of .pag file */static of_t * /* pointer to copy, or NULL */getcore(f)FILE *f;{ register of_t *p; register size_t i; register size_t nread; register char *it;#ifdef MMAP struct stat st; if (fstat(fileno(f), &st) == -1) { DEBUG(("getcore: fstat failed\n")); return(NULL); } if (((size_t)conf.tsize * SOF) > st.st_size) { /* file too small; extend it */ if (ftruncate((int)fileno(f), conf.tsize * SOF) == -1) { DEBUG(("getcore: ftruncate failed\n")); return(NULL); } } it = mmap((caddr_t)0, (size_t)conf.tsize * SOF, pagronly ? PROT_READ : PROT_WRITE | PROT_READ, MAP__ARG, (int)fileno(f), (off_t)0); if (it == (char *)-1) { DEBUG(("getcore: mmap failed\n")); return(NULL); }#ifdef MC_ADVISE /* not present in all versions of mmap() */ madvise(it, (size_t)conf.tsize * SOF, MADV_RANDOM);#endif#else it = malloc((size_t)conf.tsize * SOF); if (it == NULL) { DEBUG(("getcore: malloc failed\n")); return(NULL); } nread = fread((POINTER)it, SOF, (size_t)conf.tsize, f); if (ferror(f)) { DEBUG(("getcore: read failed\n")); free((POINTER)it); return(NULL); } /* NOSTRICT *//* Possible pointer alignment problem */ p = (of_t *)it + nread; i = (size_t)conf.tsize - nread; while (i-- > 0) *p++ = VACANT;#endif /* NOSTRICT *//* Possible pointer alignment problem */ return((of_t *)it);}#ifndef MMAP/* - putcore - try to rewrite an in-core table */static int /* 0 okay, -1 fail */putcore(tab, f)of_t *tab;FILE *f;{ if (fseek(f, (of_t)0, SEEK_SET) != 0) { DEBUG(("fseek failure in putcore\n")); return(-1); } (void) fwrite((POINTER)tab, SOF, (size_t)conf.tsize, f); (void) fflush(f); return((ferror(f)) ? -1 : 0);}#endif/* - start - set up to start or restart a search */static voidstart(sp, kp, osp)register struct searcher *sp;register datum *kp;register struct searcher *osp; /* may be FRESH, i.e. NULL */{ register long h; h = hash(kp->dptr, kp->dsize); if (osp != FRESH && osp->hash == h) { if (sp != osp) *sp = *osp; DEBUG(("search restarted\n")); } else { sp->hash = h; sp->tag = MKTAG(h / conf.tsize); DEBUG(("tag 0x%lx\n", sp->tag)); sp->place = h % conf.tsize; sp->tabno = 0; sp->run = (conf.olddbz) ? conf.tsize : MAXRUN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -