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