xref: /csrg-svn/lib/libc/db/hash/hash.h (revision 46458)
146367Sbostic /*-
246367Sbostic  * Copyright (c) 1990 The Regents of the University of California.
346367Sbostic  * All rights reserved.
446367Sbostic  *
546367Sbostic  * This code is derived from software contributed to Berkeley by
646367Sbostic  * Margo Seltzer.
746367Sbostic  *
846367Sbostic  * %sccs.include.redist.c%
946367Sbostic  *
10*46458Sbostic  *	@(#)hash.h	5.2 (Berkeley) 02/19/91
1146367Sbostic  */
1246367Sbostic 
1346367Sbostic /* Operations */
1446367Sbostic typedef enum { HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE,
1546367Sbostic 		HASH_FIRST, HASH_NEXT } ACTION;
1646367Sbostic 
1746367Sbostic /* Buffer Management structures */
1846367Sbostic typedef struct _bufhead BUFHEAD;
1946367Sbostic 
2046367Sbostic struct _bufhead {
2146367Sbostic     BUFHEAD	*prev;		/* LRU links */
2246367Sbostic     BUFHEAD	*next;		/* LRU links */
2346367Sbostic     BUFHEAD	*ovfl;		/* Overflow page buffer header */
2446367Sbostic     int		addr;		/* Address of this page */
2546367Sbostic     char	*page;		/* Actual page data */
26*46458Sbostic     char	flags;
2746367Sbostic #define	BUF_MOD		0x0001
2846367Sbostic #define BUF_DISK	0x0002
2946367Sbostic #define	BUF_BUCKET	0x0004
30*46458Sbostic #define	BUF_PIN		0x0008
31*46458Sbostic };
3246367Sbostic 
33*46458Sbostic 
3446367Sbostic #define IS_BUCKET(X)	(X & BUF_BUCKET)
3546367Sbostic 
3646367Sbostic typedef BUFHEAD	**SEGMENT;
3746367Sbostic 
3846367Sbostic /* Hash Table Information */
3946367Sbostic typedef struct hashhdr {	/* Disk resident portion */
4046367Sbostic 	int magic;	/* Magic NO for hash tables */
4146367Sbostic 	int version;	/* Version ID */
4246367Sbostic 	long lorder;	/* Byte Order */
4346367Sbostic 	int bsize;	/* Bucket/Page Size */
4446367Sbostic 	int bshift;	/* Bucket shift */
4546367Sbostic 	int dsize;	/* Directory Size */
4646367Sbostic 	int ssize;	/* Segment Size */
4746367Sbostic 	int sshift;	/* Segment shift */
4846367Sbostic 	int max_bucket;	/* ID of Maximum bucket in use */
4946367Sbostic 	int high_mask;	/* Mask to modulo into entire table */
5046367Sbostic 	int low_mask;	/* Mask to modulo into lower half of table */
5146367Sbostic 	int ffactor;	/* Fill factor */
5246367Sbostic 	int nkeys;	/* Number of keys in hash table */
5346367Sbostic 	int hdrpages;	/* Size of table header */
5446367Sbostic 	int h_charkey;	/* value of hash(CHARKEY) */
5546367Sbostic # define NCACHED		32	/* number of bit maps and spare points*/
5646367Sbostic 	int spares[NCACHED];	/* spare pages for overflow */
5746367Sbostic 	u_short bitmaps[NCACHED];	/* address of overflow page bitmaps */
5846367Sbostic } HASHHDR;
5946367Sbostic 
6046367Sbostic typedef struct htab {	/* Memory resident data structure */
6146367Sbostic 	HASHHDR hdr;	/* Header */
6246367Sbostic 	int nsegs;	/* Number of allocated segments */
6346367Sbostic 	int exsegs;	/* Number of extra allocated segments */
6446367Sbostic 	int (*hash)();	/* Hash Function */
6546367Sbostic 	int flags;	/* Flag values */
6646367Sbostic 	int fp;		/* File pointer */
6746367Sbostic 	char *tmp_buf;	/* Temporary Buffer for BIG data */
6846367Sbostic 	char *tmp_key;	/* Temporary Buffer for BIG keys */
6946367Sbostic 	BUFHEAD *cpage;	/* Current page */
7046367Sbostic 	int cbucket;	/* Current bucket */
7146367Sbostic 	int cndx;  	/* Index of next item on cpage */
7246367Sbostic 	int errno;	/* Error Number -- for DBM compatability */
7346367Sbostic 	int new_file;	/* Indicates whether fd is backing store or no */
7446367Sbostic 	int save_file;	/* Indicates whether we need to flush file at exit */
7546367Sbostic 	u_long *mapp[NCACHED];	/* Pointers to page maps */
7646367Sbostic 	int nbufs;	/* Number of buffers left to allocate */
7746367Sbostic 	BUFHEAD	bufhead; /* Header of buffer lru list */
7846367Sbostic 	SEGMENT	 *dir;	/* Hash Bucket directory */
7946367Sbostic } HTAB;
8046367Sbostic 
8146367Sbostic 
8246367Sbostic /*
8346367Sbostic  * Constants
8446367Sbostic  */
8546367Sbostic #define	MAX_BSIZE		65536	/* 2^16 */
8646367Sbostic #define MIN_BUFFERS		6
8746367Sbostic #define MINHDRSIZE		512
8846367Sbostic #define DEF_BUFSIZE		65536	/* 64 K */
8946367Sbostic #define DEF_BUCKET_SIZE	256
9046367Sbostic #define DEF_BUCKET_SHIFT	8	/* log2(BUCKET) */
9146367Sbostic #define DEF_SEGSIZE		256
9246367Sbostic #define DEF_SEGSIZE_SHIFT		8      /* log2(SEGSIZE)	 */
9346367Sbostic #define DEF_DIRSIZE		256
9446367Sbostic #define DEF_FFACTOR		5
9546367Sbostic #define SPLTMAX		8
9646367Sbostic #define CHARKEY		"%$sniglet^&"
9746367Sbostic #define NUMKEY			1038583
9846367Sbostic #define VERSION_NO		3
9946367Sbostic #define BYTE_SHIFT		3
10046367Sbostic #define INT_TO_BYTE		2
10146367Sbostic #define INT_BYTE_SHIFT		5
10246367Sbostic #define ALL_SET		((unsigned)0xFFFFFFFF)
10346367Sbostic #define ALL_CLEAR		0
10446367Sbostic 
10546367Sbostic 
10646367Sbostic #define PTROF(X)	((BUFHEAD *)((unsigned)(X)&~0x3))
10746367Sbostic #define ISMOD(X)	((unsigned)(X)&0x1)
10846367Sbostic #define DOMOD(X)	(X = (char *)( (unsigned)X | 0x1))
10946367Sbostic #define ISDISK(X)	((unsigned)(X)&0x2)
11046367Sbostic #define DODISK(X)	(X = (char *)( (unsigned)X | 0x2))
11146367Sbostic 
11246367Sbostic #define BITS_PER_MAP    32
11346367Sbostic 
11446367Sbostic /* Given the address of the beginning of a big map, clear/set the nth bit */
11546367Sbostic 
11646367Sbostic #define CLRBIT(A,N) ((A)[N/BITS_PER_MAP] &= ~(1<<(N%BITS_PER_MAP)))
11746367Sbostic #define SETBIT(A,N) ((A)[N/BITS_PER_MAP] |= (1<<(N%BITS_PER_MAP)))
11846367Sbostic #define ISSET(A,N) ((A)[N/BITS_PER_MAP] & (1<<(N%BITS_PER_MAP)))
11946367Sbostic 
12046367Sbostic /* Overflow management */
12146367Sbostic /*
12246367Sbostic 	Overflow page numbers are allocated per split point.
12346367Sbostic 	At each doubling of the table, we can allocate extra
12446367Sbostic 	pages.  So, an overflow page number has the top 5 bits
12546367Sbostic 	indicate which split point and the lower 11 bits indicate
12646367Sbostic 	which page at that split point is indicated (pages within
12746367Sbostic 	split points are numberered starting with 1).
12846367Sbostic 
12946367Sbostic 
13046367Sbostic */
13146367Sbostic 
13246367Sbostic #define SPLITSHIFT	11
13346367Sbostic #define SPLITMASK	0x7FF
13446367Sbostic #define SPLITNUM(N)	(((unsigned)N) >> SPLITSHIFT)
13546367Sbostic #define OPAGENUM(N)	(N & SPLITMASK)
13646367Sbostic #define	OADDR_OF(S,O)	((S << SPLITSHIFT) + O)
13746367Sbostic 
13846367Sbostic #define BUCKET_TO_PAGE(B) \
13946367Sbostic 	B + hashp->HDRPAGES + (B ? hashp->SPARES[__log2(B+1)-1] : 0)
14046367Sbostic #define OADDR_TO_PAGE(B) 	\
14146367Sbostic 	BUCKET_TO_PAGE ( (1 << SPLITNUM(B)) -1 ) + OPAGENUM(B);
14246367Sbostic 
14346367Sbostic /*
14446367Sbostic     page.h contains a detailed description of the page format.
14546367Sbostic 
14646367Sbostic     Normally, keys and data are accessed from offset tables in the
14746367Sbostic     top of each page which point to the beginning of the key and
14846367Sbostic     data.  There are four flag values which may be stored in these
14946367Sbostic     offset tables which indicate the following:
15046367Sbostic 
15146367Sbostic 	OVFLPAGE	Rather than a key data pair, this pair contains
15246367Sbostic 			the address of an overflow page.  The format of
15346367Sbostic 			the pair is:
15446367Sbostic 			    OVERFLOW_PAGE_NUMBER OVFLPAGE
15546367Sbostic 
15646367Sbostic 	PARTIAL_KEY	This must be the first key/data pair on a page
15746367Sbostic 			and implies that page contains only a partial key.
15846367Sbostic 			That is, the key is too big to fit on a single page
15946367Sbostic 			so it starts on this page and continues on the next.
16046367Sbostic 			The format of the page is:
16146367Sbostic 			    KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
16246367Sbostic 
16346367Sbostic 			    KEY_OFF -- offset of the beginning of the key
16446367Sbostic 			    PARTIAL_KEY -- 1
16546367Sbostic 			    OVFL_PAGENO - page number of the next overflow page
16646367Sbostic 			    OVFLPAGE -- 0
16746367Sbostic 	FULL_KEY	This must be the first key/data pair on the page.  It
16846367Sbostic 			is used in two cases.
16946367Sbostic 
17046367Sbostic 			Case 1:
17146367Sbostic 			    There is a complete key on the page but no data
17246367Sbostic 			    (because it wouldn't fit).  The next page contains
17346367Sbostic 			    the data.
17446367Sbostic 
17546367Sbostic 			    Page format it:
17646367Sbostic 			    KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
17746367Sbostic 
17846367Sbostic 			    KEY_OFF -- offset of the beginning of the key
17946367Sbostic 			    FULL_KEY -- 2
18046367Sbostic 			    OVFL_PAGENO - page number of the next overflow page
18146367Sbostic 			    OVFLPAGE -- 0
18246367Sbostic 
18346367Sbostic 			Case 2:
18446367Sbostic 			    This page contains no key, but part of a large
18546367Sbostic 			    data field, which is continued on the next page.
18646367Sbostic 
18746367Sbostic 			    Page format it:
18846367Sbostic 			    DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
18946367Sbostic 
19046367Sbostic 			    KEY_OFF -- offset of the beginning of the data on
19146367Sbostic 					this page
19246367Sbostic 			    FULL_KEY -- 2
19346367Sbostic 			    OVFL_PAGENO - page number of the next overflow page
19446367Sbostic 			    OVFLPAGE -- 0
19546367Sbostic 
19646367Sbostic 	FULL_KEY_DATA	This must be the first key/data pair on the page.
19746367Sbostic 			There are two cases:
19846367Sbostic 
19946367Sbostic 			Case 1:
20046367Sbostic 			    This page contains a key and the beginning of the
20146367Sbostic 			    data field, but the data field is continued on the
20246367Sbostic 			    next page.
20346367Sbostic 
20446367Sbostic 			    Page format is:
20546367Sbostic 			    KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
20646367Sbostic 
20746367Sbostic 			    KEY_OFF -- offset of the beginning of the key
20846367Sbostic 			    FULL_KEY_DATA -- 3
20946367Sbostic 			    OVFL_PAGENO - page number of the next overflow page
21046367Sbostic 			    DATA_OFF -- offset of the beginning of the data
21146367Sbostic 
21246367Sbostic 			Case 2:
21346367Sbostic 			    This page contains the last page of a big data pair.
21446367Sbostic 			    There is no key, only the  tail end of the data
21546367Sbostic 			    on this page.
21646367Sbostic 
21746367Sbostic 			    Page format is:
21846367Sbostic 			    DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
21946367Sbostic 
22046367Sbostic 			    DATA_OFF -- offset of the beginning of the data on
22146367Sbostic 					this page
22246367Sbostic 			    FULL_KEY_DATA -- 3
22346367Sbostic 			    OVFL_PAGENO - page number of the next overflow page
22446367Sbostic 			    OVFLPAGE -- 0
22546367Sbostic 
22646367Sbostic 			    OVFL_PAGENO and OVFLPAGE are optional (they are
22746367Sbostic 			    not present if there is no next page).
22846367Sbostic */
229*46458Sbostic 
23046367Sbostic #define OVFLPAGE	0
23146367Sbostic #define PARTIAL_KEY	1
23246367Sbostic #define FULL_KEY	2
23346367Sbostic #define FULL_KEY_DATA	3
23446367Sbostic #define	REAL_KEY	4
23546367Sbostic /* Short hands for accessing structure */
23646367Sbostic #define BSIZE	hdr.bsize
23746367Sbostic #define BSHIFT	hdr.bshift
23846367Sbostic #define DSIZE	hdr.dsize
23946367Sbostic #define SGSIZE	hdr.ssize
24046367Sbostic #define SSHIFT	hdr.sshift
24146367Sbostic #define LORDER	hdr.lorder
24246367Sbostic #define MAX_BUCKET	hdr.max_bucket
24346367Sbostic #define FFACTOR		hdr.ffactor
24446367Sbostic #define HIGH_MASK	hdr.high_mask
24546367Sbostic #define LOW_MASK	hdr.low_mask
24646367Sbostic #define NKEYS		hdr.nkeys
24746367Sbostic #define HDRPAGES	hdr.hdrpages
24846367Sbostic #define SPARES		hdr.spares
24946367Sbostic #define BITMAPS		hdr.bitmaps
25046367Sbostic #define VERSION		hdr.version
25146367Sbostic #define MAGIC		hdr.magic
25246367Sbostic #define NEXT_FREE	hdr.next_free
25346367Sbostic #define H_CHARKEY	hdr.h_charkey
254