rec_get.c revision 1.8 1 /* $NetBSD: rec_get.c,v 1.8 1996/05/03 21:38:48 cgd Exp $ */
2
3 /*-
4 * Copyright (c) 1990, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #if defined(LIBC_SCCS) && !defined(lint)
37 #if 0
38 static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94";
39 #else
40 static char rcsid[] = "$NetBSD: rec_get.c,v 1.8 1996/05/03 21:38:48 cgd Exp $";
41 #endif
42 #endif /* LIBC_SCCS and not lint */
43
44 #include <sys/types.h>
45
46 #include <errno.h>
47 #include <stddef.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <unistd.h>
52
53 #include <db.h>
54 #include "recno.h"
55
56 /*
57 * __REC_GET -- Get a record from the btree.
58 *
59 * Parameters:
60 * dbp: pointer to access method
61 * key: key to find
62 * data: data to return
63 * flag: currently unused
64 *
65 * Returns:
66 * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
67 */
68 int
69 __rec_get(dbp, key, data, flags)
70 const DB *dbp;
71 const DBT *key;
72 DBT *data;
73 u_int flags;
74 {
75 BTREE *t;
76 EPG *e;
77 recno_t nrec;
78 int status;
79
80 t = dbp->internal;
81
82 /* Toss any page pinned across calls. */
83 if (t->bt_pinned != NULL) {
84 mpool_put(t->bt_mp, t->bt_pinned, 0);
85 t->bt_pinned = NULL;
86 }
87
88 /* Get currently doesn't take any flags, and keys of 0 are illegal. */
89 if (flags || (nrec = *(recno_t *)key->data) == 0) {
90 errno = EINVAL;
91 return (RET_ERROR);
92 }
93
94 /*
95 * If we haven't seen this record yet, try to find it in the
96 * original file.
97 */
98 if (nrec > t->bt_nrecs) {
99 if (F_ISSET(t, R_EOF | R_INMEM))
100 return (RET_SPECIAL);
101 if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
102 return (status);
103 }
104
105 --nrec;
106 if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
107 return (RET_ERROR);
108
109 status = __rec_ret(t, e, 0, NULL, data);
110 if (F_ISSET(t, B_DB_LOCK))
111 mpool_put(t->bt_mp, e->page, 0);
112 else
113 t->bt_pinned = e->page;
114 return (status);
115 }
116
117 /*
118 * __REC_FPIPE -- Get fixed length records from a pipe.
119 *
120 * Parameters:
121 * t: tree
122 * cnt: records to read
123 *
124 * Returns:
125 * RET_ERROR, RET_SUCCESS
126 */
127 int
128 __rec_fpipe(t, top)
129 BTREE *t;
130 recno_t top;
131 {
132 DBT data;
133 recno_t nrec;
134 size_t len;
135 int ch;
136 u_char *p;
137
138 if (t->bt_rdata.size < t->bt_reclen) {
139 t->bt_rdata.data = t->bt_rdata.data == NULL ?
140 malloc(t->bt_reclen) :
141 realloc(t->bt_rdata.data, t->bt_reclen);
142 if (t->bt_rdata.data == NULL)
143 return (RET_ERROR);
144 t->bt_rdata.size = t->bt_reclen;
145 }
146 data.data = t->bt_rdata.data;
147 data.size = t->bt_reclen;
148
149 for (nrec = t->bt_nrecs; nrec < top;) {
150 len = t->bt_reclen;
151 for (p = t->bt_rdata.data;; *p++ = ch)
152 if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
153 if (ch != EOF)
154 *p = ch;
155 if (len != 0)
156 memset(p, t->bt_bval, len);
157 if (__rec_iput(t,
158 nrec, &data, 0) != RET_SUCCESS)
159 return (RET_ERROR);
160 ++nrec;
161 break;
162 }
163 if (ch == EOF)
164 break;
165 }
166 if (nrec < top) {
167 F_SET(t, R_EOF);
168 return (RET_SPECIAL);
169 }
170 return (RET_SUCCESS);
171 }
172
173 /*
174 * __REC_VPIPE -- Get variable length records from a pipe.
175 *
176 * Parameters:
177 * t: tree
178 * cnt: records to read
179 *
180 * Returns:
181 * RET_ERROR, RET_SUCCESS
182 */
183 int
184 __rec_vpipe(t, top)
185 BTREE *t;
186 recno_t top;
187 {
188 DBT data;
189 recno_t nrec;
190 indx_t len;
191 size_t sz;
192 int bval, ch;
193 u_char *p;
194
195 bval = t->bt_bval;
196 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
197 for (p = t->bt_rdata.data,
198 sz = t->bt_rdata.size;; *p++ = ch, --sz) {
199 if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
200 data.data = t->bt_rdata.data;
201 data.size = p - (u_char *)t->bt_rdata.data;
202 if (ch == EOF && data.size == 0)
203 break;
204 if (__rec_iput(t, nrec, &data, 0)
205 != RET_SUCCESS)
206 return (RET_ERROR);
207 break;
208 }
209 if (sz == 0) {
210 len = p - (u_char *)t->bt_rdata.data;
211 t->bt_rdata.size += (sz = 256);
212 t->bt_rdata.data = t->bt_rdata.data == NULL ?
213 malloc(t->bt_rdata.size) :
214 realloc(t->bt_rdata.data, t->bt_rdata.size);
215 if (t->bt_rdata.data == NULL)
216 return (RET_ERROR);
217 p = (u_char *)t->bt_rdata.data + len;
218 }
219 }
220 if (ch == EOF)
221 break;
222 }
223 if (nrec < top) {
224 F_SET(t, R_EOF);
225 return (RET_SPECIAL);
226 }
227 return (RET_SUCCESS);
228 }
229
230 /*
231 * __REC_FMAP -- Get fixed length records from a file.
232 *
233 * Parameters:
234 * t: tree
235 * cnt: records to read
236 *
237 * Returns:
238 * RET_ERROR, RET_SUCCESS
239 */
240 int
241 __rec_fmap(t, top)
242 BTREE *t;
243 recno_t top;
244 {
245 DBT data;
246 recno_t nrec;
247 u_char *sp, *ep, *p;
248 size_t len;
249
250 if (t->bt_rdata.size < t->bt_reclen) {
251 t->bt_rdata.data = t->bt_rdata.data == NULL ?
252 malloc(t->bt_reclen) :
253 realloc(t->bt_rdata.data, t->bt_reclen);
254 if (t->bt_rdata.data == NULL)
255 return (RET_ERROR);
256 t->bt_rdata.size = t->bt_reclen;
257 }
258 data.data = t->bt_rdata.data;
259 data.size = t->bt_reclen;
260
261 sp = (u_char *)t->bt_cmap;
262 ep = (u_char *)t->bt_emap;
263 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
264 if (sp >= ep) {
265 F_SET(t, R_EOF);
266 return (RET_SPECIAL);
267 }
268 len = t->bt_reclen;
269 for (p = t->bt_rdata.data;
270 sp < ep && len > 0; *p++ = *sp++, --len);
271 if (len != 0)
272 memset(p, t->bt_bval, len);
273 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
274 return (RET_ERROR);
275 }
276 t->bt_cmap = (caddr_t)sp;
277 return (RET_SUCCESS);
278 }
279
280 /*
281 * __REC_VMAP -- Get variable length records from a file.
282 *
283 * Parameters:
284 * t: tree
285 * cnt: records to read
286 *
287 * Returns:
288 * RET_ERROR, RET_SUCCESS
289 */
290 int
291 __rec_vmap(t, top)
292 BTREE *t;
293 recno_t top;
294 {
295 DBT data;
296 u_char *sp, *ep;
297 recno_t nrec;
298 int bval;
299
300 sp = (u_char *)t->bt_cmap;
301 ep = (u_char *)t->bt_emap;
302 bval = t->bt_bval;
303
304 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
305 if (sp >= ep) {
306 F_SET(t, R_EOF);
307 return (RET_SPECIAL);
308 }
309 for (data.data = sp; sp < ep && *sp != bval; ++sp);
310 data.size = sp - (u_char *)data.data;
311 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
312 return (RET_ERROR);
313 ++sp;
314 }
315 t->bt_cmap = (caddr_t)sp;
316 return (RET_SUCCESS);
317 }
318