xref: /original-bsd/lib/libc/db/hash/hash_page.c (revision c48498db)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Margo Seltzer.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #if defined(LIBC_SCCS) && !defined(lint)
12 static char sccsid[] = "@(#)hash_page.c	5.25 (Berkeley) 02/16/93";
13 #endif /* LIBC_SCCS and not lint */
14 
15 /*
16  * PACKAGE:  hashing
17  *
18  * DESCRIPTION:
19  *	Page manipulation for hashing package.
20  *
21  * ROUTINES:
22  *
23  * External
24  *	__get_page
25  *	__add_ovflpage
26  * Internal
27  *	overflow_page
28  *	open_temp
29  */
30 
31 #include <sys/types.h>
32 
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <signal.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #ifdef DEBUG
41 #include <assert.h>
42 #endif
43 
44 #include <db.h>
45 #include "hash.h"
46 #include "page.h"
47 #include "extern.h"
48 
49 static u_long	*fetch_bitmap __P((HTAB *, int));
50 static u_long	 first_free __P((u_long));
51 static int	 open_temp __P((HTAB *));
52 static u_short	 overflow_page __P((HTAB *));
53 static void	 putpair __P((char *, const DBT *, const DBT *));
54 static void	 squeeze_key __P((u_short *, const DBT *, const DBT *));
55 static int	 ugly_split
56 		    __P((HTAB *, u_int, BUFHEAD *, BUFHEAD *, int, int));
57 
58 #define	PAGE_INIT(P) { \
59 	((u_short *)(P))[0] = 0; \
60 	((u_short *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_short); \
61 	((u_short *)(P))[2] = hashp->BSIZE; \
62 }
63 
64 /*
65  * This is called AFTER we have verified that there is room on the page for
66  * the pair (PAIRFITS has returned true) so we go right ahead and start moving
67  * stuff on.
68  */
69 static void
70 putpair(p, key, val)
71 	char *p;
72 	const DBT *key, *val;
73 {
74 	register u_short *bp, n, off;
75 
76 	bp = (u_short *)p;
77 
78 	/* Enter the key first. */
79 	n = bp[0];
80 
81 	off = OFFSET(bp) - key->size;
82 	memmove(p + off, key->data, key->size);
83 	bp[++n] = off;
84 
85 	/* Now the data. */
86 	off -= val->size;
87 	memmove(p + off, val->data, val->size);
88 	bp[++n] = off;
89 
90 	/* Adjust page info. */
91 	bp[0] = n;
92 	bp[n + 1] = off - ((n + 3) * sizeof(u_short));
93 	bp[n + 2] = off;
94 }
95 
96 /*
97  * Returns:
98  *	 0 OK
99  *	-1 error
100  */
101 extern int
102 __delpair(hashp, bufp, ndx)
103 	HTAB *hashp;
104 	BUFHEAD *bufp;
105 	register int ndx;
106 {
107 	register u_short *bp, newoff;
108 	register int n;
109 	u_short pairlen;
110 
111 	bp = (u_short *)bufp->page;
112 	n = bp[0];
113 
114 	if (bp[ndx + 1] < REAL_KEY)
115 		return (__big_delete(hashp, bufp));
116 	if (ndx != 1)
117 		newoff = bp[ndx - 1];
118 	else
119 		newoff = hashp->BSIZE;
120 	pairlen = newoff - bp[ndx + 1];
121 
122 	if (ndx != (n - 1)) {
123 		/* Hard Case -- need to shuffle keys */
124 		register int i;
125 		register char *src = bufp->page + (int)OFFSET(bp);
126 		register char *dst = src + (int)pairlen;
127 		memmove(dst, src, bp[ndx + 1] - OFFSET(bp));
128 
129 		/* Now adjust the pointers */
130 		for (i = ndx + 2; i <= n; i += 2) {
131 			if (bp[i + 1] == OVFLPAGE) {
132 				bp[i - 2] = bp[i];
133 				bp[i - 1] = bp[i + 1];
134 			} else {
135 				bp[i - 2] = bp[i] + pairlen;
136 				bp[i - 1] = bp[i + 1] + pairlen;
137 			}
138 		}
139 	}
140 	/* Finally adjust the page data */
141 	bp[n] = OFFSET(bp) + pairlen;
142 	bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_short);
143 	bp[0] = n - 2;
144 	hashp->NKEYS--;
145 
146 	bufp->flags |= BUF_MOD;
147 	return (0);
148 }
149 /*
150  * Returns:
151  *	 0 ==> OK
152  *	-1 ==> Error
153  */
154 extern int
155 __split_page(hashp, obucket, nbucket)
156 	HTAB *hashp;
157 	u_int obucket, nbucket;
158 {
159 	register BUFHEAD *new_bufp, *old_bufp;
160 	register u_short *ino;
161 	register char *np;
162 	DBT key, val;
163 	int n, ndx, retval;
164 	u_short copyto, diff, off, moved;
165 	char *op;
166 
167 	copyto = (u_short)hashp->BSIZE;
168 	off = (u_short)hashp->BSIZE;
169 	old_bufp = __get_buf(hashp, obucket, NULL, 0);
170 	if (old_bufp == NULL)
171 		return (-1);
172 	new_bufp = __get_buf(hashp, nbucket, NULL, 0);
173 	if (new_bufp == NULL)
174 		return (-1);
175 
176 	old_bufp->flags |= (BUF_MOD | BUF_PIN);
177 	new_bufp->flags |= (BUF_MOD | BUF_PIN);
178 
179 	ino = (u_short *)(op = old_bufp->page);
180 	np = new_bufp->page;
181 
182 	moved = 0;
183 
184 	for (n = 1, ndx = 1; n < ino[0]; n += 2) {
185 		if (ino[n + 1] < REAL_KEY) {
186 			retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
187 			    (int)copyto, (int)moved);
188 			old_bufp->flags &= ~BUF_PIN;
189 			new_bufp->flags &= ~BUF_PIN;
190 			return (retval);
191 
192 		}
193 		key.data = (u_char *)op + ino[n];
194 		key.size = off - ino[n];
195 
196 		if (__call_hash(hashp, key.data, key.size) == obucket) {
197 			/* Don't switch page */
198 			diff = copyto - off;
199 			if (diff) {
200 				copyto = ino[n + 1] + diff;
201 				memmove(op + copyto, op + ino[n + 1],
202 				    off - ino[n + 1]);
203 				ino[ndx] = copyto + ino[n] - ino[n + 1];
204 				ino[ndx + 1] = copyto;
205 			} else
206 				copyto = ino[n + 1];
207 			ndx += 2;
208 		} else {
209 			/* Switch page */
210 			val.data = (u_char *)op + ino[n + 1];
211 			val.size = ino[n] - ino[n + 1];
212 			putpair(np, &key, &val);
213 			moved += 2;
214 		}
215 
216 		off = ino[n + 1];
217 	}
218 
219 	/* Now clean up the page */
220 	ino[0] -= moved;
221 	FREESPACE(ino) = copyto - sizeof(u_short) * (ino[0] + 3);
222 	OFFSET(ino) = copyto;
223 
224 #ifdef DEBUG3
225 	(void)fprintf(stderr, "split %d/%d\n",
226 	    ((u_short *)np)[0] / 2,
227 	    ((u_short *)op)[0] / 2);
228 #endif
229 	/* unpin both pages */
230 	old_bufp->flags &= ~BUF_PIN;
231 	new_bufp->flags &= ~BUF_PIN;
232 	return (0);
233 }
234 
235 /*
236  * Called when we encounter an overflow or big key/data page during split
237  * handling.  This is special cased since we have to begin checking whether
238  * the key/data pairs fit on their respective pages and because we may need
239  * overflow pages for both the old and new pages.
240  *
241  * The first page might be a page with regular key/data pairs in which case
242  * we have a regular overflow condition and just need to go on to the next
243  * page or it might be a big key/data pair in which case we need to fix the
244  * big key/data pair.
245  *
246  * Returns:
247  *	 0 ==> success
248  *	-1 ==> failure
249  */
250 static int
251 ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
252 	HTAB *hashp;
253 	u_int obucket;	/* Same as __split_page. */
254 	BUFHEAD *old_bufp, *new_bufp;
255 	int copyto;	/* First byte on page which contains key/data values. */
256 	int moved;	/* Number of pairs moved to new page. */
257 {
258 	register BUFHEAD *bufp;	/* Buffer header for ino */
259 	register u_short *ino;	/* Page keys come off of */
260 	register u_short *np;	/* New page */
261 	register u_short *op;	/* Page keys go on to if they aren't moving */
262 
263 	BUFHEAD *last_bfp;	/* Last buf header OVFL needing to be freed */
264 	DBT key, val;
265 	SPLIT_RETURN ret;
266 	u_short n, off, ov_addr, scopyto;
267 	char *cino;		/* Character value of ino */
268 
269 	bufp = old_bufp;
270 	ino = (u_short *)old_bufp->page;
271 	np = (u_short *)new_bufp->page;
272 	op = (u_short *)old_bufp->page;
273 	last_bfp = NULL;
274 	scopyto = (u_short)copyto;	/* ANSI */
275 
276 	n = ino[0] - 1;
277 	while (n < ino[0]) {
278 		if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
279 			/*
280 			 * Ov_addr gets set before reaching this point; there's
281 			 * always an overflow page before a big key/data page.
282 			 */
283 			if (__big_split(hashp, old_bufp,
284 			    new_bufp, bufp, ov_addr, obucket, &ret))
285 				return (-1);
286 			old_bufp = ret.oldp;
287 			if (!old_bufp)
288 				return (-1);
289 			op = (u_short *)old_bufp->page;
290 			new_bufp = ret.newp;
291 			if (!new_bufp)
292 				return (-1);
293 			np = (u_short *)new_bufp->page;
294 			bufp = ret.nextp;
295 			if (!bufp)
296 				return (0);
297 			cino = (char *)bufp->page;
298 			ino = (u_short *)cino;
299 			last_bfp = ret.nextp;
300 		} else if (ino[n + 1] == OVFLPAGE) {
301 			ov_addr = ino[n];
302 			/*
303 			 * Fix up the old page -- the extra 2 are the fields
304 			 * which contained the overflow information.
305 			 */
306 			ino[0] -= (moved + 2);
307 			FREESPACE(ino) =
308 			    scopyto - sizeof(u_short) * (ino[0] + 3);
309 			OFFSET(ino) = scopyto;
310 
311 			bufp = __get_buf(hashp, ov_addr, bufp, 0);
312 			if (!bufp)
313 				return (-1);
314 
315 			ino = (u_short *)bufp->page;
316 			n = 1;
317 			scopyto = hashp->BSIZE;
318 			moved = 0;
319 
320 			if (last_bfp)
321 				__free_ovflpage(hashp, last_bfp);
322 			last_bfp = bufp;
323 		}
324 		/* Move regular sized pairs of there are any */
325 		off = hashp->BSIZE;
326 		for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
327 			cino = (char *)ino;
328 			key.data = (u_char *)cino + ino[n];
329 			key.size = off - ino[n];
330 			val.data = (u_char *)cino + ino[n + 1];
331 			val.size = ino[n] - ino[n + 1];
332 			off = ino[n + 1];
333 
334 			if (__call_hash(hashp, key.data, key.size) == obucket) {
335 				/* Keep on old page */
336 				if (PAIRFITS(op, (&key), (&val)))
337 					putpair((char *)op, &key, &val);
338 				else {
339 					old_bufp =
340 					    __add_ovflpage(hashp, old_bufp);
341 					if (!old_bufp)
342 						return (-1);
343 					op = (u_short *)old_bufp->page;
344 					putpair((char *)op, &key, &val);
345 				}
346 				old_bufp->flags |= BUF_MOD;
347 			} else {
348 				/* Move to new page */
349 				if (PAIRFITS(np, (&key), (&val)))
350 					putpair((char *)np, &key, &val);
351 				else {
352 					new_bufp =
353 					    __add_ovflpage(hashp, new_bufp);
354 					if (!new_bufp)
355 						return (-1);
356 					np = (u_short *)new_bufp->page;
357 					putpair((char *)np, &key, &val);
358 				}
359 				new_bufp->flags |= BUF_MOD;
360 			}
361 		}
362 	}
363 	if (last_bfp)
364 		__free_ovflpage(hashp, last_bfp);
365 	return (0);
366 }
367 
368 /*
369  * Add the given pair to the page
370  *
371  * Returns:
372  *	0 ==> OK
373  *	1 ==> failure
374  */
375 extern int
376 __addel(hashp, bufp, key, val)
377 	HTAB *hashp;
378 	BUFHEAD *bufp;
379 	const DBT *key, *val;
380 {
381 	register u_short *bp, *sop;
382 	int do_expand;
383 
384 	bp = (u_short *)bufp->page;
385 	do_expand = 0;
386 	while (bp[0] && (bp[bp[0]] < REAL_KEY))
387 		/* Exception case */
388 		if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
389 			/* This is a big-keydata pair */
390 			bufp = __add_ovflpage(hashp, bufp);
391 			if (!bufp)
392 				return (-1);
393 			bp = (u_short *)bufp->page;
394 		} else
395 			/* Try to squeeze key on this page */
396 			if (FREESPACE(bp) > PAIRSIZE(key, val)) {
397 				squeeze_key(bp, key, val);
398 				return (0);
399 			} else {
400 				bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
401 				if (!bufp)
402 					return (-1);
403 				bp = (u_short *)bufp->page;
404 			}
405 
406 	if (PAIRFITS(bp, key, val))
407 		putpair(bufp->page, key, val);
408 	else {
409 		do_expand = 1;
410 		bufp = __add_ovflpage(hashp, bufp);
411 		if (!bufp)
412 			return (-1);
413 		sop = (u_short *)bufp->page;
414 
415 		if (PAIRFITS(sop, key, val))
416 			putpair((char *)sop, key, val);
417 		else
418 			if (__big_insert(hashp, bufp, key, val))
419 				return (-1);
420 	}
421 	bufp->flags |= BUF_MOD;
422 	/*
423 	 * If the average number of keys per bucket exceeds the fill factor,
424 	 * expand the table.
425 	 */
426 	hashp->NKEYS++;
427 	if (do_expand ||
428 	    (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
429 		return (__expand_table(hashp));
430 	return (0);
431 }
432 
433 /*
434  *
435  * Returns:
436  *	pointer on success
437  *	NULL on error
438  */
439 extern BUFHEAD *
440 __add_ovflpage(hashp, bufp)
441 	HTAB *hashp;
442 	BUFHEAD *bufp;
443 {
444 	register u_short *sp;
445 	u_short ndx, ovfl_num;
446 #ifdef DEBUG1
447 	int tmp1, tmp2;
448 #endif
449 	sp = (u_short *)bufp->page;
450 	bufp->flags |= BUF_MOD;
451 	ovfl_num = overflow_page(hashp);
452 #ifdef DEBUG1
453 	tmp1 = bufp->addr;
454 	tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
455 #endif
456 	if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
457 		return (NULL);
458 	bufp->ovfl->flags |= BUF_MOD;
459 #ifdef DEBUG1
460 	(void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
461 	    tmp1, tmp2, bufp->ovfl->addr);
462 #endif
463 	ndx = sp[0];
464 	/*
465 	 * Since a pair is allocated on a page only if there's room to add
466 	 * an overflow page, we know that the OVFL information will fit on
467 	 * the page.
468 	 */
469 	sp[ndx + 4] = OFFSET(sp);
470 	sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
471 	sp[ndx + 1] = ovfl_num;
472 	sp[ndx + 2] = OVFLPAGE;
473 	sp[0] = ndx + 2;
474 #ifdef HASH_STATISTICS
475 	hash_overflows++;
476 #endif
477 	return (bufp->ovfl);
478 }
479 
480 /*
481  * Returns:
482  *	 0 indicates SUCCESS
483  *	-1 indicates FAILURE
484  */
485 extern int
486 __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
487 	HTAB *hashp;
488 	char *p;
489 	u_int bucket;
490 	int is_bucket, is_disk, is_bitmap;
491 {
492 	register int fd, page, size;
493 	int rsize;
494 	u_short *bp;
495 
496 	fd = hashp->fp;
497 	size = hashp->BSIZE;
498 
499 	if ((fd == -1) || !is_disk) {
500 		PAGE_INIT(p);
501 		return (0);
502 	}
503 	if (is_bucket)
504 		page = BUCKET_TO_PAGE(bucket);
505 	else
506 		page = OADDR_TO_PAGE(bucket);
507 	if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
508 	    ((rsize = read(fd, p, size)) == -1))
509 		return (-1);
510 	bp = (u_short *)p;
511 	if (!rsize)
512 		bp[0] = 0;	/* We hit the EOF, so initialize a new page */
513 	else
514 		if (rsize != size) {
515 			errno = EFTYPE;
516 			return (-1);
517 		}
518 	if (!is_bitmap && !bp[0]) {
519 		PAGE_INIT(p);
520 	} else
521 		if (hashp->LORDER != BYTE_ORDER) {
522 			register int i, max;
523 
524 			if (is_bitmap) {
525 				max = hashp->BSIZE >> 2; /* divide by 4 */
526 				for (i = 0; i < max; i++)
527 					BLSWAP(((long *)p)[i]);
528 			} else {
529 				BSSWAP(bp[0]);
530 				max = bp[0] + 2;
531 				for (i = 1; i <= max; i++)
532 					BSSWAP(bp[i]);
533 			}
534 		}
535 	return (0);
536 }
537 
538 /*
539  * Write page p to disk
540  *
541  * Returns:
542  *	 0 ==> OK
543  *	-1 ==>failure
544  */
545 extern int
546 __put_page(hashp, p, bucket, is_bucket, is_bitmap)
547 	HTAB *hashp;
548 	char *p;
549 	u_int bucket;
550 	int is_bucket, is_bitmap;
551 {
552 	register int fd, page, size;
553 	int wsize;
554 
555 	size = hashp->BSIZE;
556 	if ((hashp->fp == -1) && open_temp(hashp))
557 		return (-1);
558 	fd = hashp->fp;
559 
560 	if (hashp->LORDER != BYTE_ORDER) {
561 		register int i;
562 		register int max;
563 
564 		if (is_bitmap) {
565 			max = hashp->BSIZE >> 2;	/* divide by 4 */
566 			for (i = 0; i < max; i++)
567 				BLSWAP(((long *)p)[i]);
568 		} else {
569 			max = ((u_short *)p)[0] + 2;
570 			for (i = 0; i <= max; i++)
571 				BSSWAP(((u_short *)p)[i]);
572 		}
573 	}
574 	if (is_bucket)
575 		page = BUCKET_TO_PAGE(bucket);
576 	else
577 		page = OADDR_TO_PAGE(bucket);
578 	if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
579 	    ((wsize = write(fd, p, size)) == -1))
580 		/* Errno is set */
581 		return (-1);
582 	if (wsize != size) {
583 		errno = EFTYPE;
584 		return (-1);
585 	}
586 	return (0);
587 }
588 
589 #define BYTE_MASK	((1 << INT_BYTE_SHIFT) -1)
590 /*
591  * Initialize a new bitmap page.  Bitmap pages are left in memory
592  * once they are read in.
593  */
594 extern int
595 __init_bitmap(hashp, pnum, nbits, ndx)
596 	HTAB *hashp;
597 	int pnum, nbits, ndx;
598 {
599 	u_long *ip;
600 	int clearbytes, clearints;
601 
602 	if (!(ip = malloc(hashp->BSIZE)))
603 		return (1);
604 	hashp->nmaps++;
605 	clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
606 	clearbytes = clearints << INT_TO_BYTE;
607 	(void)memset((char *)ip, 0, clearbytes);
608 	(void)memset(((char *)ip) + clearbytes, 0xFF,
609 	    hashp->BSIZE - clearbytes);
610 	ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
611 	SETBIT(ip, 0);
612 	hashp->BITMAPS[ndx] = (u_short)pnum;
613 	hashp->mapp[ndx] = ip;
614 	return (0);
615 }
616 
617 static u_long
618 first_free(map)
619 	u_long map;
620 {
621 	register u_long i, mask;
622 
623 	mask = 0x1;
624 	for (i = 0; i < BITS_PER_MAP; i++) {
625 		if (!(mask & map))
626 			return (i);
627 		mask = mask << 1;
628 	}
629 	return (i);
630 }
631 
632 static u_short
633 overflow_page(hashp)
634 	HTAB *hashp;
635 {
636 	register u_long *freep;
637 	register int max_free, offset, splitnum;
638 	u_short addr;
639 	int bit, first_page, free_bit, free_page, i, in_use_bits, j;
640 #ifdef DEBUG2
641 	int tmp1, tmp2;
642 #endif
643 	splitnum = hashp->OVFL_POINT;
644 	max_free = hashp->SPARES[splitnum];
645 
646 	free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
647 	free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
648 
649 	/* Look through all the free maps to find the first free block */
650 	first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
651 	for ( i = first_page; i <= free_page; i++ ) {
652 		if (!(freep = (u_long *)hashp->mapp[i]) &&
653 		    !(freep = fetch_bitmap(hashp, i)))
654 			return (NULL);
655 		if (i == free_page)
656 			in_use_bits = free_bit;
657 		else
658 			in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
659 
660 		if (i == first_page) {
661 			bit = hashp->LAST_FREED &
662 			    ((hashp->BSIZE << BYTE_SHIFT) - 1);
663 			j = bit / BITS_PER_MAP;
664 			bit = bit & ~(BITS_PER_MAP - 1);
665 		} else {
666 			bit = 0;
667 			j = 0;
668 		}
669 		for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
670 			if (freep[j] != ALL_SET)
671 				goto found;
672 	}
673 
674 	/* No Free Page Found */
675 	hashp->LAST_FREED = hashp->SPARES[splitnum];
676 	hashp->SPARES[splitnum]++;
677 	offset = hashp->SPARES[splitnum] -
678 	    (splitnum ? hashp->SPARES[splitnum - 1] : 0);
679 
680 #define	OVMSG	"HASH: Out of overflow pages.  Increase page size\n"
681 	if (offset > SPLITMASK) {
682 		if (++splitnum >= NCACHED) {
683 			(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
684 			return (NULL);
685 		}
686 		hashp->OVFL_POINT = splitnum;
687 		hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
688 		hashp->SPARES[splitnum-1]--;
689 		offset = 0;
690 	}
691 
692 	/* Check if we need to allocate a new bitmap page */
693 	if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
694 		free_page++;
695 		if (free_page >= NCACHED) {
696 			(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
697 			return (NULL);
698 		}
699 		/*
700 		 * This is tricky.  The 1 indicates that you want the new page
701 		 * allocated with 1 clear bit.  Actually, you are going to
702 		 * allocate 2 pages from this map.  The first is going to be
703 		 * the map page, the second is the overflow page we were
704 		 * looking for.  The init_bitmap routine automatically, sets
705 		 * the first bit of itself to indicate that the bitmap itself
706 		 * is in use.  We would explicitly set the second bit, but
707 		 * don't have to if we tell init_bitmap not to leave it clear
708 		 * in the first place.
709 		 */
710 		if (__init_bitmap(hashp, (int)OADDR_OF(splitnum, offset),
711 		    1, free_page))
712 			return (NULL);
713 		hashp->SPARES[splitnum]++;
714 #ifdef DEBUG2
715 		free_bit = 2;
716 #endif
717 		offset++;
718 		if (offset > SPLITMASK) {
719 			if (++splitnum >= NCACHED) {
720 				(void)write(STDERR_FILENO, OVMSG,
721 				    sizeof(OVMSG) - 1);
722 				return (NULL);
723 			}
724 			hashp->OVFL_POINT = splitnum;
725 			hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
726 			hashp->SPARES[splitnum-1]--;
727 			offset = 0;
728 		}
729 	} else {
730 		/*
731 		 * Free_bit addresses the last used bit.  Bump it to address
732 		 * the first available bit.
733 		 */
734 		free_bit++;
735 		SETBIT(freep, free_bit);
736 	}
737 
738 	/* Calculate address of the new overflow page */
739 	addr = OADDR_OF(splitnum, offset);
740 #ifdef DEBUG2
741 	(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
742 	    addr, free_bit, free_page);
743 #endif
744 	return (addr);
745 
746 found:
747 	bit = bit + first_free(freep[j]);
748 	SETBIT(freep, bit);
749 #ifdef DEBUG2
750 	tmp1 = bit;
751 	tmp2 = i;
752 #endif
753 	/*
754 	 * Bits are addressed starting with 0, but overflow pages are addressed
755 	 * beginning at 1. Bit is a bit addressnumber, so we need to increment
756 	 * it to convert it to a page number.
757 	 */
758 	bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
759 	if (bit >= hashp->LAST_FREED)
760 		hashp->LAST_FREED = bit - 1;
761 
762 	/* Calculate the split number for this page */
763 	for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
764 	offset = (i ? bit - hashp->SPARES[i - 1] : bit);
765 	if (offset >= SPLITMASK)
766 		return (NULL);	/* Out of overflow pages */
767 	addr = OADDR_OF(i, offset);
768 #ifdef DEBUG2
769 	(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
770 	    addr, tmp1, tmp2);
771 #endif
772 
773 	/* Allocate and return the overflow page */
774 	return (addr);
775 }
776 
777 /*
778  * Mark this overflow page as free.
779  */
780 extern void
781 __free_ovflpage(hashp, obufp)
782 	HTAB *hashp;
783 	BUFHEAD *obufp;
784 {
785 	register u_short addr;
786 	u_long *freep;
787 	int bit_address, free_page, free_bit;
788 	u_short ndx;
789 
790 	addr = obufp->addr;
791 #ifdef DEBUG1
792 	(void)fprintf(stderr, "Freeing %d\n", addr);
793 #endif
794 	ndx = (((u_short)addr) >> SPLITSHIFT);
795 	bit_address =
796 	    (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
797 	 if (bit_address < hashp->LAST_FREED)
798 		hashp->LAST_FREED = bit_address;
799 	free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
800 	free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
801 
802 	if (!(freep = hashp->mapp[free_page]))
803 		freep = fetch_bitmap(hashp, free_page);
804 #ifdef DEBUG
805 	/*
806 	 * This had better never happen.  It means we tried to read a bitmap
807 	 * that has already had overflow pages allocated off it, and we
808 	 * failed to read it from the file.
809 	 */
810 	if (!freep)
811 		assert(0);
812 #endif
813 	CLRBIT(freep, free_bit);
814 #ifdef DEBUG2
815 	(void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
816 	    obufp->addr, free_bit, free_page);
817 #endif
818 	__reclaim_buf(hashp, obufp);
819 }
820 
821 /*
822  * Returns:
823  *	 0 success
824  *	-1 failure
825  */
826 static int
827 open_temp(hashp)
828 	HTAB *hashp;
829 {
830 	sigset_t set, oset;
831 	static char namestr[] = "_hashXXXXXX";
832 
833 	/* Block signals; make sure file goes away at process exit. */
834 	(void)sigfillset(&set);
835 	(void)sigprocmask(SIG_BLOCK, &set, &oset);
836 	if ((hashp->fp = mkstemp(namestr)) != -1) {
837 		(void)unlink(namestr);
838 		(void)fcntl(hashp->fp, F_SETFD, 1);
839 	}
840 	(void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
841 	return (hashp->fp != -1 ? 0 : -1);
842 }
843 
844 /*
845  * We have to know that the key will fit, but the last entry on the page is
846  * an overflow pair, so we need to shift things.
847  */
848 static void
849 squeeze_key(sp, key, val)
850 	u_short *sp;
851 	const DBT *key, *val;
852 {
853 	register char *p;
854 	u_short free_space, n, off, pageno;
855 
856 	p = (char *)sp;
857 	n = sp[0];
858 	free_space = FREESPACE(sp);
859 	off = OFFSET(sp);
860 
861 	pageno = sp[n - 1];
862 	off -= key->size;
863 	sp[n - 1] = off;
864 	memmove(p + off, key->data, key->size);
865 	off -= val->size;
866 	sp[n] = off;
867 	memmove(p + off, val->data, val->size);
868 	sp[0] = n + 2;
869 	sp[n + 1] = pageno;
870 	sp[n + 2] = OVFLPAGE;
871 	FREESPACE(sp) = free_space - PAIRSIZE(key, val);
872 	OFFSET(sp) = off;
873 }
874 
875 static u_long *
876 fetch_bitmap(hashp, ndx)
877 	HTAB *hashp;
878 	int ndx;
879 {
880 	if (ndx >= hashp->nmaps ||
881 	    !(hashp->mapp[ndx] = malloc(hashp->BSIZE)) ||
882 	    __get_page(hashp, (char *)hashp->mapp[ndx],
883 	    hashp->BITMAPS[ndx], 0, 1, 1))
884 		return (NULL);
885 	return (hashp->mapp[ndx]);
886 }
887 
888 #ifdef DEBUG4
889 int
890 print_chain(addr)
891 	int addr;
892 {
893 	BUFHEAD *bufp;
894 	short *bp, oaddr;
895 
896 	(void)fprintf(stderr, "%d ", addr);
897 	bufp = __get_buf(hashp, addr, NULL, 0);
898 	bp = (short *)bufp->page;
899 	while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
900 		((bp[0] > 2) && bp[2] < REAL_KEY))) {
901 		oaddr = bp[bp[0] - 1];
902 		(void)fprintf(stderr, "%d ", (int)oaddr);
903 		bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
904 		bp = (short *)bufp->page;
905 	}
906 	(void)fprintf(stderr, "\n");
907 }
908 #endif
909