1 /*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)rec_get.c 8.4 (Berkeley) 03/01/94";
10 #endif /* LIBC_SCCS and not lint */
11
12 #include <sys/types.h>
13
14 #include <errno.h>
15 #include <stddef.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20
21 #include <db.h>
22 #include "recno.h"
23
24 /*
25 * __REC_GET -- Get a record from the btree.
26 *
27 * Parameters:
28 * dbp: pointer to access method
29 * key: key to find
30 * data: data to return
31 * flag: currently unused
32 *
33 * Returns:
34 * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
35 */
36 int
__rec_get(dbp,key,data,flags)37 __rec_get(dbp, key, data, flags)
38 const DB *dbp;
39 const DBT *key;
40 DBT *data;
41 u_int flags;
42 {
43 BTREE *t;
44 EPG *e;
45 recno_t nrec;
46 int status;
47
48 t = dbp->internal;
49
50 /* Toss any page pinned across calls. */
51 if (t->bt_pinned != NULL) {
52 mpool_put(t->bt_mp, t->bt_pinned, 0);
53 t->bt_pinned = NULL;
54 }
55
56 /* Get currently doesn't take any flags, and keys of 0 are illegal. */
57 if (flags || (nrec = *(recno_t *)key->data) == 0) {
58 errno = EINVAL;
59 return (RET_ERROR);
60 }
61
62 /*
63 * If we haven't seen this record yet, try to find it in the
64 * original file.
65 */
66 if (nrec > t->bt_nrecs) {
67 if (ISSET(t, R_EOF | R_INMEM))
68 return (RET_SPECIAL);
69 if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
70 return (status);
71 }
72
73 --nrec;
74 if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
75 return (RET_ERROR);
76
77 status = __rec_ret(t, e, 0, NULL, data);
78 if (ISSET(t, B_DB_LOCK))
79 mpool_put(t->bt_mp, e->page, 0);
80 else
81 t->bt_pinned = e->page;
82 return (status);
83 }
84
85 /*
86 * __REC_FPIPE -- Get fixed length records from a pipe.
87 *
88 * Parameters:
89 * t: tree
90 * cnt: records to read
91 *
92 * Returns:
93 * RET_ERROR, RET_SUCCESS
94 */
95 int
__rec_fpipe(t,top)96 __rec_fpipe(t, top)
97 BTREE *t;
98 recno_t top;
99 {
100 DBT data;
101 recno_t nrec;
102 size_t len;
103 int ch;
104 char *p;
105
106 if (t->bt_dbufsz < t->bt_reclen) {
107 if ((t->bt_dbuf =
108 (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
109 return (RET_ERROR);
110 t->bt_dbufsz = t->bt_reclen;
111 }
112 data.data = t->bt_dbuf;
113 data.size = t->bt_reclen;
114
115 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
116 len = t->bt_reclen;
117 for (p = t->bt_dbuf;; *p++ = ch)
118 if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
119 if (__rec_iput(t, nrec, &data, 0)
120 != RET_SUCCESS)
121 return (RET_ERROR);
122 break;
123 }
124 if (ch == EOF)
125 break;
126 }
127 if (nrec < top) {
128 SET(t, R_EOF);
129 return (RET_SPECIAL);
130 }
131 return (RET_SUCCESS);
132 }
133
134 /*
135 * __REC_VPIPE -- Get variable length records from a pipe.
136 *
137 * Parameters:
138 * t: tree
139 * cnt: records to read
140 *
141 * Returns:
142 * RET_ERROR, RET_SUCCESS
143 */
144 int
__rec_vpipe(t,top)145 __rec_vpipe(t, top)
146 BTREE *t;
147 recno_t top;
148 {
149 DBT data;
150 recno_t nrec;
151 indx_t len;
152 size_t sz;
153 int bval, ch;
154 char *p;
155
156 bval = t->bt_bval;
157 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
158 for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
159 if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
160 data.data = t->bt_dbuf;
161 data.size = p - t->bt_dbuf;
162 if (ch == EOF && data.size == 0)
163 break;
164 if (__rec_iput(t, nrec, &data, 0)
165 != RET_SUCCESS)
166 return (RET_ERROR);
167 break;
168 }
169 if (sz == 0) {
170 len = p - t->bt_dbuf;
171 t->bt_dbufsz += (sz = 256);
172 if ((t->bt_dbuf = (char *)realloc(t->bt_dbuf,
173 t->bt_dbufsz)) == NULL)
174 return (RET_ERROR);
175 p = t->bt_dbuf + len;
176 }
177 }
178 if (ch == EOF)
179 break;
180 }
181 if (nrec < top) {
182 SET(t, R_EOF);
183 return (RET_SPECIAL);
184 }
185 return (RET_SUCCESS);
186 }
187
188 /*
189 * __REC_FMAP -- Get fixed length records from a file.
190 *
191 * Parameters:
192 * t: tree
193 * cnt: records to read
194 *
195 * Returns:
196 * RET_ERROR, RET_SUCCESS
197 */
198 int
__rec_fmap(t,top)199 __rec_fmap(t, top)
200 BTREE *t;
201 recno_t top;
202 {
203 DBT data;
204 recno_t nrec;
205 caddr_t sp, ep;
206 size_t len;
207 char *p;
208
209 if (t->bt_dbufsz < t->bt_reclen) {
210 if ((t->bt_dbuf =
211 (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
212 return (RET_ERROR);
213 t->bt_dbufsz = t->bt_reclen;
214 }
215 data.data = t->bt_dbuf;
216 data.size = t->bt_reclen;
217
218 sp = t->bt_cmap;
219 ep = t->bt_emap;
220 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
221 if (sp >= ep) {
222 SET(t, R_EOF);
223 return (RET_SPECIAL);
224 }
225 len = t->bt_reclen;
226 for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
227 memset(p, t->bt_bval, len);
228 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
229 return (RET_ERROR);
230 }
231 t->bt_cmap = sp;
232 return (RET_SUCCESS);
233 }
234
235 /*
236 * __REC_VMAP -- Get variable length records from a file.
237 *
238 * Parameters:
239 * t: tree
240 * cnt: records to read
241 *
242 * Returns:
243 * RET_ERROR, RET_SUCCESS
244 */
245 int
__rec_vmap(t,top)246 __rec_vmap(t, top)
247 BTREE *t;
248 recno_t top;
249 {
250 DBT data;
251 caddr_t sp, ep;
252 recno_t nrec;
253 int bval;
254
255 sp = t->bt_cmap;
256 ep = t->bt_emap;
257 bval = t->bt_bval;
258
259 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
260 if (sp >= ep) {
261 SET(t, R_EOF);
262 return (RET_SPECIAL);
263 }
264 for (data.data = sp; sp < ep && *sp != bval; ++sp);
265 data.size = sp - (caddr_t)data.data;
266 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
267 return (RET_ERROR);
268 ++sp;
269 }
270 t->bt_cmap = sp;
271 return (RET_SUCCESS);
272 }
273