Home | History | Annotate | Line # | Download | only in hash
hash.h revision 1.1
      1  1.1  cgd /*-
      2  1.1  cgd  * Copyright (c) 1990 The Regents of the University of California.
      3  1.1  cgd  * All rights reserved.
      4  1.1  cgd  *
      5  1.1  cgd  * This code is derived from software contributed to Berkeley by
      6  1.1  cgd  * Margo Seltzer.
      7  1.1  cgd  *
      8  1.1  cgd  * Redistribution and use in source and binary forms, with or without
      9  1.1  cgd  * modification, are permitted provided that the following conditions
     10  1.1  cgd  * are met:
     11  1.1  cgd  * 1. Redistributions of source code must retain the above copyright
     12  1.1  cgd  *    notice, this list of conditions and the following disclaimer.
     13  1.1  cgd  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  cgd  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  cgd  *    documentation and/or other materials provided with the distribution.
     16  1.1  cgd  * 3. All advertising materials mentioning features or use of this software
     17  1.1  cgd  *    must display the following acknowledgement:
     18  1.1  cgd  *	This product includes software developed by the University of
     19  1.1  cgd  *	California, Berkeley and its contributors.
     20  1.1  cgd  * 4. Neither the name of the University nor the names of its contributors
     21  1.1  cgd  *    may be used to endorse or promote products derived from this software
     22  1.1  cgd  *    without specific prior written permission.
     23  1.1  cgd  *
     24  1.1  cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  1.1  cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  1.1  cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  1.1  cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  1.1  cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  1.1  cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  1.1  cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  1.1  cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  1.1  cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  1.1  cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  1.1  cgd  * SUCH DAMAGE.
     35  1.1  cgd  *
     36  1.1  cgd  *	@(#)hash.h	5.4 (Berkeley) 3/12/91
     37  1.1  cgd  */
     38  1.1  cgd 
     39  1.1  cgd /* Operations */
     40  1.1  cgd typedef enum { HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE,
     41  1.1  cgd 		HASH_FIRST, HASH_NEXT } ACTION;
     42  1.1  cgd 
     43  1.1  cgd /* Buffer Management structures */
     44  1.1  cgd typedef struct _bufhead BUFHEAD;
     45  1.1  cgd 
     46  1.1  cgd struct _bufhead {
     47  1.1  cgd     BUFHEAD	*prev;		/* LRU links */
     48  1.1  cgd     BUFHEAD	*next;		/* LRU links */
     49  1.1  cgd     BUFHEAD	*ovfl;		/* Overflow page buffer header */
     50  1.1  cgd     u_int	 addr;		/* Address of this page */
     51  1.1  cgd     char	*page;		/* Actual page data */
     52  1.1  cgd     char	flags;
     53  1.1  cgd #define	BUF_MOD		0x0001
     54  1.1  cgd #define BUF_DISK	0x0002
     55  1.1  cgd #define	BUF_BUCKET	0x0004
     56  1.1  cgd #define	BUF_PIN		0x0008
     57  1.1  cgd };
     58  1.1  cgd 
     59  1.1  cgd 
     60  1.1  cgd #define IS_BUCKET(X)	(X & BUF_BUCKET)
     61  1.1  cgd 
     62  1.1  cgd typedef BUFHEAD	**SEGMENT;
     63  1.1  cgd 
     64  1.1  cgd /* Hash Table Information */
     65  1.1  cgd typedef struct hashhdr {	/* Disk resident portion */
     66  1.1  cgd 	int magic;	/* Magic NO for hash tables */
     67  1.1  cgd 	int version;	/* Version ID */
     68  1.1  cgd 	long lorder;	/* Byte Order */
     69  1.1  cgd 	int bsize;	/* Bucket/Page Size */
     70  1.1  cgd 	int bshift;	/* Bucket shift */
     71  1.1  cgd 	int dsize;	/* Directory Size */
     72  1.1  cgd 	int ssize;	/* Segment Size */
     73  1.1  cgd 	int sshift;	/* Segment shift */
     74  1.1  cgd 	int max_bucket;	/* ID of Maximum bucket in use */
     75  1.1  cgd 	int high_mask;	/* Mask to modulo into entire table */
     76  1.1  cgd 	int low_mask;	/* Mask to modulo into lower half of table */
     77  1.1  cgd 	int ffactor;	/* Fill factor */
     78  1.1  cgd 	int nkeys;	/* Number of keys in hash table */
     79  1.1  cgd 	int hdrpages;	/* Size of table header */
     80  1.1  cgd 	int h_charkey;	/* value of hash(CHARKEY) */
     81  1.1  cgd # define NCACHED		32	/* number of bit maps and spare points*/
     82  1.1  cgd 	int spares[NCACHED];	/* spare pages for overflow */
     83  1.1  cgd 	u_short bitmaps[NCACHED];	/* address of overflow page bitmaps */
     84  1.1  cgd } HASHHDR;
     85  1.1  cgd 
     86  1.1  cgd typedef struct htab {	/* Memory resident data structure */
     87  1.1  cgd 	HASHHDR hdr;	/* Header */
     88  1.1  cgd 	int nsegs;	/* Number of allocated segments */
     89  1.1  cgd 	int exsegs;	/* Number of extra allocated segments */
     90  1.1  cgd 	int (*hash)();	/* Hash Function */
     91  1.1  cgd 	int flags;	/* Flag values */
     92  1.1  cgd 	int fp;		/* File pointer */
     93  1.1  cgd 	char *tmp_buf;	/* Temporary Buffer for BIG data */
     94  1.1  cgd 	char *tmp_key;	/* Temporary Buffer for BIG keys */
     95  1.1  cgd 	BUFHEAD *cpage;	/* Current page */
     96  1.1  cgd 	int cbucket;	/* Current bucket */
     97  1.1  cgd 	int cndx;  	/* Index of next item on cpage */
     98  1.1  cgd 	int errno;	/* Error Number -- for DBM compatability */
     99  1.1  cgd 	int new_file;	/* Indicates whether fd is backing store or no */
    100  1.1  cgd 	int save_file;	/* Indicates whether we need to flush file at exit */
    101  1.1  cgd 	u_long *mapp[NCACHED];	/* Pointers to page maps */
    102  1.1  cgd 	int nmaps;	/* Initial number of bitmaps */
    103  1.1  cgd 	int nbufs;	/* Number of buffers left to allocate */
    104  1.1  cgd 	BUFHEAD	bufhead; /* Header of buffer lru list */
    105  1.1  cgd 	SEGMENT	 *dir;	/* Hash Bucket directory */
    106  1.1  cgd } HTAB;
    107  1.1  cgd 
    108  1.1  cgd 
    109  1.1  cgd /*
    110  1.1  cgd  * Constants
    111  1.1  cgd  */
    112  1.1  cgd #define	MAX_BSIZE		65536	/* 2^16 */
    113  1.1  cgd #define MIN_BUFFERS		6
    114  1.1  cgd #define MINHDRSIZE		512
    115  1.1  cgd #define DEF_BUFSIZE		65536	/* 64 K */
    116  1.1  cgd #define DEF_BUCKET_SIZE	256
    117  1.1  cgd #define DEF_BUCKET_SHIFT	8	/* log2(BUCKET) */
    118  1.1  cgd #define DEF_SEGSIZE		256
    119  1.1  cgd #define DEF_SEGSIZE_SHIFT		8      /* log2(SEGSIZE)	 */
    120  1.1  cgd #define DEF_DIRSIZE		256
    121  1.1  cgd #define DEF_FFACTOR		5
    122  1.1  cgd #define SPLTMAX		8
    123  1.1  cgd #define CHARKEY		"%$sniglet^&"
    124  1.1  cgd #define NUMKEY			1038583
    125  1.1  cgd #define VERSION_NO		3
    126  1.1  cgd #define BYTE_SHIFT		3
    127  1.1  cgd #define INT_TO_BYTE		2
    128  1.1  cgd #define INT_BYTE_SHIFT		5
    129  1.1  cgd #define ALL_SET		((unsigned)0xFFFFFFFF)
    130  1.1  cgd #define ALL_CLEAR		0
    131  1.1  cgd 
    132  1.1  cgd 
    133  1.1  cgd #define PTROF(X)	((BUFHEAD *)((unsigned)(X)&~0x3))
    134  1.1  cgd #define ISMOD(X)	((unsigned)(X)&0x1)
    135  1.1  cgd #define DOMOD(X)	(X = (char *)( (unsigned)X | 0x1))
    136  1.1  cgd #define ISDISK(X)	((unsigned)(X)&0x2)
    137  1.1  cgd #define DODISK(X)	(X = (char *)( (unsigned)X | 0x2))
    138  1.1  cgd 
    139  1.1  cgd #define BITS_PER_MAP    32
    140  1.1  cgd 
    141  1.1  cgd /* Given the address of the beginning of a big map, clear/set the nth bit */
    142  1.1  cgd 
    143  1.1  cgd #define CLRBIT(A,N) ((A)[N/BITS_PER_MAP] &= ~(1<<(N%BITS_PER_MAP)))
    144  1.1  cgd #define SETBIT(A,N) ((A)[N/BITS_PER_MAP] |= (1<<(N%BITS_PER_MAP)))
    145  1.1  cgd #define ISSET(A,N) ((A)[N/BITS_PER_MAP] & (1<<(N%BITS_PER_MAP)))
    146  1.1  cgd 
    147  1.1  cgd /* Overflow management */
    148  1.1  cgd /*
    149  1.1  cgd 	Overflow page numbers are allocated per split point.
    150  1.1  cgd 	At each doubling of the table, we can allocate extra
    151  1.1  cgd 	pages.  So, an overflow page number has the top 5 bits
    152  1.1  cgd 	indicate which split point and the lower 11 bits indicate
    153  1.1  cgd 	which page at that split point is indicated (pages within
    154  1.1  cgd 	split points are numberered starting with 1).
    155  1.1  cgd 
    156  1.1  cgd 
    157  1.1  cgd */
    158  1.1  cgd 
    159  1.1  cgd #define SPLITSHIFT	11
    160  1.1  cgd #define SPLITMASK	0x7FF
    161  1.1  cgd #define SPLITNUM(N)	(((unsigned)N) >> SPLITSHIFT)
    162  1.1  cgd #define OPAGENUM(N)	(N & SPLITMASK)
    163  1.1  cgd #define	OADDR_OF(S,O)	((unsigned)((unsigned)S << SPLITSHIFT) + O)
    164  1.1  cgd 
    165  1.1  cgd #define BUCKET_TO_PAGE(B) \
    166  1.1  cgd 	B + hashp->HDRPAGES + (B ? hashp->SPARES[__log2(B+1)-1] : 0)
    167  1.1  cgd #define OADDR_TO_PAGE(B) 	\
    168  1.1  cgd 	BUCKET_TO_PAGE ( (1 << SPLITNUM(B)) -1 ) + OPAGENUM(B);
    169  1.1  cgd 
    170  1.1  cgd /*
    171  1.1  cgd     page.h contains a detailed description of the page format.
    172  1.1  cgd 
    173  1.1  cgd     Normally, keys and data are accessed from offset tables in the
    174  1.1  cgd     top of each page which point to the beginning of the key and
    175  1.1  cgd     data.  There are four flag values which may be stored in these
    176  1.1  cgd     offset tables which indicate the following:
    177  1.1  cgd 
    178  1.1  cgd 	OVFLPAGE	Rather than a key data pair, this pair contains
    179  1.1  cgd 			the address of an overflow page.  The format of
    180  1.1  cgd 			the pair is:
    181  1.1  cgd 			    OVERFLOW_PAGE_NUMBER OVFLPAGE
    182  1.1  cgd 
    183  1.1  cgd 	PARTIAL_KEY	This must be the first key/data pair on a page
    184  1.1  cgd 			and implies that page contains only a partial key.
    185  1.1  cgd 			That is, the key is too big to fit on a single page
    186  1.1  cgd 			so it starts on this page and continues on the next.
    187  1.1  cgd 			The format of the page is:
    188  1.1  cgd 			    KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
    189  1.1  cgd 
    190  1.1  cgd 			    KEY_OFF -- offset of the beginning of the key
    191  1.1  cgd 			    PARTIAL_KEY -- 1
    192  1.1  cgd 			    OVFL_PAGENO - page number of the next overflow page
    193  1.1  cgd 			    OVFLPAGE -- 0
    194  1.1  cgd 	FULL_KEY	This must be the first key/data pair on the page.  It
    195  1.1  cgd 			is used in two cases.
    196  1.1  cgd 
    197  1.1  cgd 			Case 1:
    198  1.1  cgd 			    There is a complete key on the page but no data
    199  1.1  cgd 			    (because it wouldn't fit).  The next page contains
    200  1.1  cgd 			    the data.
    201  1.1  cgd 
    202  1.1  cgd 			    Page format it:
    203  1.1  cgd 			    KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
    204  1.1  cgd 
    205  1.1  cgd 			    KEY_OFF -- offset of the beginning of the key
    206  1.1  cgd 			    FULL_KEY -- 2
    207  1.1  cgd 			    OVFL_PAGENO - page number of the next overflow page
    208  1.1  cgd 			    OVFLPAGE -- 0
    209  1.1  cgd 
    210  1.1  cgd 			Case 2:
    211  1.1  cgd 			    This page contains no key, but part of a large
    212  1.1  cgd 			    data field, which is continued on the next page.
    213  1.1  cgd 
    214  1.1  cgd 			    Page format it:
    215  1.1  cgd 			    DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
    216  1.1  cgd 
    217  1.1  cgd 			    KEY_OFF -- offset of the beginning of the data on
    218  1.1  cgd 					this page
    219  1.1  cgd 			    FULL_KEY -- 2
    220  1.1  cgd 			    OVFL_PAGENO - page number of the next overflow page
    221  1.1  cgd 			    OVFLPAGE -- 0
    222  1.1  cgd 
    223  1.1  cgd 	FULL_KEY_DATA	This must be the first key/data pair on the page.
    224  1.1  cgd 			There are two cases:
    225  1.1  cgd 
    226  1.1  cgd 			Case 1:
    227  1.1  cgd 			    This page contains a key and the beginning of the
    228  1.1  cgd 			    data field, but the data field is continued on the
    229  1.1  cgd 			    next page.
    230  1.1  cgd 
    231  1.1  cgd 			    Page format is:
    232  1.1  cgd 			    KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
    233  1.1  cgd 
    234  1.1  cgd 			    KEY_OFF -- offset of the beginning of the key
    235  1.1  cgd 			    FULL_KEY_DATA -- 3
    236  1.1  cgd 			    OVFL_PAGENO - page number of the next overflow page
    237  1.1  cgd 			    DATA_OFF -- offset of the beginning of the data
    238  1.1  cgd 
    239  1.1  cgd 			Case 2:
    240  1.1  cgd 			    This page contains the last page of a big data pair.
    241  1.1  cgd 			    There is no key, only the  tail end of the data
    242  1.1  cgd 			    on this page.
    243  1.1  cgd 
    244  1.1  cgd 			    Page format is:
    245  1.1  cgd 			    DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
    246  1.1  cgd 
    247  1.1  cgd 			    DATA_OFF -- offset of the beginning of the data on
    248  1.1  cgd 					this page
    249  1.1  cgd 			    FULL_KEY_DATA -- 3
    250  1.1  cgd 			    OVFL_PAGENO - page number of the next overflow page
    251  1.1  cgd 			    OVFLPAGE -- 0
    252  1.1  cgd 
    253  1.1  cgd 			    OVFL_PAGENO and OVFLPAGE are optional (they are
    254  1.1  cgd 			    not present if there is no next page).
    255  1.1  cgd */
    256  1.1  cgd 
    257  1.1  cgd #define OVFLPAGE	0
    258  1.1  cgd #define PARTIAL_KEY	1
    259  1.1  cgd #define FULL_KEY	2
    260  1.1  cgd #define FULL_KEY_DATA	3
    261  1.1  cgd #define	REAL_KEY	4
    262  1.1  cgd /* Short hands for accessing structure */
    263  1.1  cgd #define BSIZE	hdr.bsize
    264  1.1  cgd #define BSHIFT	hdr.bshift
    265  1.1  cgd #define DSIZE	hdr.dsize
    266  1.1  cgd #define SGSIZE	hdr.ssize
    267  1.1  cgd #define SSHIFT	hdr.sshift
    268  1.1  cgd #define LORDER	hdr.lorder
    269  1.1  cgd #define MAX_BUCKET	hdr.max_bucket
    270  1.1  cgd #define FFACTOR		hdr.ffactor
    271  1.1  cgd #define HIGH_MASK	hdr.high_mask
    272  1.1  cgd #define LOW_MASK	hdr.low_mask
    273  1.1  cgd #define NKEYS		hdr.nkeys
    274  1.1  cgd #define HDRPAGES	hdr.hdrpages
    275  1.1  cgd #define SPARES		hdr.spares
    276  1.1  cgd #define BITMAPS		hdr.bitmaps
    277  1.1  cgd #define VERSION		hdr.version
    278  1.1  cgd #define MAGIC		hdr.magic
    279  1.1  cgd #define NEXT_FREE	hdr.next_free
    280  1.1  cgd #define H_CHARKEY	hdr.h_charkey
    281