Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

772 ADatabase Library Chapter 20


502 /*
503 * Write an index record. _db_writedat is called before
504 * this function to set the datoff and datlen fields in the
505 * DB structure, which we need to write the index record.
506 */
507 static void
508 _db_writeidx(DB *db, const char *key,
509 off_t offset, int whence, off_t ptrval)
510 {
511 struct iovec iov[2];
512 char asciiptrlen[PTR_SZ + IDXLEN_SZ + 1];
513 int len;
514 if ((db->ptrval = ptrval) < 0 || ptrval > PTR_MAX)
515 err_quit("_db_writeidx: invalid ptr: %d", ptrval);
516 sprintf(db->idxbuf, "%s%c%lld%c%ld\n", key, SEP,
517 (long long)db->datoff, SEP, (long)db->datlen);
518 len=strlen(db->idxbuf);
519 if (len < IDXLEN_MIN || len > IDXLEN_MAX)
520 err_dump("_db_writeidx: invalid length");
521 sprintf(asciiptrlen, "%*lld%*d", PTR_SZ, (long long)ptrval,
522 IDXLEN_SZ, len);
523 /*
524 * If we’re appending, we have to lock before doing the lseek
525 * and write to make the two an atomic operation. If we’re
526 * overwriting an existing record, we don’t have to lock.
527 */
528 if (whence == SEEK_END) /* we’re appending */
529 if (writew_lock(db->idxfd, ((db->nhash+1)*PTR_SZ)+1,
530 SEEK_SET, 0) < 0)
531 err_dump("_db_writeidx: writew_lock error");

[502 – 522] The_db_writeidx function is called to write an index record. After
validating the next pointer in the chain, we create the index recordand store
the second half of it inidxbuf.Weneed the size of this portion of the index
record to create the first half of the index record, which we store in the local
variableasciiptrlen.
Note that we use casts to force the size of the arguments in thesprintf
statements to match the format specifications. This is because the size of the
off_tandsize_tdata types can vary among platforms. Even a 32-bit
system can provide 64-bit file offsets, so we can’t make any assumptions
about the size of theoff_tdata type.
[523 – 531] As with_db_writedat,this function deals with locking only when a new
index record is being appended to the index file. When_db_dodelete
calls this function, we’rerewriting an existing index record. In this case, the
caller has write locked the hash chain, so no additional locking is required.
Free download pdf