OLD | NEW |
1 /*- | 1 /*- |
2 * Copyright (c) 1990, 1993, 1994 | 2 * Copyright (c) 1990, 1993, 1994 |
3 * The Regents of the University of California. All rights reserved. | 3 * The Regents of the University of California. All rights reserved. |
4 * | 4 * |
5 * This code is derived from software contributed to Berkeley by | 5 * This code is derived from software contributed to Berkeley by |
6 * Margo Seltzer. | 6 * Margo Seltzer. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
11 * 1. Redistributions of source code must retain the above copyright | 11 * 1. Redistributions of source code must retain the above copyright |
12 * notice, this list of conditions and the following disclaimer. | 12 * notice, this list of conditions and the following disclaimer. |
13 * 2. Redistributions in binary form must reproduce the above copyright | 13 * 2. Redistributions in binary form must reproduce the above copyright |
14 * notice, this list of conditions and the following disclaimer in the | 14 * notice, this list of conditions and the following disclaimer in the |
15 * documentation and/or other materials provided with the distribution. | 15 * documentation and/or other materials provided with the distribution. |
16 * 3. ***REMOVED*** - see | 16 * 3. ***REMOVED*** - see |
17 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change | 17 * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change |
18 * 4. Neither the name of the University nor the names of its contributors | 18 * 4. Neither the name of the University nor the names of its contributors |
19 * may be used to endorse or promote products derived from this software | 19 * may be used to endorse or promote products derived from this software |
20 * without specific prior written permission. | 20 * without specific prior written permission. |
21 * | 21 * |
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 | 77 |
78 /* | 78 /* |
79 * Big_insert | 79 * Big_insert |
80 * | 80 * |
81 * You need to do an insert and the key/data pair is too big | 81 * You need to do an insert and the key/data pair is too big |
82 * | 82 * |
83 * Returns: | 83 * Returns: |
84 * 0 ==> OK | 84 * 0 ==> OK |
85 *-1 ==> ERROR | 85 *-1 ==> ERROR |
86 */ | 86 */ |
87 extern int | 87 extern int __big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, |
88 __big_insert(HTAB *hashp, BUFHEAD *bufp, const DBT *key, const DBT *val) | 88 const DBT *val) { |
89 { | 89 register uint16 *p; |
90 » register uint16 *p; | 90 uint key_size, n, val_size; |
91 » uint key_size, n, val_size; | 91 uint16 space, move_bytes, off; |
92 » uint16 space, move_bytes, off; | 92 char *cp, *key_data, *val_data; |
93 » char *cp, *key_data, *val_data; | 93 |
94 | 94 cp = bufp->page; /* Character pointer of p. */ |
95 » cp = bufp->page;» » /* Character pointer of p. */ | 95 p = (uint16 *)cp; |
96 » p = (uint16 *)cp; | 96 |
97 | 97 key_data = (char *)key->data; |
98 » key_data = (char *)key->data; | 98 key_size = key->size; |
99 » key_size = key->size; | 99 val_data = (char *)val->data; |
100 » val_data = (char *)val->data; | 100 val_size = val->size; |
101 » val_size = val->size; | 101 |
102 | 102 /* First move the Key */ |
103 » /* First move the Key */ | 103 for (space = FREESPACE(p) - BIGOVERHEAD; key_size; |
104 » for (space = FREESPACE(p) - BIGOVERHEAD; key_size; | 104 space = FREESPACE(p) - BIGOVERHEAD) { |
105 » space = FREESPACE(p) - BIGOVERHEAD) { | 105 move_bytes = PR_MIN(space, key_size); |
106 » » move_bytes = PR_MIN(space, key_size); | 106 off = OFFSET(p) - move_bytes; |
107 » » off = OFFSET(p) - move_bytes; | 107 memmove(cp + off, key_data, move_bytes); |
108 » » memmove(cp + off, key_data, move_bytes); | 108 key_size -= move_bytes; |
109 » » key_size -= move_bytes; | 109 key_data += move_bytes; |
110 » » key_data += move_bytes; | 110 n = p[0]; |
111 » » n = p[0]; | 111 p[++n] = off; |
112 » » p[++n] = off; | 112 p[0] = ++n; |
113 » » p[0] = ++n; | 113 FREESPACE(p) = off - PAGE_META(n); |
114 » » FREESPACE(p) = off - PAGE_META(n); | 114 OFFSET(p) = off; |
115 » » OFFSET(p) = off; | 115 p[n] = PARTIAL_KEY; |
116 » » p[n] = PARTIAL_KEY; | 116 bufp = __add_ovflpage(hashp, bufp); |
117 » » bufp = __add_ovflpage(hashp, bufp); | 117 if (!bufp) return (-1); |
118 » » if (!bufp) | 118 n = p[0]; |
119 » » » return (-1); | 119 if (!key_size) { |
120 » » n = p[0]; | 120 if (FREESPACE(p)) { |
121 » » if (!key_size) { | 121 move_bytes = PR_MIN(FREESPACE(p), val_size); |
122 » » » if (FREESPACE(p)) { | 122 off = OFFSET(p) - move_bytes; |
123 » » » » move_bytes = PR_MIN(FREESPACE(p), val_size); | 123 p[n] = off; |
124 » » » » off = OFFSET(p) - move_bytes; | 124 memmove(cp + off, val_data, move_bytes); |
125 » » » » p[n] = off; | 125 val_data += move_bytes; |
126 » » » » memmove(cp + off, val_data, move_bytes); | 126 val_size -= move_bytes; |
127 » » » » val_data += move_bytes; | 127 p[n - 2] = FULL_KEY_DATA; |
128 » » » » val_size -= move_bytes; | 128 FREESPACE(p) = FREESPACE(p) - move_bytes; |
129 » » » » p[n - 2] = FULL_KEY_DATA; | 129 OFFSET(p) = off; |
130 » » » » FREESPACE(p) = FREESPACE(p) - move_bytes; | 130 } else |
131 » » » » OFFSET(p) = off; | 131 p[n - 2] = FULL_KEY; |
132 » » » } else | 132 } |
133 » » » » p[n - 2] = FULL_KEY; | 133 p = (uint16 *)bufp->page; |
134 » » } | 134 cp = bufp->page; |
135 » » p = (uint16 *)bufp->page; | 135 bufp->flags |= BUF_MOD; |
136 » » cp = bufp->page; | 136 } |
137 » » bufp->flags |= BUF_MOD; | 137 |
138 » } | 138 /* Now move the data */ |
139 | 139 for (space = FREESPACE(p) - BIGOVERHEAD; val_size; |
140 » /* Now move the data */ | 140 space = FREESPACE(p) - BIGOVERHEAD) { |
141 » for (space = FREESPACE(p) - BIGOVERHEAD; val_size; | 141 move_bytes = PR_MIN(space, val_size); |
142 » space = FREESPACE(p) - BIGOVERHEAD) { | 142 /* |
143 » » move_bytes = PR_MIN(space, val_size); | 143 * Here's the hack to make sure that if the data ends on the |
144 » » /* | 144 * same page as the key ends, FREESPACE is at least one. |
145 » » * Here's the hack to make sure that if the data ends on the | 145 */ |
146 » » * same page as the key ends, FREESPACE is at least one. | 146 if (space == val_size && val_size == val->size) move_bytes--; |
147 » » */ | 147 off = OFFSET(p) - move_bytes; |
148 » » if (space == val_size && val_size == val->size) | 148 memmove(cp + off, val_data, move_bytes); |
149 » » » move_bytes--; | 149 val_size -= move_bytes; |
150 » » off = OFFSET(p) - move_bytes; | 150 val_data += move_bytes; |
151 » » memmove(cp + off, val_data, move_bytes); | 151 n = p[0]; |
152 » » val_size -= move_bytes; | 152 p[++n] = off; |
153 » » val_data += move_bytes; | 153 p[0] = ++n; |
154 » » n = p[0]; | 154 FREESPACE(p) = off - PAGE_META(n); |
155 » » p[++n] = off; | 155 OFFSET(p) = off; |
156 » » p[0] = ++n; | 156 if (val_size) { |
157 » » FREESPACE(p) = off - PAGE_META(n); | 157 p[n] = FULL_KEY; |
158 » » OFFSET(p) = off; | 158 bufp = __add_ovflpage(hashp, bufp); |
159 » » if (val_size) { | 159 if (!bufp) return (-1); |
160 » » » p[n] = FULL_KEY; | 160 cp = bufp->page; |
161 » » » bufp = __add_ovflpage(hashp, bufp); | 161 p = (uint16 *)cp; |
162 » » » if (!bufp) | 162 } else |
163 » » » » return (-1); | 163 p[n] = FULL_KEY_DATA; |
164 » » » cp = bufp->page; | 164 bufp->flags |= BUF_MOD; |
165 » » » p = (uint16 *)cp; | 165 } |
166 » » } else | 166 return (0); |
167 » » » p[n] = FULL_KEY_DATA; | |
168 » » bufp->flags |= BUF_MOD; | |
169 » } | |
170 » return (0); | |
171 } | 167 } |
172 | 168 |
173 /* | 169 /* |
174 * Called when bufp's page contains a partial key (index should be 1) | 170 * Called when bufp's page contains a partial key (index should be 1) |
175 * | 171 * |
176 * All pages in the big key/data pair except bufp are freed. We cannot | 172 * All pages in the big key/data pair except bufp are freed. We cannot |
177 * free bufp because the page pointing to it is lost and we can't get rid | 173 * free bufp because the page pointing to it is lost and we can't get rid |
178 * of its pointer. | 174 * of its pointer. |
179 * | 175 * |
180 * Returns: | 176 * Returns: |
181 * 0 => OK | 177 * 0 => OK |
182 *-1 => ERROR | 178 *-1 => ERROR |
183 */ | 179 */ |
184 extern int | 180 extern int __big_delete(HTAB *hashp, BUFHEAD *bufp) { |
185 __big_delete(HTAB *hashp, BUFHEAD *bufp) | 181 register BUFHEAD *last_bfp, *rbufp; |
186 { | 182 uint16 *bp, pageno; |
187 » register BUFHEAD *last_bfp, *rbufp; | 183 int key_done, n; |
188 » uint16 *bp, pageno; | 184 |
189 » int key_done, n; | 185 rbufp = bufp; |
190 | 186 last_bfp = NULL; |
191 » rbufp = bufp; | 187 bp = (uint16 *)bufp->page; |
192 » last_bfp = NULL; | 188 pageno = 0; |
193 » bp = (uint16 *)bufp->page; | 189 key_done = 0; |
194 » pageno = 0; | 190 |
195 » key_done = 0; | 191 while (!key_done || (bp[2] != FULL_KEY_DATA)) { |
196 | 192 if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) key_done = 1; |
197 » while (!key_done || (bp[2] != FULL_KEY_DATA)) { | 193 |
198 » » if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) | 194 /* |
199 » » » key_done = 1; | 195 * If there is freespace left on a FULL_KEY_DATA page, then |
200 | 196 * the data is short and fits entirely on this page, and this |
201 » » /* | 197 * is the last page. |
202 » » * If there is freespace left on a FULL_KEY_DATA page, then | 198 */ |
203 » » * the data is short and fits entirely on this page, and this | 199 if (bp[2] == FULL_KEY_DATA && FREESPACE(bp)) break; |
204 » » * is the last page. | 200 pageno = bp[bp[0] - 1]; |
205 » » */ | 201 rbufp->flags |= BUF_MOD; |
206 » » if (bp[2] == FULL_KEY_DATA && FREESPACE(bp)) | 202 rbufp = __get_buf(hashp, pageno, rbufp, 0); |
207 » » » break; | 203 if (last_bfp) __free_ovflpage(hashp, last_bfp); |
208 » » pageno = bp[bp[0] - 1]; | 204 last_bfp = rbufp; |
209 » » rbufp->flags |= BUF_MOD; | 205 if (!rbufp) return (-1); /* Error. */ |
210 » » rbufp = __get_buf(hashp, pageno, rbufp, 0); | 206 bp = (uint16 *)rbufp->page; |
211 » » if (last_bfp) | 207 } |
212 » » » __free_ovflpage(hashp, last_bfp); | 208 |
213 » » last_bfp = rbufp; | 209 /* |
214 » » if (!rbufp) | 210 * If we get here then rbufp points to the last page of the big |
215 » » » return (-1);» » /* Error. */ | 211 * key/data pair. Bufp points to the first one -- it should now be |
216 » » bp = (uint16 *)rbufp->page; | 212 * empty pointing to the next page after this pair. Can't free it |
217 » } | 213 * because we don't have the page pointing to it. |
218 | 214 */ |
219 » /* | 215 |
220 » * If we get here then rbufp points to the last page of the big | 216 /* This is information from the last page of the pair. */ |
221 » * key/data pair. Bufp points to the first one -- it should now be | 217 n = bp[0]; |
222 » * empty pointing to the next page after this pair. Can't free it | 218 pageno = bp[n - 1]; |
223 » * because we don't have the page pointing to it. | 219 |
224 » */ | 220 /* Now, bp is the first page of the pair. */ |
225 | 221 bp = (uint16 *)bufp->page; |
226 » /* This is information from the last page of the pair. */ | 222 if (n > 2) { |
227 » n = bp[0]; | 223 /* There is an overflow page. */ |
228 » pageno = bp[n - 1]; | 224 bp[1] = pageno; |
229 | 225 bp[2] = OVFLPAGE; |
230 » /* Now, bp is the first page of the pair. */ | 226 bufp->ovfl = rbufp->ovfl; |
231 » bp = (uint16 *)bufp->page; | 227 } else |
232 » if (n > 2) { | 228 /* This is the last page. */ |
233 » » /* There is an overflow page. */ | 229 bufp->ovfl = NULL; |
234 » » bp[1] = pageno; | 230 n -= 2; |
235 » » bp[2] = OVFLPAGE; | 231 bp[0] = n; |
236 » » bufp->ovfl = rbufp->ovfl; | 232 FREESPACE(bp) = hashp->BSIZE - PAGE_META(n); |
237 » } else | 233 OFFSET(bp) = hashp->BSIZE - 1; |
238 » » /* This is the last page. */ | 234 |
239 » » bufp->ovfl = NULL; | 235 bufp->flags |= BUF_MOD; |
240 » n -= 2; | 236 if (rbufp) __free_ovflpage(hashp, rbufp); |
241 » bp[0] = n; | 237 if (last_bfp != rbufp) __free_ovflpage(hashp, last_bfp); |
242 » FREESPACE(bp) = hashp->BSIZE - PAGE_META(n); | 238 |
243 » OFFSET(bp) = hashp->BSIZE - 1; | 239 hashp->NKEYS--; |
244 | 240 return (0); |
245 » bufp->flags |= BUF_MOD; | |
246 » if (rbufp) | |
247 » » __free_ovflpage(hashp, rbufp); | |
248 » if (last_bfp != rbufp) | |
249 » » __free_ovflpage(hashp, last_bfp); | |
250 | |
251 » hashp->NKEYS--; | |
252 » return (0); | |
253 } | 241 } |
254 /* | 242 /* |
255 * Returns: | 243 * Returns: |
256 * 0 = key not found | 244 * 0 = key not found |
257 * -1 = get next overflow page | 245 * -1 = get next overflow page |
258 * -2 means key not found and this is big key/data | 246 * -2 means key not found and this is big key/data |
259 * -3 error | 247 * -3 error |
260 */ | 248 */ |
261 extern int | 249 extern int __find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, |
262 __find_bigpair(HTAB *hashp, BUFHEAD *bufp, int ndx, char *key, int size) | 250 int size) { |
263 { | 251 register uint16 *bp; |
264 » register uint16 *bp; | 252 register char *p; |
265 » register char *p; | 253 int ksize; |
266 » int ksize; | 254 uint16 bytes; |
267 » uint16 bytes; | 255 char *kkey; |
268 » char *kkey; | 256 |
269 | 257 bp = (uint16 *)bufp->page; |
270 » bp = (uint16 *)bufp->page; | 258 p = bufp->page; |
271 » p = bufp->page; | 259 ksize = size; |
272 » ksize = size; | 260 kkey = key; |
273 » kkey = key; | 261 |
274 | 262 for (bytes = hashp->BSIZE - bp[ndx]; |
275 » for (bytes = hashp->BSIZE - bp[ndx]; | 263 bytes <= size && bp[ndx + 1] == PARTIAL_KEY; |
276 » bytes <= size && bp[ndx + 1] == PARTIAL_KEY; | 264 bytes = hashp->BSIZE - bp[ndx]) { |
277 » bytes = hashp->BSIZE - bp[ndx]) { | 265 if (memcmp(p + bp[ndx], kkey, bytes)) return (-2); |
278 » » if (memcmp(p + bp[ndx], kkey, bytes)) | 266 kkey += bytes; |
279 » » » return (-2); | 267 ksize -= bytes; |
280 » » kkey += bytes; | 268 bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0); |
281 » » ksize -= bytes; | 269 if (!bufp) return (-3); |
282 » » bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0); | 270 p = bufp->page; |
283 » » if (!bufp) | 271 bp = (uint16 *)p; |
284 » » » return (-3); | 272 ndx = 1; |
285 » » p = bufp->page; | 273 } |
286 » » bp = (uint16 *)p; | 274 |
287 » » ndx = 1; | 275 if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) { |
288 » } | |
289 | |
290 » if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) { | |
291 #ifdef HASH_STATISTICS | 276 #ifdef HASH_STATISTICS |
292 » » ++hash_collisions; | 277 ++hash_collisions; |
293 #endif | 278 #endif |
294 » » return (-2); | 279 return (-2); |
295 » } else | 280 } else |
296 » » return (ndx); | 281 return (ndx); |
297 } | 282 } |
298 | 283 |
299 /* | 284 /* |
300 * Given the buffer pointer of the first overflow page of a big pair, | 285 * Given the buffer pointer of the first overflow page of a big pair, |
301 * find the end of the big pair | 286 * find the end of the big pair |
302 * | 287 * |
303 * This will set bpp to the buffer header of the last page of the big pair. | 288 * This will set bpp to the buffer header of the last page of the big pair. |
304 * It will return the pageno of the overflow page following the last page | 289 * It will return the pageno of the overflow page following the last page |
305 * of the pair; 0 if there isn't any (i.e. big pair is the last key in the | 290 * of the pair; 0 if there isn't any (i.e. big pair is the last key in the |
306 * bucket) | 291 * bucket) |
307 */ | 292 */ |
308 extern uint16 | 293 extern uint16 __find_last_page(HTAB *hashp, BUFHEAD **bpp) { |
309 __find_last_page(HTAB *hashp, BUFHEAD **bpp) | 294 BUFHEAD *bufp; |
310 { | 295 uint16 *bp, pageno; |
311 » BUFHEAD *bufp; | 296 uint n; |
312 » uint16 *bp, pageno; | 297 |
313 » uint n; | 298 bufp = *bpp; |
314 | 299 bp = (uint16 *)bufp->page; |
315 » bufp = *bpp; | 300 for (;;) { |
316 » bp = (uint16 *)bufp->page; | 301 n = bp[0]; |
317 » for (;;) { | 302 |
318 » » n = bp[0]; | 303 /* |
319 | 304 * This is the last page if: the tag is FULL_KEY_DATA and |
320 » » /* | 305 * either only 2 entries OVFLPAGE marker is explicit there |
321 » » * This is the last page if: the tag is FULL_KEY_DATA and | 306 * is freespace on the page. |
322 » » * either only 2 entries OVFLPAGE marker is explicit there | 307 */ |
323 » » * is freespace on the page. | 308 if (bp[2] == FULL_KEY_DATA && |
324 » » */ | 309 ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp)))) |
325 » » if (bp[2] == FULL_KEY_DATA && | 310 break; |
326 » » ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp)))) | 311 |
327 » » » break; | 312 /* LJM bound the size of n to reasonable limits |
328 | 313 */ |
329 » » /* LJM bound the size of n to reasonable limits | 314 if (n > hashp->BSIZE / sizeof(uint16)) return (0); |
330 » » */ | 315 |
331 » » if(n > hashp->BSIZE/sizeof(uint16)) | 316 pageno = bp[n - 1]; |
332 » » » return(0); | 317 bufp = __get_buf(hashp, pageno, bufp, 0); |
333 | 318 if (!bufp) return (0); /* Need to indicate an error! */ |
334 » » pageno = bp[n - 1]; | 319 bp = (uint16 *)bufp->page; |
335 » » bufp = __get_buf(hashp, pageno, bufp, 0); | 320 } |
336 » » if (!bufp) | 321 |
337 » » » return (0);» /* Need to indicate an error! */ | 322 *bpp = bufp; |
338 » » bp = (uint16 *)bufp->page; | 323 if (bp[0] > 2) |
339 » } | 324 return (bp[3]); |
340 | 325 else |
341 » *bpp = bufp; | 326 return (0); |
342 » if (bp[0] > 2) | |
343 » » return (bp[3]); | |
344 » else | |
345 » » return (0); | |
346 } | 327 } |
347 | 328 |
348 /* | 329 /* |
349 * Return the data for the key/data pair that begins on this page at this | 330 * Return the data for the key/data pair that begins on this page at this |
350 * index (index should always be 1). | 331 * index (index should always be 1). |
351 */ | 332 */ |
352 extern int | 333 extern int __big_return(HTAB *hashp, BUFHEAD *bufp, int ndx, DBT *val, |
353 __big_return( | 334 int set_current) { |
354 » HTAB *hashp, | 335 BUFHEAD *save_p; |
355 » BUFHEAD *bufp, | 336 uint16 *bp, len, off, save_addr; |
356 » int ndx, | 337 char *tp; |
357 » DBT *val, | 338 int save_flags; |
358 » int set_current) | 339 |
359 { | 340 bp = (uint16 *)bufp->page; |
360 » BUFHEAD *save_p; | 341 while (bp[ndx + 1] == PARTIAL_KEY) { |
361 » uint16 *bp, len, off, save_addr; | 342 bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); |
362 » char *tp; | 343 if (!bufp) return (-1); |
363 » int save_flags; | 344 bp = (uint16 *)bufp->page; |
364 | 345 ndx = 1; |
365 » bp = (uint16 *)bufp->page; | 346 } |
366 » while (bp[ndx + 1] == PARTIAL_KEY) { | 347 |
367 » » bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); | 348 if (bp[ndx + 1] == FULL_KEY) { |
368 » » if (!bufp) | 349 bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); |
369 » » » return (-1); | 350 if (!bufp) return (-1); |
370 » » bp = (uint16 *)bufp->page; | 351 bp = (uint16 *)bufp->page; |
371 » » ndx = 1; | 352 save_p = bufp; |
372 » } | 353 save_addr = save_p->addr; |
373 | 354 off = bp[1]; |
374 » if (bp[ndx + 1] == FULL_KEY) { | 355 len = 0; |
375 » » bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); | 356 } else if (!FREESPACE(bp)) { |
376 » » if (!bufp) | 357 /* |
377 » » » return (-1); | 358 * This is a hack. We can't distinguish between |
378 » » bp = (uint16 *)bufp->page; | 359 * FULL_KEY_DATA that contains complete data or |
379 » » save_p = bufp; | 360 * incomplete data, so we require that if the data |
380 » » save_addr = save_p->addr; | 361 * is complete, there is at least 1 byte of free |
381 » » off = bp[1]; | 362 * space left. |
382 » » len = 0; | 363 */ |
383 » } else | 364 off = bp[bp[0]]; |
384 » » if (!FREESPACE(bp)) { | 365 len = bp[1] - off; |
385 » » » /* | 366 save_p = bufp; |
386 » » » * This is a hack. We can't distinguish between | 367 save_addr = bufp->addr; |
387 » » » * FULL_KEY_DATA that contains complete data or | 368 bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); |
388 » » » * incomplete data, so we require that if the data | 369 if (!bufp) return (-1); |
389 » » » * is complete, there is at least 1 byte of free | 370 bp = (uint16 *)bufp->page; |
390 » » » * space left. | 371 } else { |
391 » » » */ | 372 /* The data is all on one page. */ |
392 » » » off = bp[bp[0]]; | 373 tp = (char *)bp; |
393 » » » len = bp[1] - off; | 374 off = bp[bp[0]]; |
394 » » » save_p = bufp; | 375 val->data = (uint8 *)tp + off; |
395 » » » save_addr = bufp->addr; | 376 val->size = bp[1] - off; |
396 » » » bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); | 377 if (set_current) { |
397 » » » if (!bufp) | 378 if (bp[0] == 2) {/* No more buckets in |
398 » » » » return (-1); | 379 * chain */ |
399 » » » bp = (uint16 *)bufp->page; | 380 hashp->cpage = NULL; |
400 » » } else { | 381 hashp->cbucket++; |
401 » » » /* The data is all on one page. */ | 382 hashp->cndx = 1; |
402 » » » tp = (char *)bp; | 383 } else { |
403 » » » off = bp[bp[0]]; | 384 hashp->cpage = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); |
404 » » » val->data = (uint8 *)tp + off; | 385 if (!hashp->cpage) return (-1); |
405 » » » val->size = bp[1] - off; | 386 hashp->cndx = 1; |
406 » » » if (set_current) { | 387 if (!((uint16 *)hashp->cpage->page)[0]) { |
407 » » » » if (bp[0] == 2) {» /* No more buckets in | 388 hashp->cbucket++; |
408 » » » » » » » * chain */ | 389 hashp->cpage = NULL; |
409 » » » » » hashp->cpage = NULL; | 390 } |
410 » » » » » hashp->cbucket++; | 391 } |
411 » » » » » hashp->cndx = 1; | 392 } |
412 » » » » } else { | 393 return (0); |
413 » » » » » hashp->cpage = __get_buf(hashp, | 394 } |
414 » » » » » bp[bp[0] - 1], bufp, 0); | 395 |
415 » » » » » if (!hashp->cpage) | 396 /* pin our saved buf so that we don't lose if |
416 » » » » » » return (-1); | 397 * we run out of buffers */ |
417 » » » » » hashp->cndx = 1; | 398 save_flags = save_p->flags; |
418 » » » » » if (!((uint16 *) | 399 save_p->flags |= BUF_PIN; |
419 » » » » » hashp->cpage->page)[0]) { | 400 val->size = collect_data(hashp, bufp, (int)len, set_current); |
420 » » » » » » hashp->cbucket++; | 401 save_p->flags = save_flags; |
421 » » » » » » hashp->cpage = NULL; | 402 if (val->size == (size_t) - 1) return (-1); |
422 » » » » » } | 403 if (save_p->addr != save_addr) { |
423 » » » » } | 404 /* We are pretty short on buffers. */ |
424 » » » } | 405 errno = EINVAL; /* OUT OF BUFFERS */ |
425 » » » return (0); | 406 return (-1); |
426 » » } | 407 } |
427 | 408 memmove(hashp->tmp_buf, (save_p->page) + off, len); |
428 » /* pin our saved buf so that we don't lose if· | 409 val->data = (uint8 *)hashp->tmp_buf; |
429 » * we run out of buffers */ | 410 return (0); |
430 » save_flags = save_p->flags; | 411 } |
431 » save_p->flags |= BUF_PIN; | |
432 » val->size = collect_data(hashp, bufp, (int)len, set_current); | |
433 » save_p->flags = save_flags; | |
434 » if (val->size == (size_t)-1) | |
435 » » return (-1); | |
436 » if (save_p->addr != save_addr) { | |
437 » » /* We are pretty short on buffers. */ | |
438 » » errno = EINVAL;»» » /* OUT OF BUFFERS */ | |
439 » » return (-1); | |
440 » } | |
441 » memmove(hashp->tmp_buf, (save_p->page) + off, len); | |
442 » val->data = (uint8 *)hashp->tmp_buf; | |
443 » return (0); | |
444 } | |
445 | |
446 | 412 |
447 /* | 413 /* |
448 * Count how big the total datasize is by looping through the pages. Then | 414 * Count how big the total datasize is by looping through the pages. Then |
449 * allocate a buffer and copy the data in the second loop. NOTE: Our caller | 415 * allocate a buffer and copy the data in the second loop. NOTE: Our caller |
450 * may already have a bp which it is holding onto. The caller is | 416 * may already have a bp which it is holding onto. The caller is |
451 * responsible for copying that bp into our temp buffer. 'len' is how much | 417 * responsible for copying that bp into our temp buffer. 'len' is how much |
452 * space to reserve for that buffer. | 418 * space to reserve for that buffer. |
453 */ | 419 */ |
454 static int | 420 static int collect_data(HTAB *hashp, BUFHEAD *bufp, int len, int set) { |
455 collect_data( | 421 register uint16 *bp; |
456 » HTAB *hashp, | 422 BUFHEAD *save_bufp; |
457 » BUFHEAD *bufp, | 423 int save_flags; |
458 » int len, int set) | 424 int mylen, totlen; |
459 { | 425 |
460 » register uint16 *bp; | 426 /* |
461 » BUFHEAD *save_bufp; | 427 * save the input buf head because we need to walk the list twice. |
462 » int save_flags; | 428 * pin it to make sure it doesn't leave the buffer pool. |
463 » int mylen, totlen; | 429 * This has the effect of growing the buffer pool if necessary. |
464 | 430 */ |
465 » /* | 431 save_bufp = bufp; |
466 » * save the input buf head because we need to walk the list twice. | 432 save_flags = save_bufp->flags; |
467 » * pin it to make sure it doesn't leave the buffer pool.· | 433 save_bufp->flags |= BUF_PIN; |
468 » * This has the effect of growing the buffer pool if necessary. | 434 |
469 » */ | 435 /* read the length of the buffer */ |
470 » save_bufp = bufp; | 436 for (totlen = len; bufp; bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0)) { |
471 » save_flags = save_bufp->flags; | 437 bp = (uint16 *)bufp->page; |
472 » save_bufp->flags |= BUF_PIN; | 438 mylen = hashp->BSIZE - bp[1]; |
473 | 439 |
474 » /* read the length of the buffer */ | 440 /* if mylen ever goes negative it means that the |
475 » for (totlen = len; bufp ; bufp = __get_buf(hashp, bp[bp[0]-1], bufp, 0))
{ | 441 * page is screwed up. |
476 » » bp = (uint16 *)bufp->page; | 442 */ |
477 » » mylen = hashp->BSIZE - bp[1]; | 443 if (mylen < 0) { |
478 | 444 save_bufp->flags = save_flags; |
479 » » /* if mylen ever goes negative it means that the | 445 return (-1); |
480 » » * page is screwed up. | 446 } |
481 » » */ | 447 totlen += mylen; |
482 » » if (mylen < 0) { | 448 if (bp[2] == FULL_KEY_DATA) {/* End of Data */ |
483 » » » save_bufp->flags = save_flags; | 449 break; |
484 » » » return (-1); | 450 } |
485 » » } | 451 } |
486 » » totlen += mylen; | 452 |
487 » » if (bp[2] == FULL_KEY_DATA) {» » /* End of Data */ | 453 if (!bufp) { |
488 » » » break; | 454 save_bufp->flags = save_flags; |
489 » » } | 455 return (-1); |
490 » } | 456 } |
491 | 457 |
492 » if (!bufp) { | 458 /* allocate a temp buf */ |
493 » » save_bufp->flags = save_flags; | 459 if (hashp->tmp_buf) free(hashp->tmp_buf); |
494 » » return (-1); | 460 if ((hashp->tmp_buf = (char *)malloc((size_t)totlen)) == NULL) { |
495 » } | 461 save_bufp->flags = save_flags; |
496 | 462 return (-1); |
497 » /* allocate a temp buf */ | 463 } |
498 » if (hashp->tmp_buf) | 464 |
499 » » free(hashp->tmp_buf); | 465 /* copy the buffers back into temp buf */ |
500 » if ((hashp->tmp_buf = (char *)malloc((size_t)totlen)) == NULL) { | 466 for (bufp = save_bufp; bufp; |
501 » » save_bufp->flags = save_flags; | 467 bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0)) { |
502 » » return (-1); | 468 bp = (uint16 *)bufp->page; |
503 » } | 469 mylen = hashp->BSIZE - bp[1]; |
504 | 470 memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], (size_t)mylen); |
505 » /* copy the buffers back into temp buf */ | 471 len += mylen; |
506 » for (bufp = save_bufp; bufp ; | 472 if (bp[2] == FULL_KEY_DATA) { |
507 » » » » bufp = __get_buf(hashp, bp[bp[0]-1], bufp, 0)) { | 473 break; |
508 » » bp = (uint16 *)bufp->page; | 474 } |
509 » » mylen = hashp->BSIZE - bp[1]; | 475 } |
510 » » memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], (size_t)myle
n); | 476 |
511 » » len += mylen; | 477 /* 'clear' the pin flags */ |
512 » » if (bp[2] == FULL_KEY_DATA) { | 478 save_bufp->flags = save_flags; |
513 » » » break; | 479 |
514 » » } | 480 /* update the database cursor */ |
515 » } | 481 if (set) { |
516 | 482 hashp->cndx = 1; |
517 » /* 'clear' the pin flags */ | 483 if (bp[0] == 2) {/* No more buckets in chain */ |
518 » save_bufp->flags = save_flags; | 484 hashp->cpage = NULL; |
519 | 485 hashp->cbucket++; |
520 » /* update the database cursor */ | 486 } else { |
521 » if (set) { | 487 hashp->cpage = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); |
522 » » hashp->cndx = 1; | 488 if (!hashp->cpage) |
523 » » if (bp[0] == 2) {» /* No more buckets in chain */ | 489 return (-1); |
524 » » » hashp->cpage = NULL; | 490 else if (!((uint16 *)hashp->cpage->page)[0]) { |
525 » » » hashp->cbucket++; | 491 hashp->cbucket++; |
526 » » } else { | 492 hashp->cpage = NULL; |
527 » » » hashp->cpage = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); | 493 } |
528 » » » if (!hashp->cpage) | 494 } |
529 » » » » return (-1); | 495 } |
530 » » » else if (!((uint16 *)hashp->cpage->page)[0]) { | 496 return (totlen); |
531 » » » » hashp->cbucket++; | |
532 » » » » hashp->cpage = NULL; | |
533 » » » } | |
534 » » } | |
535 » } | |
536 » return (totlen); | |
537 } | 497 } |
538 | 498 |
539 /* | 499 /* |
540 * Fill in the key and data for this big pair. | 500 * Fill in the key and data for this big pair. |
541 */ | 501 */ |
542 extern int | 502 extern int __big_keydata(HTAB *hashp, BUFHEAD *bufp, DBT *key, DBT *val, |
543 __big_keydata( | 503 int set) { |
544 » HTAB *hashp, | 504 key->size = collect_key(hashp, bufp, 0, val, set); |
545 » BUFHEAD *bufp, | 505 if (key->size == (size_t) - 1) return (-1); |
546 » DBT *key, DBT *val, | 506 key->data = (uint8 *)hashp->tmp_key; |
547 » int set) | 507 return (0); |
548 { | |
549 » key->size = collect_key(hashp, bufp, 0, val, set); | |
550 » if (key->size == (size_t)-1) | |
551 » » return (-1); | |
552 » key->data = (uint8 *)hashp->tmp_key; | |
553 » return (0); | |
554 } | 508 } |
555 | 509 |
556 /* | 510 /* |
557 * Count how big the total key size is by recursing through the pages. Then | 511 * Count how big the total key size is by recursing through the pages. Then |
558 * collect the data, allocate a buffer and copy the key as you recurse up. | 512 * collect the data, allocate a buffer and copy the key as you recurse up. |
559 */ | 513 */ |
560 static int | 514 static int collect_key(HTAB *hashp, BUFHEAD *bufp, int len, DBT *val, int set) { |
561 collect_key( | 515 BUFHEAD *xbp; |
562 » HTAB *hashp, | 516 char *p; |
563 » BUFHEAD *bufp, | 517 int mylen, totlen; |
564 » int len, | 518 uint16 *bp, save_addr; |
565 » DBT *val, | 519 |
566 » int set) | 520 p = bufp->page; |
567 { | 521 bp = (uint16 *)p; |
568 » BUFHEAD *xbp; | 522 mylen = hashp->BSIZE - bp[1]; |
569 » char *p; | 523 |
570 » int mylen, totlen; | 524 save_addr = bufp->addr; |
571 » uint16 *bp, save_addr; | 525 totlen = len + mylen; |
572 | 526 if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) {/* End of Key. */ |
573 » p = bufp->page; | 527 if (hashp->tmp_key != NULL) free(hashp->tmp_key); |
574 » bp = (uint16 *)p; | 528 if ((hashp->tmp_key = (char *)malloc((size_t)totlen)) == NULL) return (-1); |
575 » mylen = hashp->BSIZE - bp[1]; | 529 if (__big_return(hashp, bufp, 1, val, set)) return (-1); |
576 | 530 } else { |
577 » save_addr = bufp->addr; | 531 xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); |
578 » totlen = len + mylen; | 532 if (!xbp || ((totlen = collect_key(hashp, xbp, totlen, val, set)) < 1)) |
579 » if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */ | 533 return (-1); |
580 » » if (hashp->tmp_key != NULL) | 534 } |
581 » » » free(hashp->tmp_key); | 535 if (bufp->addr != save_addr) { |
582 » » if ((hashp->tmp_key = (char *)malloc((size_t)totlen)) == NULL) | 536 errno = EINVAL; /* MIS -- OUT OF BUFFERS */ |
583 » » » return (-1); | 537 return (-1); |
584 » » if (__big_return(hashp, bufp, 1, val, set)) | 538 } |
585 » » » return (-1); | 539 memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], (size_t)mylen); |
586 » } else { | 540 return (totlen); |
587 » » xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0); | |
588 » » if (!xbp || ((totlen = | |
589 » » collect_key(hashp, xbp, totlen, val, set)) < 1)) | |
590 » » » return (-1); | |
591 » } | |
592 » if (bufp->addr != save_addr) { | |
593 » » errno = EINVAL;»» /* MIS -- OUT OF BUFFERS */ | |
594 » » return (-1); | |
595 » } | |
596 » memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], (size_t)mylen); | |
597 » return (totlen); | |
598 } | 541 } |
599 | 542 |
600 /* | 543 /* |
601 * Returns: | 544 * Returns: |
602 * 0 => OK | 545 * 0 => OK |
603 * -1 => error | 546 * -1 => error |
604 */ | 547 */ |
605 extern int | 548 extern int __big_split(HTAB *hashp, |
606 __big_split( | 549 BUFHEAD *op, /* Pointer to where to put keys that go in |
607 » HTAB *hashp, | 550 old bucket */ |
608 » BUFHEAD *op,» /* Pointer to where to put keys that go in old bucket */ | 551 BUFHEAD *np, /* Pointer to new bucket page */ |
609 » BUFHEAD *np,» /* Pointer to new bucket page */ | 552 /* Pointer to first page containing the big key/data */ |
610 » » » /* Pointer to first page containing the big key/data */ | 553 BUFHEAD *big_keyp, uint32 addr, /* Address of big_keyp */ |
611 » BUFHEAD *big_keyp, | 554 uint32 obucket, /* Old Bucket */ |
612 » uint32 addr,» /* Address of big_keyp */ | 555 SPLIT_RETURN *ret) { |
613 » uint32 obucket,/* Old Bucket */ | 556 register BUFHEAD *tmpp; |
614 » SPLIT_RETURN *ret) | 557 register uint16 *tp; |
615 { | 558 BUFHEAD *bp; |
616 » register BUFHEAD *tmpp; | 559 DBT key, val; |
617 » register uint16 *tp; | 560 uint32 change; |
618 » BUFHEAD *bp; | 561 uint16 free_space, n, off; |
619 » DBT key, val; | 562 |
620 » uint32 change; | 563 bp = big_keyp; |
621 » uint16 free_space, n, off; | 564 |
622 | 565 /* Now figure out where the big key/data goes */ |
623 » bp = big_keyp; | 566 if (__big_keydata(hashp, big_keyp, &key, &val, 0)) return (-1); |
624 | 567 change = (__call_hash(hashp, (char *)key.data, key.size) != obucket); |
625 » /* Now figure out where the big key/data goes */ | 568 |
626 » if (__big_keydata(hashp, big_keyp, &key, &val, 0)) | 569 if ((ret->next_addr = __find_last_page(hashp, &big_keyp))) { |
627 » » return (-1); | 570 if (!(ret->nextp = __get_buf(hashp, ret->next_addr, big_keyp, 0))) |
628 » change = (__call_hash(hashp,(char*) key.data, key.size) != obucket); | 571 return (-1); |
629 | 572 ; |
630 » if ((ret->next_addr = __find_last_page(hashp, &big_keyp))) { | 573 } else |
631 » » if (!(ret->nextp = | 574 ret->nextp = NULL; |
632 » » __get_buf(hashp, ret->next_addr, big_keyp, 0))) | 575 |
633 » » » return (-1);; | 576 /* Now make one of np/op point to the big key/data pair */ |
634 » } else | |
635 » » ret->nextp = NULL; | |
636 | |
637 » /* Now make one of np/op point to the big key/data pair */ | |
638 #ifdef DEBUG | 577 #ifdef DEBUG |
639 » assert(np->ovfl == NULL); | 578 assert(np->ovfl == NULL); |
640 #endif | 579 #endif |
641 » if (change) | 580 if (change) |
642 » » tmpp = np; | 581 tmpp = np; |
643 » else | 582 else |
644 » » tmpp = op; | 583 tmpp = op; |
645 | 584 |
646 » tmpp->flags |= BUF_MOD; | 585 tmpp->flags |= BUF_MOD; |
647 #ifdef DEBUG1 | 586 #ifdef DEBUG1 |
648 » (void)fprintf(stderr, | 587 (void)fprintf(stderr, "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr, |
649 » "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr, | 588 (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0)); |
650 » (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0)); | |
651 #endif | 589 #endif |
652 » tmpp->ovfl = bp;» /* one of op/np point to big_keyp */ | 590 tmpp->ovfl = bp; /* one of op/np point to big_keyp */ |
653 » tp = (uint16 *)tmpp->page; | 591 tp = (uint16 *)tmpp->page; |
654 | 592 |
655 | 593 #if 0 /* this get's tripped on database corrupted error */ |
656 #if 0 /* this get's tripped on database corrupted error */ | |
657 assert(FREESPACE(tp) >= OVFLSIZE); | 594 assert(FREESPACE(tp) >= OVFLSIZE); |
658 #endif | 595 #endif |
659 » if(FREESPACE(tp) < OVFLSIZE) | 596 if (FREESPACE(tp) < OVFLSIZE) return (DATABASE_CORRUPTED_ERROR); |
660 » » return(DATABASE_CORRUPTED_ERROR); | 597 |
661 | 598 n = tp[0]; |
662 » n = tp[0]; | 599 off = OFFSET(tp); |
663 » off = OFFSET(tp); | 600 free_space = FREESPACE(tp); |
664 » free_space = FREESPACE(tp); | 601 tp[++n] = (uint16)addr; |
665 » tp[++n] = (uint16)addr; | 602 tp[++n] = OVFLPAGE; |
666 » tp[++n] = OVFLPAGE; | 603 tp[0] = n; |
667 » tp[0] = n; | 604 OFFSET(tp) = off; |
668 » OFFSET(tp) = off; | 605 FREESPACE(tp) = free_space - OVFLSIZE; |
669 » FREESPACE(tp) = free_space - OVFLSIZE; | 606 |
670 | 607 /* |
671 » /* | 608 * Finally, set the new and old return values. BIG_KEYP contains a |
672 » * Finally, set the new and old return values. BIG_KEYP contains a | 609 * pointer to the last page of the big key_data pair. Make sure that |
673 » * pointer to the last page of the big key_data pair. Make sure that | 610 * big_keyp has no following page (2 elements) or create an empty |
674 » * big_keyp has no following page (2 elements) or create an empty | 611 * following page. |
675 » * following page. | 612 */ |
676 » */ | 613 |
677 | 614 ret->newp = np; |
678 » ret->newp = np; | 615 ret->oldp = op; |
679 » ret->oldp = op; | 616 |
680 | 617 tp = (uint16 *)big_keyp->page; |
681 » tp = (uint16 *)big_keyp->page; | 618 big_keyp->flags |= BUF_MOD; |
682 » big_keyp->flags |= BUF_MOD; | 619 if (tp[0] > 2) { |
683 » if (tp[0] > 2) { | 620 /* |
684 » » /* | 621 * There may be either one or two offsets on this page. If |
685 » » * There may be either one or two offsets on this page. If | 622 * there is one, then the overflow page is linked on normally |
686 » » * there is one, then the overflow page is linked on normally | 623 * and tp[4] is OVFLPAGE. If there are two, tp[4] contains |
687 » » * and tp[4] is OVFLPAGE. If there are two, tp[4] contains | 624 * the second offset and needs to get stuffed in after the |
688 » » * the second offset and needs to get stuffed in after the | 625 * next overflow page is added. |
689 » » * next overflow page is added. | 626 */ |
690 » » */ | 627 n = tp[4]; |
691 » » n = tp[4]; | 628 free_space = FREESPACE(tp); |
692 » » free_space = FREESPACE(tp); | 629 off = OFFSET(tp); |
693 » » off = OFFSET(tp); | 630 tp[0] -= 2; |
694 » » tp[0] -= 2; | 631 FREESPACE(tp) = free_space + OVFLSIZE; |
695 » » FREESPACE(tp) = free_space + OVFLSIZE; | 632 OFFSET(tp) = off; |
696 » » OFFSET(tp) = off; | 633 tmpp = __add_ovflpage(hashp, big_keyp); |
697 » » tmpp = __add_ovflpage(hashp, big_keyp); | 634 if (!tmpp) return (-1); |
698 » » if (!tmpp) | 635 tp[4] = n; |
699 » » » return (-1); | 636 } else |
700 » » tp[4] = n; | 637 tmpp = big_keyp; |
701 » } else | 638 |
702 » » tmpp = big_keyp; | 639 if (change) |
703 | 640 ret->newp = tmpp; |
704 » if (change) | 641 else |
705 » » ret->newp = tmpp; | 642 ret->oldp = tmpp; |
706 » else | 643 return (0); |
707 » » ret->oldp = tmpp; | 644 } |
708 » return (0); | |
709 } | |
OLD | NEW |