ptg10805159
Section 20.8 Source Code 767
348 /*
349 * Now read the actual index record. We read it into the key
350 * buffer that we malloced when we opened the database.
351 */
352 if ((i = read(db->idxfd, db->idxbuf, db->idxlen)) != db->idxlen)
353 err_dump("_db_readidx: read error of index record");
354 if (db->idxbuf[db->idxlen-1] != NEWLINE) /* sanity check */
355 err_dump("_db_readidx: missing newline");
356 db->idxbuf[db->idxlen-1]=0;/*replace newline with null */
357 /*
358 * Find the separators in the index record.
359 */
360 if ((ptr1 = strchr(db->idxbuf, SEP)) == NULL)
361 err_dump("_db_readidx: missing first separator");
362 *ptr1++=0;/*replace SEP with null */
363 if ((ptr2 = strchr(ptr1, SEP)) == NULL)
364 err_dump("_db_readidx: missing second separator");
365 *ptr2++=0;/*replace SEP with null */
366 if (strchr(ptr2, SEP) != NULL)
367 err_dump("_db_readidx: too many separators");
368 /*
369 * Get the starting offset and length of the data record.
370 */
371 if ((db->datoff = atol(ptr1)) < 0)
372 err_dump("_db_readidx: starting offset < 0");
373 if ((db->datlen = atol(ptr2)) <= 0 || db->datlen > DATLEN_MAX)
374 err_dump("_db_readidx: invalid length");
375 return(db->ptrval); /* return offset of next key in chain */
376 }
[348 – 356] We read the variable-length index recordinto theidxbuffield in theDB
structure. Therecordshould be terminated with a newline, which we
replace with a null byte. If the index file is corrupt, we terminate and drop
core by callingerr_dump.
[357 – 367] We separate the index recordinto three fields: the key,the offset of the
corresponding data record, and the length of the data record. Thestrchr
function finds the first occurrence of the specified character in the given
string. Here we look for the character that separates fields in the record
(SEP,which we define to be a colon).
[368 – 376] We convert the data recordoffset and length into integers and storethem in
theDBstructure. Then we return the offset of the next record in the hash
chain. Note that we do not read the data record; that task is left to the caller.
In thedb_fetchfunction, for example, we don’t read the data recorduntil
_db_find_and_lockhas read the index recordthat matches the key that
we’relooking for.