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 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 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 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 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 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