SCCS-vsn: lib/libc/db/hash/hash.c 5.17
SCCS-vsn: lib/libc/db/hash/hash.h 5.6
SCCS-vsn: lib/libc/db/hash/hash_page.c 5.16
*/
#if defined(LIBC_SCCS) && !defined(lint)
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash.c 5.16 (Berkeley) %G%";
+static char sccsid[] = "@(#)hash.c 5.17 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
/* Verify file type, versions and hash function */
if (hashp->MAGIC != HASHMAGIC)
RETURN_ERROR(EFTYPE, error1);
/* Verify file type, versions and hash function */
if (hashp->MAGIC != HASHMAGIC)
RETURN_ERROR(EFTYPE, error1);
- if (hashp->VERSION != VERSION_NO)
+ if (hashp->VERSION != HASHVERSION)
RETURN_ERROR(EFTYPE, error1);
if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY)
RETURN_ERROR(EFTYPE, error1);
RETURN_ERROR(EFTYPE, error1);
if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY)
RETURN_ERROR(EFTYPE, error1);
*/
return (NULL);
/* Read in bitmaps */
*/
return (NULL);
/* Read in bitmaps */
- bpages = (hashp->SPARES[__log2(hashp->MAX_BUCKET)] +
+ bpages = (hashp->SPARES[hashp->OVFL_POINT] +
(hashp->BSIZE << BYTE_SHIFT) - 1) >>
(hashp->BSHIFT + BYTE_SHIFT);
(hashp->BSIZE << BYTE_SHIFT) - 1) >>
(hashp->BSHIFT + BYTE_SHIFT);
#ifdef DEBUG
(void)fprintf(stderr,
#ifdef DEBUG
(void)fprintf(stderr,
-"%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%x\n%s%x\n%s%d\n%s%d\n",
+"%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",
"init_htab:",
"TABLE POINTER ", hashp,
"BUCKET SIZE ", hashp->BSIZE,
"init_htab:",
"TABLE POINTER ", hashp,
"BUCKET SIZE ", hashp->BSIZE,
"SEGMENT SHIFT ", hashp->SSHIFT,
"FILL FACTOR ", hashp->FFACTOR,
"MAX BUCKET ", hashp->MAX_BUCKET,
"SEGMENT SHIFT ", hashp->SSHIFT,
"FILL FACTOR ", hashp->FFACTOR,
"MAX BUCKET ", hashp->MAX_BUCKET,
+ "OVFL POINT ", hashp->OVFL_POINT,
+ "LAST FREED ", hashp->LAST_FREED,
"HIGH MASK ", hashp->HIGH_MASK,
"LOW MASK ", hashp->LOW_MASK,
"NSEGS ", hashp->nsegs,
"HIGH MASK ", hashp->HIGH_MASK,
"LOW MASK ", hashp->LOW_MASK,
"NSEGS ", hashp->nsegs,
hashp->LORDER = BYTE_ORDER;
hashp->BSIZE = DEF_BUCKET_SIZE;
hashp->BSHIFT = DEF_BUCKET_SHIFT;
hashp->LORDER = BYTE_ORDER;
hashp->BSIZE = DEF_BUCKET_SIZE;
hashp->BSHIFT = DEF_BUCKET_SHIFT;
hashp->FFACTOR = DEF_FFACTOR;
hashp->hash = default_hash;
bzero(hashp->SPARES, sizeof(hashp->SPARES));
hashp->FFACTOR = DEF_FFACTOR;
hashp->hash = default_hash;
bzero(hashp->SPARES, sizeof(hashp->SPARES));
+ bzero (hashp->BITMAPS, sizeof (hashp->BITMAPS));
if (info) {
if (info->bsize) {
if (info) {
if (info->bsize) {
hashp->SPARES[l2] = l2 + 1;
hashp->SPARES[l2 + 1] = l2 + 1;
hashp->SPARES[l2] = l2 + 1;
hashp->SPARES[l2 + 1] = l2 + 1;
+ hashp->OVFL_POINT = l2;
+ hashp->LAST_FREED = 2;
+
/* First bitmap page is at: splitpoint l2 page offset 1 */
if (__init_bitmap(OADDR_OF(l2, 1), l2 + 1, 0))
return (-1);
/* First bitmap page is at: splitpoint l2 page offset 1 */
if (__init_bitmap(OADDR_OF(l2, 1), l2 + 1, 0))
return (-1);
if (!hashp->save_file)
return (0);
hashp->MAGIC = HASHMAGIC;
if (!hashp->save_file)
return (0);
hashp->MAGIC = HASHMAGIC;
- hashp->VERSION = VERSION_NO;
+ hashp->VERSION = HASHVERSION;
hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
fp = hashp->fp;
hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
fp = hashp->fp;
* split bucket to the next bucket.
*/
spare_ndx = __log2(hashp->MAX_BUCKET);
* split bucket to the next bucket.
*/
spare_ndx = __log2(hashp->MAX_BUCKET);
- if (spare_ndx != (__log2(hashp->MAX_BUCKET - 1)))
- hashp->SPARES[spare_ndx] = hashp->SPARES[spare_ndx - 1];
+ if ( spare_ndx > hashp->OVFL_POINT ) {
+ hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
+ hashp->OVFL_POINT = spare_ndx;
+ }
+
if (new_bucket > hashp->HIGH_MASK) {
/* Starting a new doubling */
hashp->LOW_MASK = hashp->HIGH_MASK;
if (new_bucket > hashp->HIGH_MASK) {
/* Starting a new doubling */
hashp->LOW_MASK = hashp->HIGH_MASK;
BLSWAP_COPY(srcp->dsize, destp->dsize);
BLSWAP_COPY(srcp->ssize, destp->ssize);
BLSWAP_COPY(srcp->sshift, destp->sshift);
BLSWAP_COPY(srcp->dsize, destp->dsize);
BLSWAP_COPY(srcp->ssize, destp->ssize);
BLSWAP_COPY(srcp->sshift, destp->sshift);
+ BLSWAP_COPY(srcp->ovfl_point, destp->ovfl_point);
+ BLSWAP_COPY(srcp->last_freed, destp->last_freed);
BLSWAP_COPY(srcp->max_bucket, destp->max_bucket);
BLSWAP_COPY(srcp->high_mask, destp->high_mask);
BLSWAP_COPY(srcp->low_mask, destp->low_mask);
BLSWAP_COPY(srcp->max_bucket, destp->max_bucket);
BLSWAP_COPY(srcp->high_mask, destp->high_mask);
BLSWAP_COPY(srcp->low_mask, destp->low_mask);
BLSWAP(hdrp->dsize);
BLSWAP(hdrp->ssize);
BLSWAP(hdrp->sshift);
BLSWAP(hdrp->dsize);
BLSWAP(hdrp->ssize);
BLSWAP(hdrp->sshift);
+ BLSWAP(hdrp->ovfl_point);
+ BLSWAP(hdrp->last_freed);
BLSWAP(hdrp->max_bucket);
BLSWAP(hdrp->high_mask);
BLSWAP(hdrp->low_mask);
BLSWAP(hdrp->max_bucket);
BLSWAP(hdrp->high_mask);
BLSWAP(hdrp->low_mask);
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)hash.h 5.5 (Berkeley) %G%
+ * @(#)hash.h 5.6 (Berkeley) %G%
int dsize; /* Directory Size */
int ssize; /* Segment Size */
int sshift; /* Segment shift */
int dsize; /* Directory Size */
int ssize; /* Segment Size */
int sshift; /* Segment shift */
+ int ovfl_point; /* Where overflow pages are being allocated */
+ int last_freed; /* Last overflow page freed */
int max_bucket; /* ID of Maximum bucket in use */
int high_mask; /* Mask to modulo into entire table */
int low_mask; /* Mask to modulo into lower half of table */
int max_bucket; /* ID of Maximum bucket in use */
int high_mask; /* Mask to modulo into entire table */
int low_mask; /* Mask to modulo into lower half of table */
#define SPLTMAX 8
#define CHARKEY "%$sniglet^&"
#define NUMKEY 1038583
#define SPLTMAX 8
#define CHARKEY "%$sniglet^&"
#define NUMKEY 1038583
#define BYTE_SHIFT 3
#define INT_TO_BYTE 2
#define INT_BYTE_SHIFT 5
#define BYTE_SHIFT 3
#define INT_TO_BYTE 2
#define INT_BYTE_SHIFT 5
#define SGSIZE hdr.ssize
#define SSHIFT hdr.sshift
#define LORDER hdr.lorder
#define SGSIZE hdr.ssize
#define SSHIFT hdr.sshift
#define LORDER hdr.lorder
+#define OVFL_POINT hdr.ovfl_point
+#define LAST_FREED hdr.last_freed
#define MAX_BUCKET hdr.max_bucket
#define FFACTOR hdr.ffactor
#define HIGH_MASK hdr.high_mask
#define MAX_BUCKET hdr.max_bucket
#define FFACTOR hdr.ffactor
#define HIGH_MASK hdr.high_mask
*/
#if defined(LIBC_SCCS) && !defined(lint)
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_page.c 5.15 (Berkeley) %G%";
+static char sccsid[] = "@(#)hash_page.c 5.16 (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
/*
#endif /* LIBC_SCCS and not lint */
/*
register u_long *freep;
register int max_free, offset, splitnum;
u_short addr;
register u_long *freep;
register int max_free, offset, splitnum;
u_short addr;
- int bit, free_bit, free_page, i, in_use_bits, j;
+ int bit, first_page, free_bit, free_page, i, in_use_bits, j;
#ifdef DEBUG2
int tmp1, tmp2;
#endif
#ifdef DEBUG2
int tmp1, tmp2;
#endif
- splitnum = __log2(hashp->MAX_BUCKET);
+ splitnum = hashp->OVFL_POINT;
max_free = hashp->SPARES[splitnum];
free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
/* Look through all the free maps to find the first free block */
max_free = hashp->SPARES[splitnum];
free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
/* Look through all the free maps to find the first free block */
- for (i = 0; i <= free_page; i++) {
+ first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
+ for ( i = first_page; i <= free_page; i++ ) {
if (!(freep = (u_long *)hashp->mapp[i]) &&
!(freep = fetch_bitmap(i)))
return (NULL);
if (!(freep = (u_long *)hashp->mapp[i]) &&
!(freep = fetch_bitmap(i)))
return (NULL);
in_use_bits = free_bit;
else
in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
in_use_bits = free_bit;
else
in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
-
- for (j = 0, bit = 0; bit <= in_use_bits;
- j++, bit += BITS_PER_MAP)
+
+ if (i == first_page) {
+ bit = hashp->LAST_FREED &
+ ((hashp->BSIZE << BYTE_SHIFT) - 1);
+ j = bit / BITS_PER_MAP;
+ bit = bit & ~(BITS_PER_MAP - 1);
+ } else {
+ bit = 0;
+ j = 0;
+ }
+ for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
if (freep[j] != ALL_SET)
goto found;
}
/* No Free Page Found */
if (freep[j] != ALL_SET)
goto found;
}
/* No Free Page Found */
+ hashp->LAST_FREED = hashp->SPARES[splitnum];
hashp->SPARES[splitnum]++;
offset = hashp->SPARES[splitnum] -
(splitnum ? hashp->SPARES[splitnum - 1] : 0);
hashp->SPARES[splitnum]++;
offset = hashp->SPARES[splitnum] -
(splitnum ? hashp->SPARES[splitnum - 1] : 0);
+#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
+ if (offset > SPLITMASK) {
+ if (++splitnum >= NCACHED) {
+ (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
+ return (NULL);
+ }
+ hashp->OVFL_POINT = splitnum;
+ hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
+ hashp->SPARES[splitnum-1]--;
+ offset = 0;
+ }
+
/* Check if we need to allocate a new bitmap page */
if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
free_page++;
/* Check if we need to allocate a new bitmap page */
if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
free_page++;
-#define OVMSG "hash: out of overflow pages; increase page size\n"
if (free_page >= NCACHED) {
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
return (NULL);
if (free_page >= NCACHED) {
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
return (NULL);
free_bit = 2;
#endif
offset++;
free_bit = 2;
#endif
offset++;
+ if (offset > SPLITMASK) {
+ if (++splitnum >= NCACHED) {
+ (void)write(STDERR_FILENO, OVMSG,
+ sizeof(OVMSG) - 1);
+ return (NULL);
+ }
+ hashp->OVFL_POINT = splitnum;
+ hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
+ hashp->SPARES[splitnum-1]--;
+ offset = 0;
+ }
} else {
/*
* Free_bit addresses the last used bit. Bump it to address
} else {
/*
* Free_bit addresses the last used bit. Bump it to address
}
/* Calculate address of the new overflow page */
}
/* Calculate address of the new overflow page */
- if (offset > SPLITMASK) {
- (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
- return (NULL);
- }
addr = OADDR_OF(splitnum, offset);
#ifdef DEBUG2
(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
addr = OADDR_OF(splitnum, offset);
#ifdef DEBUG2
(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
* it to convert it to a page number.
*/
bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
* it to convert it to a page number.
*/
bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
+ if (bit >= hashp->LAST_FREED)
+ hashp->LAST_FREED = bit - 1;
/* Calculate the split number for this page */
for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
/* Calculate the split number for this page */
for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
ndx = (((u_short)addr) >> SPLITSHIFT);
bit_address =
(ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
ndx = (((u_short)addr) >> SPLITSHIFT);
bit_address =
(ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
+ if (bit_address < hashp->LAST_FREED)
+ hashp->LAST_FREED = bit_address;
free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);