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.2 (Berkeley) 09/07/93"; 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 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 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 data.data = t->bt_dbuf; 107 data.size = t->bt_reclen; 108 109 if (t->bt_dbufsz < t->bt_reclen) { 110 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 111 return (RET_ERROR); 112 t->bt_dbufsz = t->bt_reclen; 113 } 114 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 115 len = t->bt_reclen; 116 for (p = t->bt_dbuf;; *p++ = ch) 117 if ((ch = getc(t->bt_rfp)) == EOF || !len--) { 118 if (__rec_iput(t, nrec, &data, 0) 119 != RET_SUCCESS) 120 return (RET_ERROR); 121 break; 122 } 123 if (ch == EOF) 124 break; 125 } 126 if (nrec < top) { 127 SET(t, R_EOF); 128 return (RET_SPECIAL); 129 } 130 return (RET_SUCCESS); 131 } 132 133 /* 134 * __REC_VPIPE -- Get variable length records from a pipe. 135 * 136 * Parameters: 137 * t: tree 138 * cnt: records to read 139 * 140 * Returns: 141 * RET_ERROR, RET_SUCCESS 142 */ 143 int 144 __rec_vpipe(t, top) 145 BTREE *t; 146 recno_t top; 147 { 148 DBT data; 149 recno_t nrec; 150 indx_t len; 151 size_t sz; 152 int bval, ch; 153 char *p; 154 155 bval = t->bt_bval; 156 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 157 for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) { 158 if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { 159 data.data = t->bt_dbuf; 160 data.size = p - t->bt_dbuf; 161 if (ch == EOF && data.size == 0) 162 break; 163 if (__rec_iput(t, nrec, &data, 0) 164 != RET_SUCCESS) 165 return (RET_ERROR); 166 break; 167 } 168 if (sz == 0) { 169 len = p - t->bt_dbuf; 170 t->bt_dbufsz += (sz = 256); 171 if ((t->bt_dbuf = 172 realloc(t->bt_dbuf, t->bt_dbufsz)) == NULL) 173 return (RET_ERROR); 174 p = t->bt_dbuf + len; 175 } 176 } 177 if (ch == EOF) 178 break; 179 } 180 if (nrec < top) { 181 SET(t, R_EOF); 182 return (RET_SPECIAL); 183 } 184 return (RET_SUCCESS); 185 } 186 187 /* 188 * __REC_FMAP -- Get fixed length records from a file. 189 * 190 * Parameters: 191 * t: tree 192 * cnt: records to read 193 * 194 * Returns: 195 * RET_ERROR, RET_SUCCESS 196 */ 197 int 198 __rec_fmap(t, top) 199 BTREE *t; 200 recno_t top; 201 { 202 DBT data; 203 recno_t nrec; 204 caddr_t sp, ep; 205 size_t len; 206 char *p; 207 208 sp = t->bt_cmap; 209 ep = t->bt_emap; 210 data.data = t->bt_dbuf; 211 data.size = t->bt_reclen; 212 213 if (t->bt_dbufsz < t->bt_reclen) { 214 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 215 return (RET_ERROR); 216 t->bt_dbufsz = t->bt_reclen; 217 } 218 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 219 if (sp >= ep) { 220 SET(t, R_EOF); 221 return (RET_SPECIAL); 222 } 223 len = t->bt_reclen; 224 for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++); 225 memset(p, t->bt_bval, len); 226 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 227 return (RET_ERROR); 228 } 229 t->bt_cmap = sp; 230 return (RET_SUCCESS); 231 } 232 233 /* 234 * __REC_VMAP -- Get variable length records from a file. 235 * 236 * Parameters: 237 * t: tree 238 * cnt: records to read 239 * 240 * Returns: 241 * RET_ERROR, RET_SUCCESS 242 */ 243 int 244 __rec_vmap(t, top) 245 BTREE *t; 246 recno_t top; 247 { 248 DBT data; 249 caddr_t sp, ep; 250 recno_t nrec; 251 int bval; 252 253 sp = t->bt_cmap; 254 ep = t->bt_emap; 255 bval = t->bt_bval; 256 257 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 258 if (sp >= ep) { 259 SET(t, R_EOF); 260 return (RET_SPECIAL); 261 } 262 for (data.data = sp; sp < ep && *sp != bval; ++sp); 263 data.size = sp - (caddr_t)data.data; 264 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 265 return (RET_ERROR); 266 ++sp; 267 } 268 t->bt_cmap = sp; 269 return (RET_SUCCESS); 270 } 271