⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 store.c

📁 unix高级编程源代码.<<unix高级编程>>
💻 C
字号:
#include	"db.h"

/* Store a record in the database.
 * Return 0 if OK, 1 if record exists and DB_INSERT specified,
 * -1 if record doesn't exist and DB_REPLACE specified. */

int
db_store(DB *db, const char *key, const char *data, int flag)
{
	int		rc, keylen, datlen;
	off_t	ptrval;

	keylen = strlen(key);
	datlen = strlen(data) + 1;		/* +1 for newline at end */
	if (datlen < DATLEN_MIN || datlen > DATLEN_MAX)
		err_dump("invalid data length");

		/* _db_find() calculates which hash table this new record
		   goes into (db->chainoff), regardless whether it already
		   exists or not.  The calls to _db_writeptr() below
		   change the hash table entry for this chain to point to
		   the new record.  This means the new record is added to
		   the front of the hash chain. */

	if (_db_find(db, key, 1) < 0) {		/* record not found */
		if (flag & DB_REPLACE) {
			rc = -1;
			db->cnt_storerr++;
			goto doreturn;		/* error, record does not exist */
		}

			/* _db_find() locked the hash chain for us; read the
			   chain ptr to the first index record on hash chain */
		ptrval = _db_readptr(db, db->chainoff);

		if (_db_findfree(db, keylen, datlen) < 0) {
				/* An empty record of the correct size was not found.
				   We have to append the new record to the ends of
				   the index and data files */
			_db_writedat(db, data, 0, SEEK_END);
			_db_writeidx(db, key, 0, SEEK_END, ptrval);
				/* db->idxoff was set by _db_writeidx().  The new
				   record goes to the front of the hash chain. */
			_db_writeptr(db, db->chainoff, db->idxoff);
			db->cnt_stor1++;
		} else {
				/* We can reuse an empty record.
				   _db_findfree() removed the record from the free
				   list and set both db->datoff and db->idxoff. */
			_db_writedat(db, data, db->datoff, SEEK_SET);
			_db_writeidx(db, key, db->idxoff, SEEK_SET, ptrval);
				/* reused record goes to the front of the hash chain. */
			_db_writeptr(db, db->chainoff, db->idxoff);
			db->cnt_stor2++;
		}

	} else {						/* record found */
		if (flag & DB_INSERT) {
			rc = 1;
			db->cnt_storerr++;
			goto doreturn;		/* error, record already in db */
		}

			/* We are replacing an existing record.  We know the new
			   key equals the existing key, but we need to check if
			   the data records are the same size. */
		if (datlen != db->datlen) {
			_db_dodelete(db);	/* delete the existing record */

				/* Reread the chain ptr in the hash table
				   (it may change with the deletion). */
			ptrval = _db_readptr(db, db->chainoff);

				/* append new index and data records to end of files */
			_db_writedat(db, data, 0, SEEK_END);
			_db_writeidx(db, key, 0, SEEK_END, ptrval);
				/* new record goes to the front of the hash chain. */
			_db_writeptr(db, db->chainoff, db->idxoff);
			db->cnt_stor3++;

		} else {
				/* same size data, just replace data record */
			_db_writedat(db, data, db->datoff, SEEK_SET);
			db->cnt_stor4++;
		}
	}
	rc = 0;		/* OK */
doreturn:	/* unlock the hash chain that _db_find() locked */
	if (un_lock(db->idxfd, db->chainoff, SEEK_SET, 1) < 0)
		err_dump("un_lock error");
	return(rc);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -