xref: /original-bsd/lib/libc/db/hash/hash_page.c (revision 4092c5cc)
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.27 (Berkeley) 05/25/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 
451 	/* Check if we are dynamically determining the fill factor */
452 	if (hashp->FFACTOR == DEF_FFACTOR) {
453 		hashp->FFACTOR = sp[0] >> 1;
454 		if (hashp->FFACTOR < MIN_FFACTOR)
455 			hashp->FFACTOR = MIN_FFACTOR;
456 	}
457 	bufp->flags |= BUF_MOD;
458 	ovfl_num = overflow_page(hashp);
459 #ifdef DEBUG1
460 	tmp1 = bufp->addr;
461 	tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
462 #endif
463 	if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
464 		return (NULL);
465 	bufp->ovfl->flags |= BUF_MOD;
466 #ifdef DEBUG1
467 	(void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
468 	    tmp1, tmp2, bufp->ovfl->addr);
469 #endif
470 	ndx = sp[0];
471 	/*
472 	 * Since a pair is allocated on a page only if there's room to add
473 	 * an overflow page, we know that the OVFL information will fit on
474 	 * the page.
475 	 */
476 	sp[ndx + 4] = OFFSET(sp);
477 	sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
478 	sp[ndx + 1] = ovfl_num;
479 	sp[ndx + 2] = OVFLPAGE;
480 	sp[0] = ndx + 2;
481 #ifdef HASH_STATISTICS
482 	hash_overflows++;
483 #endif
484 	return (bufp->ovfl);
485 }
486 
487 /*
488  * Returns:
489  *	 0 indicates SUCCESS
490  *	-1 indicates FAILURE
491  */
492 extern int
493 __get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
494 	HTAB *hashp;
495 	char *p;
496 	u_int bucket;
497 	int is_bucket, is_disk, is_bitmap;
498 {
499 	register int fd, page, size;
500 	int rsize;
501 	u_short *bp;
502 
503 	fd = hashp->fp;
504 	size = hashp->BSIZE;
505 
506 	if ((fd == -1) || !is_disk) {
507 		PAGE_INIT(p);
508 		return (0);
509 	}
510 	if (is_bucket)
511 		page = BUCKET_TO_PAGE(bucket);
512 	else
513 		page = OADDR_TO_PAGE(bucket);
514 	if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
515 	    ((rsize = read(fd, p, size)) == -1))
516 		return (-1);
517 	bp = (u_short *)p;
518 	if (!rsize)
519 		bp[0] = 0;	/* We hit the EOF, so initialize a new page */
520 	else
521 		if (rsize != size) {
522 			errno = EFTYPE;
523 			return (-1);
524 		}
525 	if (!is_bitmap && !bp[0]) {
526 		PAGE_INIT(p);
527 	} else
528 		if (hashp->LORDER != BYTE_ORDER) {
529 			register int i, max;
530 
531 			if (is_bitmap) {
532 				max = hashp->BSIZE >> 2; /* divide by 4 */
533 				for (i = 0; i < max; i++)
534 					BLSWAP(((long *)p)[i]);
535 			} else {
536 				BSSWAP(bp[0]);
537 				max = bp[0] + 2;
538 				for (i = 1; i <= max; i++)
539 					BSSWAP(bp[i]);
540 			}
541 		}
542 	return (0);
543 }
544 
545 /*
546  * Write page p to disk
547  *
548  * Returns:
549  *	 0 ==> OK
550  *	-1 ==>failure
551  */
552 extern int
553 __put_page(hashp, p, bucket, is_bucket, is_bitmap)
554 	HTAB *hashp;
555 	char *p;
556 	u_int bucket;
557 	int is_bucket, is_bitmap;
558 {
559 	register int fd, page, size;
560 	int wsize;
561 
562 	size = hashp->BSIZE;
563 	if ((hashp->fp == -1) && open_temp(hashp))
564 		return (-1);
565 	fd = hashp->fp;
566 
567 	if (hashp->LORDER != BYTE_ORDER) {
568 		register int i;
569 		register int max;
570 
571 		if (is_bitmap) {
572 			max = hashp->BSIZE >> 2;	/* divide by 4 */
573 			for (i = 0; i < max; i++)
574 				BLSWAP(((long *)p)[i]);
575 		} else {
576 			max = ((u_short *)p)[0] + 2;
577 			for (i = 0; i <= max; i++)
578 				BSSWAP(((u_short *)p)[i]);
579 		}
580 	}
581 	if (is_bucket)
582 		page = BUCKET_TO_PAGE(bucket);
583 	else
584 		page = OADDR_TO_PAGE(bucket);
585 	if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
586 	    ((wsize = write(fd, p, size)) == -1))
587 		/* Errno is set */
588 		return (-1);
589 	if (wsize != size) {
590 		errno = EFTYPE;
591 		return (-1);
592 	}
593 	return (0);
594 }
595 
596 #define BYTE_MASK	((1 << INT_BYTE_SHIFT) -1)
597 /*
598  * Initialize a new bitmap page.  Bitmap pages are left in memory
599  * once they are read in.
600  */
601 extern int
602 __init_bitmap(hashp, pnum, nbits, ndx)
603 	HTAB *hashp;
604 	int pnum, nbits, ndx;
605 {
606 	u_long *ip;
607 	int clearbytes, clearints;
608 
609 	if (!(ip = malloc(hashp->BSIZE)))
610 		return (1);
611 	hashp->nmaps++;
612 	clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
613 	clearbytes = clearints << INT_TO_BYTE;
614 	(void)memset((char *)ip, 0, clearbytes);
615 	(void)memset(((char *)ip) + clearbytes, 0xFF,
616 	    hashp->BSIZE - clearbytes);
617 	ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
618 	SETBIT(ip, 0);
619 	hashp->BITMAPS[ndx] = (u_short)pnum;
620 	hashp->mapp[ndx] = ip;
621 	return (0);
622 }
623 
624 static u_long
625 first_free(map)
626 	u_long map;
627 {
628 	register u_long i, mask;
629 
630 	mask = 0x1;
631 	for (i = 0; i < BITS_PER_MAP; i++) {
632 		if (!(mask & map))
633 			return (i);
634 		mask = mask << 1;
635 	}
636 	return (i);
637 }
638 
639 static u_short
640 overflow_page(hashp)
641 	HTAB *hashp;
642 {
643 	register u_long *freep;
644 	register int max_free, offset, splitnum;
645 	u_short addr;
646 	int bit, first_page, free_bit, free_page, i, in_use_bits, j;
647 #ifdef DEBUG2
648 	int tmp1, tmp2;
649 #endif
650 	splitnum = hashp->OVFL_POINT;
651 	max_free = hashp->SPARES[splitnum];
652 
653 	free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
654 	free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
655 
656 	/* Look through all the free maps to find the first free block */
657 	first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
658 	for ( i = first_page; i <= free_page; i++ ) {
659 		if (!(freep = (u_long *)hashp->mapp[i]) &&
660 		    !(freep = fetch_bitmap(hashp, i)))
661 			return (NULL);
662 		if (i == free_page)
663 			in_use_bits = free_bit;
664 		else
665 			in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
666 
667 		if (i == first_page) {
668 			bit = hashp->LAST_FREED &
669 			    ((hashp->BSIZE << BYTE_SHIFT) - 1);
670 			j = bit / BITS_PER_MAP;
671 			bit = bit & ~(BITS_PER_MAP - 1);
672 		} else {
673 			bit = 0;
674 			j = 0;
675 		}
676 		for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
677 			if (freep[j] != ALL_SET)
678 				goto found;
679 	}
680 
681 	/* No Free Page Found */
682 	hashp->LAST_FREED = hashp->SPARES[splitnum];
683 	hashp->SPARES[splitnum]++;
684 	offset = hashp->SPARES[splitnum] -
685 	    (splitnum ? hashp->SPARES[splitnum - 1] : 0);
686 
687 #define	OVMSG	"HASH: Out of overflow pages.  Increase page size\n"
688 	if (offset > SPLITMASK) {
689 		if (++splitnum >= NCACHED) {
690 			(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
691 			return (NULL);
692 		}
693 		hashp->OVFL_POINT = splitnum;
694 		hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
695 		hashp->SPARES[splitnum-1]--;
696 		offset = 0;
697 	}
698 
699 	/* Check if we need to allocate a new bitmap page */
700 	if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
701 		free_page++;
702 		if (free_page >= NCACHED) {
703 			(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
704 			return (NULL);
705 		}
706 		/*
707 		 * This is tricky.  The 1 indicates that you want the new page
708 		 * allocated with 1 clear bit.  Actually, you are going to
709 		 * allocate 2 pages from this map.  The first is going to be
710 		 * the map page, the second is the overflow page we were
711 		 * looking for.  The init_bitmap routine automatically, sets
712 		 * the first bit of itself to indicate that the bitmap itself
713 		 * is in use.  We would explicitly set the second bit, but
714 		 * don't have to if we tell init_bitmap not to leave it clear
715 		 * in the first place.
716 		 */
717 		if (__init_bitmap(hashp, (int)OADDR_OF(splitnum, offset),
718 		    1, free_page))
719 			return (NULL);
720 		hashp->SPARES[splitnum]++;
721 #ifdef DEBUG2
722 		free_bit = 2;
723 #endif
724 		offset++;
725 		if (offset > SPLITMASK) {
726 			if (++splitnum >= NCACHED) {
727 				(void)write(STDERR_FILENO, OVMSG,
728 				    sizeof(OVMSG) - 1);
729 				return (NULL);
730 			}
731 			hashp->OVFL_POINT = splitnum;
732 			hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
733 			hashp->SPARES[splitnum-1]--;
734 			offset = 0;
735 		}
736 	} else {
737 		/*
738 		 * Free_bit addresses the last used bit.  Bump it to address
739 		 * the first available bit.
740 		 */
741 		free_bit++;
742 		SETBIT(freep, free_bit);
743 	}
744 
745 	/* Calculate address of the new overflow page */
746 	addr = OADDR_OF(splitnum, offset);
747 #ifdef DEBUG2
748 	(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
749 	    addr, free_bit, free_page);
750 #endif
751 	return (addr);
752 
753 found:
754 	bit = bit + first_free(freep[j]);
755 	SETBIT(freep, bit);
756 #ifdef DEBUG2
757 	tmp1 = bit;
758 	tmp2 = i;
759 #endif
760 	/*
761 	 * Bits are addressed starting with 0, but overflow pages are addressed
762 	 * beginning at 1. Bit is a bit addressnumber, so we need to increment
763 	 * it to convert it to a page number.
764 	 */
765 	bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
766 	if (bit >= hashp->LAST_FREED)
767 		hashp->LAST_FREED = bit - 1;
768 
769 	/* Calculate the split number for this page */
770 	for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
771 	offset = (i ? bit - hashp->SPARES[i - 1] : bit);
772 	if (offset >= SPLITMASK)
773 		return (NULL);	/* Out of overflow pages */
774 	addr = OADDR_OF(i, offset);
775 #ifdef DEBUG2
776 	(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
777 	    addr, tmp1, tmp2);
778 #endif
779 
780 	/* Allocate and return the overflow page */
781 	return (addr);
782 }
783 
784 /*
785  * Mark this overflow page as free.
786  */
787 extern void
788 __free_ovflpage(hashp, obufp)
789 	HTAB *hashp;
790 	BUFHEAD *obufp;
791 {
792 	register u_short addr;
793 	u_long *freep;
794 	int bit_address, free_page, free_bit;
795 	u_short ndx;
796 
797 	addr = obufp->addr;
798 #ifdef DEBUG1
799 	(void)fprintf(stderr, "Freeing %d\n", addr);
800 #endif
801 	ndx = (((u_short)addr) >> SPLITSHIFT);
802 	bit_address =
803 	    (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
804 	 if (bit_address < hashp->LAST_FREED)
805 		hashp->LAST_FREED = bit_address;
806 	free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
807 	free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
808 
809 	if (!(freep = hashp->mapp[free_page]))
810 		freep = fetch_bitmap(hashp, free_page);
811 #ifdef DEBUG
812 	/*
813 	 * This had better never happen.  It means we tried to read a bitmap
814 	 * that has already had overflow pages allocated off it, and we
815 	 * failed to read it from the file.
816 	 */
817 	if (!freep)
818 		assert(0);
819 #endif
820 	CLRBIT(freep, free_bit);
821 #ifdef DEBUG2
822 	(void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
823 	    obufp->addr, free_bit, free_page);
824 #endif
825 	__reclaim_buf(hashp, obufp);
826 }
827 
828 /*
829  * Returns:
830  *	 0 success
831  *	-1 failure
832  */
833 static int
834 open_temp(hashp)
835 	HTAB *hashp;
836 {
837 	sigset_t set, oset;
838 	static char namestr[] = "_hashXXXXXX";
839 
840 	/* Block signals; make sure file goes away at process exit. */
841 	(void)sigfillset(&set);
842 	(void)sigprocmask(SIG_BLOCK, &set, &oset);
843 	if ((hashp->fp = mkstemp(namestr)) != -1) {
844 		(void)unlink(namestr);
845 		(void)fcntl(hashp->fp, F_SETFD, 1);
846 	}
847 	(void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
848 	return (hashp->fp != -1 ? 0 : -1);
849 }
850 
851 /*
852  * We have to know that the key will fit, but the last entry on the page is
853  * an overflow pair, so we need to shift things.
854  */
855 static void
856 squeeze_key(sp, key, val)
857 	u_short *sp;
858 	const DBT *key, *val;
859 {
860 	register char *p;
861 	u_short free_space, n, off, pageno;
862 
863 	p = (char *)sp;
864 	n = sp[0];
865 	free_space = FREESPACE(sp);
866 	off = OFFSET(sp);
867 
868 	pageno = sp[n - 1];
869 	off -= key->size;
870 	sp[n - 1] = off;
871 	memmove(p + off, key->data, key->size);
872 	off -= val->size;
873 	sp[n] = off;
874 	memmove(p + off, val->data, val->size);
875 	sp[0] = n + 2;
876 	sp[n + 1] = pageno;
877 	sp[n + 2] = OVFLPAGE;
878 	FREESPACE(sp) = free_space - PAIRSIZE(key, val);
879 	OFFSET(sp) = off;
880 }
881 
882 static u_long *
883 fetch_bitmap(hashp, ndx)
884 	HTAB *hashp;
885 	int ndx;
886 {
887 	if (ndx >= hashp->nmaps ||
888 	    !(hashp->mapp[ndx] = malloc(hashp->BSIZE)) ||
889 	    __get_page(hashp, (char *)hashp->mapp[ndx],
890 	    hashp->BITMAPS[ndx], 0, 1, 1))
891 		return (NULL);
892 	return (hashp->mapp[ndx]);
893 }
894 
895 #ifdef DEBUG4
896 int
897 print_chain(addr)
898 	int addr;
899 {
900 	BUFHEAD *bufp;
901 	short *bp, oaddr;
902 
903 	(void)fprintf(stderr, "%d ", addr);
904 	bufp = __get_buf(hashp, addr, NULL, 0);
905 	bp = (short *)bufp->page;
906 	while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
907 		((bp[0] > 2) && bp[2] < REAL_KEY))) {
908 		oaddr = bp[bp[0] - 1];
909 		(void)fprintf(stderr, "%d ", (int)oaddr);
910 		bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
911 		bp = (short *)bufp->page;
912 	}
913 	(void)fprintf(stderr, "\n");
914 }
915 #endif
916