37 #if defined(LIBC_SCCS) && !defined(lint) 38 static char sccsid[] =
"@(#)hash.c 8.9 (Berkeley) 6/16/94";
41 #include <sys/param.h> 54 #include "../include/db.h" 73 #if BYTE_ORDER == LITTLE_ENDIAN 79 #define MOD(x, y) ((x) & ((y) - 1)) 81 #define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; } 88 #ifdef HASH_STATISTICS 89 int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
104 int bpages, hdrsize, new_table, nsegs, save_errno;
106 if ((flags & O_ACCMODE) == O_WRONLY) {
121 hashp->
flags = flags;
124 if (!file || (flags & O_TRUNC) ||
125 (stat(file, &statbuf) && (
errno == ENOENT))) {
131 if ((hashp->
fp = open(file, flags, mode)) == -1)
133 (void)fcntl(hashp->
fp, F_SETFD, 1);
136 if (!(hashp =
init_hash(hashp, file, info)))
140 if (info && info->hash)
141 hashp->hash = info->hash;
143 hashp->hash = __default_hash;
145 hdrsize = read(hashp->
fp, &hashp->
hdr,
sizeof(
HASHHDR));
146 #if BYTE_ORDER == LITTLE_ENDIAN 151 if (hdrsize !=
sizeof(
HASHHDR))
156 #define OLDHASHVERSION 1 168 nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
178 bpages = (hashp->SPARES[hashp->OVFL_POINT] +
182 hashp->
nmaps = bpages;
183 (void)memset(&hashp->
mapp[0], 0, bpages *
sizeof(
u_int32_t *));
193 hashp->
save_file = file && (hashp->
flags & O_ACCMODE) != O_RDONLY;
201 dbp->internal = hashp;
212 (void)fprintf(stderr,
213 "%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
215 "TABLE POINTER ", hashp,
216 "BUCKET SIZE ", hashp->BSIZE,
217 "BUCKET SHIFT ", hashp->BSHIFT,
218 "DIRECTORY SIZE ", hashp->DSIZE,
219 "SEGMENT SIZE ", hashp->SGSIZE,
220 "SEGMENT SHIFT ", hashp->SSHIFT,
221 "FILL FACTOR ", hashp->FFACTOR,
222 "MAX BUCKET ", hashp->MAX_BUCKET,
223 "OVFL POINT ", hashp->OVFL_POINT,
224 "LAST FREED ", hashp->LAST_FREED,
225 "HIGH MASK ", hashp->HIGH_MASK,
226 "LOW MASK ", hashp->LOW_MASK,
227 "NSEGS ", hashp->
nsegs,
228 "NKEYS ", hashp->NKEYS);
230 #ifdef HASH_STATISTICS 231 hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
237 (void)close(hashp->
fp);
271 if (hashp->
fp == -1) {
285 #ifdef _STATBUF_ST_BLKSIZE 299 hashp->hash = __default_hash;
300 memset(hashp->SPARES, 0,
sizeof(hashp->SPARES));
301 memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS));
304 #ifdef _STATBUF_ST_BLKSIZE 306 if (stat(file, &statbuf))
308 hashp->BSIZE = statbuf.st_blksize;
317 hashp->BSIZE = 1 << hashp->BSHIFT;
324 hashp->FFACTOR = info->
ffactor;
326 hashp->hash = info->hash;
335 hashp->LORDER = info->
lorder;
355 register int nbuckets, nsegs;
363 nelem = (nelem - 1) / hashp->FFACTOR + 1;
368 hashp->SPARES[l2] = l2 + 1;
369 hashp->SPARES[l2 + 1] = l2 + 1;
370 hashp->OVFL_POINT = l2;
371 hashp->LAST_FREED = 2;
377 hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
378 hashp->HIGH_MASK = (nbuckets << 1) - 1;
382 nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
385 if (nsegs > hashp->DSIZE)
386 hashp->DSIZE = nsegs;
404 #ifdef HASH_STATISTICS 405 (void)fprintf(stderr,
"hdestroy: accesses %ld collisions %ld\n",
406 hash_accesses, hash_collisions);
407 (void)fprintf(stderr,
"hdestroy: expansions %ld\n",
409 (void)fprintf(stderr,
"hdestroy: overflows %ld\n",
411 (void)fprintf(stderr,
"keys %ld maxp %d segmentcount %d\n",
412 hashp->NKEYS, hashp->MAX_BUCKET, hashp->
nsegs);
415 (
void)fprintf(stderr,
416 "spares[%d] = %d\n", i, hashp->SPARES[i]);
434 for (i = 0; i < hashp->
nmaps; i++)
439 (void)close(hashp->
fp);
490 #if BYTE_ORDER == LITTLE_ENDIAN 503 #if BYTE_ORDER == LITTLE_ENDIAN 507 if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
508 ((wsize = write(fp, whdrp,
sizeof(
HASHHDR))) == -1))
511 if (wsize !=
sizeof(
HASHHDR)) {
519 hashp->BITMAPS[i], 0, 1))
564 if ((hashp->
flags & O_ACCMODE) == O_RDONLY) {
585 if ((hashp->
flags & O_ACCMODE) == O_RDONLY) {
604 register int n, ndx, off, size;
608 #ifdef HASH_STATISTICS 614 kp = (
char *)key->
data;
622 for (bp = (
u_int16_t *)rbufp->
page, n = *bp++, ndx = 1; ndx < n;)
625 if (size == off - *bp &&
626 memcmp(kp, rbufp->
page + *bp, size) == 0)
629 #ifdef HASH_STATISTICS 657 rbufp =
__get_buf(hashp, pageno, bufp, 0);
677 if (
__addel(hashp, rbufp, key, val)) {
702 val->
data = (u_char *)rbufp->
page + (
int)bp[ndx + 1];
703 val->
size = bp[ndx] - bp[ndx + 1];
708 (
__addel(hashp, rbufp, key, val))) {
740 #ifdef HASH_STATISTICS 749 for (bp =
NULL; !bp || !bp[0]; ) {
750 if (!(bufp = hashp->
cpage)) {
753 bucket++, hashp->
cndx = 1) {
763 if (hashp->
cbucket > hashp->MAX_BUCKET) {
775 bufp = hashp->
cpage =
793 key->
size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
795 data->
size = bp[ndx] - bp[ndx + 1];
819 int dirsize, new_segnum, spare_ndx;
821 #ifdef HASH_STATISTICS 824 new_bucket = ++hashp->MAX_BUCKET;
825 old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
827 new_segnum = new_bucket >> hashp->SSHIFT;
830 if (new_segnum >= hashp->
nsegs) {
832 if (new_segnum >= hashp->DSIZE) {
834 dirsize = hashp->DSIZE *
sizeof(
SEGMENT *);
837 hashp->DSIZE = dirsize << 1;
839 if ((hashp->
dir[new_segnum] =
851 if (spare_ndx > hashp->OVFL_POINT) {
852 hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
853 hashp->OVFL_POINT = spare_ndx;
856 if (new_bucket > (
u_int32_t) hashp->HIGH_MASK) {
858 hashp->LOW_MASK = hashp->HIGH_MASK;
859 hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
872 int oldsize, newsize;
876 if ((p =
malloc(newsize))) {
877 memmove(p, *p_ptr, oldsize);
878 memset((
char *)p + oldsize, 0, newsize - oldsize);
893 n = hashp->hash(k, len);
894 bucket = n & hashp->HIGH_MASK;
895 if (bucket > hashp->MAX_BUCKET)
896 bucket = bucket & hashp->LOW_MASK;
930 for (i = 0; i < nsegs; i++, hashp->
nsegs++)
931 hashp->
dir[i] = &store[i << hashp->SSHIFT];
935 #if BYTE_ORDER == LITTLE_ENDIAN 962 for (i = 0; i <
NCACHED; i++) {
977 M_32_SWAP(hdrp->
magic);
980 M_32_SWAP(hdrp->
bsize);
982 M_32_SWAP(hdrp->
dsize);
983 M_32_SWAP(hdrp->
ssize);
991 M_32_SWAP(hdrp->
nkeys);
994 for (i = 0; i <
NCACHED; i++) {
995 M_32_SWAP(hdrp->
spares[i]);
static int hash_put(DB *dbp, DBT *key, const DBT *data, u_int32_t flag) const
int __buf_free(HTAB *hashp, int do_free, int to_disk)
int __big_keydata(HTAB *hashp, BUFHEAD *bufp, DBT *key, DBT *val, int set)
#define DEF_SEGSIZE_SHIFT
#define RETURN_ERROR(ERR, LOC)
static void * hash_realloc(SEGMENT **p_ptr, int oldsize, int newsize)
static int hdestroy(HTAB *hashp)
static int hash_fd(DB *dbp) const
int __expand_table(HTAB *hashp)
int __addel(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val)
DB * __hash_open(char *file, int flags, int mode, const HASHINFO *info, int dflags) const
static int flush_meta(HTAB *hashp)
u_int32_t * mapp[NCACHED]
static void swap_header_copy(HASHHDR *srcp, HASHHDR *destp)
static int hash_access(HTAB *hashp, ACTION action, DBT *key, DBT *val)
u_int16_t bitmaps[NCACHED]
u_int16_t __find_last_page(HTAB *hashp, BUFHEAD **bpp)
u_int32_t __call_hash(HTAB *hashp, char *k, int len)
u_int32_t __hash_log2(u_int32_t num)
int __delpair(HTAB *hashp, BUFHEAD *bufp, int ndx)
int __put_page(HTAB *hashp, char *p, u_int32_t bucket, int is_bucket, int is_bitmap)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int hash_get(DB *dbp, const DBT *key, DBT *data, u_int32_t flag) const
static int init_htab(HTAB *hashp, int nelem)
static int alloc_segs __P((HTAB *, int))
BUFHEAD * __get_buf(HTAB *hashp, u_int32_t addr, BUFHEAD *prev_bp, int newpage)
static void swap_header(HTAB *hashp)
static int alloc_segs(HTAB *hashp, int nsegs)
int __find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, int size)
static int hash_sync(DB *dbp, u_int32_t flags) const
int __ibitmap(HTAB *hashp, int pnum, int nbits, int ndx)
void __buf_init(HTAB *hashp, int nbytes)
int __split_page(HTAB *hashp, u_int32_t obucket, u_int32_t nbucket)
int __big_return(HTAB *hashp, BUFHEAD *bufp, int ndx, DBT *val, int set_current)
static int hash_delete(DB *dbp, const DBT *key, u_int32_t flag) const
static int hash_close(DB *dbp)
static int hash_seq(DB *dbp, DBT *key, DBT *data, u_int32_t flag) const
static HTAB * init_hash(HTAB *hashp, const char *file, const HASHINFO *info)