146367Sbostic /*- 261202Sbostic * Copyright (c) 1990, 1993 361202Sbostic * The Regents of the University of California. 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*66193Sbostic * @(#)hash.h 8.2 (Berkeley) 02/21/94 1146367Sbostic */ 1246367Sbostic 1346367Sbostic /* Operations */ 1450997Sbostic typedef enum { 1550997Sbostic HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT 1650997Sbostic } ACTION; 1746367Sbostic 1846367Sbostic /* Buffer Management structures */ 1946367Sbostic typedef struct _bufhead BUFHEAD; 2046367Sbostic 2146367Sbostic struct _bufhead { 2250997Sbostic BUFHEAD *prev; /* LRU links */ 2350997Sbostic BUFHEAD *next; /* LRU links */ 2450997Sbostic BUFHEAD *ovfl; /* Overflow page buffer header */ 2550997Sbostic u_int addr; /* Address of this page */ 2650997Sbostic char *page; /* Actual page data */ 2750997Sbostic char flags; 2846367Sbostic #define BUF_MOD 0x0001 2946367Sbostic #define BUF_DISK 0x0002 3046367Sbostic #define BUF_BUCKET 0x0004 3146458Sbostic #define BUF_PIN 0x0008 3246458Sbostic }; 3346367Sbostic 3450997Sbostic #define IS_BUCKET(X) ((X) & BUF_BUCKET) 3546458Sbostic 3650997Sbostic typedef BUFHEAD **SEGMENT; 3746367Sbostic 3846367Sbostic /* Hash Table Information */ 3946367Sbostic typedef struct hashhdr { /* Disk resident portion */ 4050997Sbostic int magic; /* Magic NO for hash tables */ 4150997Sbostic int version; /* Version ID */ 4250997Sbostic long lorder; /* Byte Order */ 4350997Sbostic int bsize; /* Bucket/Page Size */ 4450997Sbostic int bshift; /* Bucket shift */ 4550997Sbostic int dsize; /* Directory Size */ 4650997Sbostic int ssize; /* Segment Size */ 4750997Sbostic int sshift; /* Segment shift */ 4851061Sbostic int ovfl_point; /* Where overflow pages are being allocated */ 4951061Sbostic int last_freed; /* Last overflow page freed */ 5050997Sbostic int max_bucket; /* ID of Maximum bucket in use */ 5150997Sbostic int high_mask; /* Mask to modulo into entire table */ 5250997Sbostic int low_mask; /* Mask to modulo into lower half of table */ 5350997Sbostic int ffactor; /* Fill factor */ 5450997Sbostic int nkeys; /* Number of keys in hash table */ 5550997Sbostic int hdrpages; /* Size of table header */ 5650997Sbostic int h_charkey; /* value of hash(CHARKEY) */ 5750997Sbostic #define NCACHED 32 /* number of bit maps and spare points */ 5850997Sbostic int spares[NCACHED];/* spare pages for overflow */ 5950997Sbostic u_short bitmaps[NCACHED]; /* address of overflow page bitmaps */ 6046367Sbostic } HASHHDR; 6146367Sbostic 6250997Sbostic typedef struct htab { /* Memory resident data structure */ 6350997Sbostic HASHHDR hdr; /* Header */ 6450997Sbostic int nsegs; /* Number of allocated segments */ 6550997Sbostic int exsegs; /* Number of extra allocated segments */ 66*66193Sbostic u_int32_t /* Hash function */ 67*66193Sbostic (*hash)__P((const void *, size_t)); 6850997Sbostic int flags; /* Flag values */ 6950997Sbostic int fp; /* File pointer */ 7050997Sbostic char *tmp_buf; /* Temporary Buffer for BIG data */ 7150997Sbostic char *tmp_key; /* Temporary Buffer for BIG keys */ 7250997Sbostic BUFHEAD *cpage; /* Current page */ 7350997Sbostic int cbucket; /* Current bucket */ 7450997Sbostic int cndx; /* Index of next item on cpage */ 7550997Sbostic int errno; /* Error Number -- for DBM compatability */ 7650997Sbostic int new_file; /* Indicates if fd is backing store or no */ 7750997Sbostic int save_file; /* Indicates whether we need to flush file at 7850997Sbostic * exit */ 7946367Sbostic u_long *mapp[NCACHED]; /* Pointers to page maps */ 8050997Sbostic int nmaps; /* Initial number of bitmaps */ 8150997Sbostic int nbufs; /* Number of buffers left to allocate */ 8250997Sbostic BUFHEAD bufhead; /* Header of buffer lru list */ 8350997Sbostic SEGMENT *dir; /* Hash Bucket directory */ 8446367Sbostic } HTAB; 8546367Sbostic 8646367Sbostic /* 8746367Sbostic * Constants 8846367Sbostic */ 8950997Sbostic #define MAX_BSIZE 65536 /* 2^16 */ 9046367Sbostic #define MIN_BUFFERS 6 9146367Sbostic #define MINHDRSIZE 512 9250997Sbostic #define DEF_BUFSIZE 65536 /* 64 K */ 9360244Sbostic #define DEF_BUCKET_SIZE 4096 9460244Sbostic #define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */ 9546367Sbostic #define DEF_SEGSIZE 256 9650997Sbostic #define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */ 9746367Sbostic #define DEF_DIRSIZE 256 9860244Sbostic #define DEF_FFACTOR 65536 9960244Sbostic #define MIN_FFACTOR 4 10050997Sbostic #define SPLTMAX 8 10150997Sbostic #define CHARKEY "%$sniglet^&" 10246367Sbostic #define NUMKEY 1038583 10346367Sbostic #define BYTE_SHIFT 3 10446367Sbostic #define INT_TO_BYTE 2 10546367Sbostic #define INT_BYTE_SHIFT 5 10650997Sbostic #define ALL_SET ((u_int)0xFFFFFFFF) 10746367Sbostic #define ALL_CLEAR 0 10846367Sbostic 10950997Sbostic #define PTROF(X) ((BUFHEAD *)((u_int)(X)&~0x3)) 11050997Sbostic #define ISMOD(X) ((u_int)(X)&0x1) 11150997Sbostic #define DOMOD(X) ((X) = (char *)((u_int)(X)|0x1)) 11250997Sbostic #define ISDISK(X) ((u_int)(X)&0x2) 11350997Sbostic #define DODISK(X) ((X) = (char *)((u_int)(X)|0x2)) 11446367Sbostic 11550997Sbostic #define BITS_PER_MAP 32 11646367Sbostic 11746367Sbostic /* Given the address of the beginning of a big map, clear/set the nth bit */ 11850997Sbostic #define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP))) 11950997Sbostic #define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP))) 12050997Sbostic #define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP))) 12146367Sbostic 12246367Sbostic /* Overflow management */ 12346367Sbostic /* 12450997Sbostic * Overflow page numbers are allocated per split point. At each doubling of 12550997Sbostic * the table, we can allocate extra pages. So, an overflow page number has 12650997Sbostic * the top 5 bits indicate which split point and the lower 11 bits indicate 12750997Sbostic * which page at that split point is indicated (pages within split points are 12850997Sbostic * numberered starting with 1). 12950997Sbostic */ 13046367Sbostic 13146367Sbostic #define SPLITSHIFT 11 13246367Sbostic #define SPLITMASK 0x7FF 13350997Sbostic #define SPLITNUM(N) (((u_int)(N)) >> SPLITSHIFT) 13450997Sbostic #define OPAGENUM(N) ((N) & SPLITMASK) 13550997Sbostic #define OADDR_OF(S,O) ((u_int)((u_int)(S) << SPLITSHIFT) + (O)) 13646367Sbostic 13746367Sbostic #define BUCKET_TO_PAGE(B) \ 13850997Sbostic (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0) 13946367Sbostic #define OADDR_TO_PAGE(B) \ 14050997Sbostic BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B)); 14146367Sbostic 14246367Sbostic /* 14350997Sbostic * page.h contains a detailed description of the page format. 14450997Sbostic * 14550997Sbostic * Normally, keys and data are accessed from offset tables in the top of 14650997Sbostic * each page which point to the beginning of the key and data. There are 14750997Sbostic * four flag values which may be stored in these offset tables which indicate 14850997Sbostic * the following: 14950997Sbostic * 15050997Sbostic * 15150997Sbostic * OVFLPAGE Rather than a key data pair, this pair contains 15250997Sbostic * the address of an overflow page. The format of 15350997Sbostic * the pair is: 15450997Sbostic * OVERFLOW_PAGE_NUMBER OVFLPAGE 15550997Sbostic * 15650997Sbostic * PARTIAL_KEY This must be the first key/data pair on a page 15750997Sbostic * and implies that page contains only a partial key. 15850997Sbostic * That is, the key is too big to fit on a single page 15950997Sbostic * so it starts on this page and continues on the next. 16050997Sbostic * The format of the page is: 16150997Sbostic * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE 16250997Sbostic * 16350997Sbostic * KEY_OFF -- offset of the beginning of the key 16450997Sbostic * PARTIAL_KEY -- 1 16550997Sbostic * OVFL_PAGENO - page number of the next overflow page 16650997Sbostic * OVFLPAGE -- 0 16750997Sbostic * 16850997Sbostic * FULL_KEY This must be the first key/data pair on the page. It 16950997Sbostic * is used in two cases. 17050997Sbostic * 17150997Sbostic * Case 1: 17250997Sbostic * There is a complete key on the page but no data 17350997Sbostic * (because it wouldn't fit). The next page contains 17450997Sbostic * the data. 17550997Sbostic * 17650997Sbostic * Page format it: 17750997Sbostic * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE 17850997Sbostic * 17950997Sbostic * KEY_OFF -- offset of the beginning of the key 18050997Sbostic * FULL_KEY -- 2 18150997Sbostic * OVFL_PAGENO - page number of the next overflow page 18250997Sbostic * OVFLPAGE -- 0 18350997Sbostic * 18450997Sbostic * Case 2: 18550997Sbostic * This page contains no key, but part of a large 18650997Sbostic * data field, which is continued on the next page. 18750997Sbostic * 18850997Sbostic * Page format it: 18950997Sbostic * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE 19050997Sbostic * 19150997Sbostic * KEY_OFF -- offset of the beginning of the data on 19250997Sbostic * this page 19350997Sbostic * FULL_KEY -- 2 19450997Sbostic * OVFL_PAGENO - page number of the next overflow page 19550997Sbostic * OVFLPAGE -- 0 19650997Sbostic * 19750997Sbostic * FULL_KEY_DATA 19850997Sbostic * This must be the first key/data pair on the page. 19950997Sbostic * There are two cases: 20050997Sbostic * 20150997Sbostic * Case 1: 20250997Sbostic * This page contains a key and the beginning of the 20350997Sbostic * data field, but the data field is continued on the 20450997Sbostic * next page. 20550997Sbostic * 20650997Sbostic * Page format is: 20750997Sbostic * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF 20850997Sbostic * 20950997Sbostic * KEY_OFF -- offset of the beginning of the key 21050997Sbostic * FULL_KEY_DATA -- 3 21150997Sbostic * OVFL_PAGENO - page number of the next overflow page 21250997Sbostic * DATA_OFF -- offset of the beginning of the data 21350997Sbostic * 21450997Sbostic * Case 2: 21550997Sbostic * This page contains the last page of a big data pair. 21650997Sbostic * There is no key, only the tail end of the data 21750997Sbostic * on this page. 21850997Sbostic * 21950997Sbostic * Page format is: 22050997Sbostic * DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE> 22150997Sbostic * 22250997Sbostic * DATA_OFF -- offset of the beginning of the data on 22350997Sbostic * this page 22450997Sbostic * FULL_KEY_DATA -- 3 22550997Sbostic * OVFL_PAGENO - page number of the next overflow page 22650997Sbostic * OVFLPAGE -- 0 22750997Sbostic * 22850997Sbostic * OVFL_PAGENO and OVFLPAGE are optional (they are 22950997Sbostic * not present if there is no next page). 23050997Sbostic */ 23146367Sbostic 23246367Sbostic #define OVFLPAGE 0 23346367Sbostic #define PARTIAL_KEY 1 23446367Sbostic #define FULL_KEY 2 23546367Sbostic #define FULL_KEY_DATA 3 23646367Sbostic #define REAL_KEY 4 23750997Sbostic 23846367Sbostic /* Short hands for accessing structure */ 23950997Sbostic #define BSIZE hdr.bsize 24050997Sbostic #define BSHIFT hdr.bshift 24150997Sbostic #define DSIZE hdr.dsize 24250997Sbostic #define SGSIZE hdr.ssize 24350997Sbostic #define SSHIFT hdr.sshift 24450997Sbostic #define LORDER hdr.lorder 24551061Sbostic #define OVFL_POINT hdr.ovfl_point 24651061Sbostic #define LAST_FREED hdr.last_freed 24746367Sbostic #define MAX_BUCKET hdr.max_bucket 24846367Sbostic #define FFACTOR hdr.ffactor 24946367Sbostic #define HIGH_MASK hdr.high_mask 25046367Sbostic #define LOW_MASK hdr.low_mask 25146367Sbostic #define NKEYS hdr.nkeys 25246367Sbostic #define HDRPAGES hdr.hdrpages 25346367Sbostic #define SPARES hdr.spares 25446367Sbostic #define BITMAPS hdr.bitmaps 25546367Sbostic #define VERSION hdr.version 25646367Sbostic #define MAGIC hdr.magic 25746367Sbostic #define NEXT_FREE hdr.next_free 25846367Sbostic #define H_CHARKEY hdr.h_charkey 259