logrec.html   [plain text]


<!--$Id: logrec.so,v 10.31 2004/08/05 14:16:56 bostic Exp $-->
<!--Copyright (c) 1997,2008 Oracle.  All rights reserved.-->
<!--See the file LICENSE for redistribution information.-->
<html>
<head>
<title>Berkeley DB Reference Guide: Logical record numbers</title>
<meta name="description" content="Berkeley DB: An embedded database programmatic toolkit.">
<meta name="keywords" content="embedded,database,programmatic,toolkit,btree,hash,hashing,transaction,transactions,locking,logging,access method,access methods,Java,C,C++">
</head>
<body bgcolor=white>
<a name="2"><!--meow--></a>
<table width="100%"><tr valign=top>
<td><b><dl><dt>Berkeley DB Reference Guide:<dd>Access Methods</dl></b></td>
<td align=right><a href="../am_conf/select.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../toc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../am_conf/pagesize.html"><img src="../../images/next.gif" alt="Next"></a>
</td></tr></table>
<p align=center><b>Logical record numbers</b></p>
<p>The Berkeley DB Btree, Queue and Recno access methods can operate on logical
record numbers.  Record numbers are 1-based, not 0-based, that is, the
first record in a database is record number 1.</p>
<p>In all cases for the Queue and Recno access methods, and when calling
the Btree access method using the <a href="../../api_c/db_get.html">DB-&gt;get</a> and <a href="../../api_c/dbc_get.html">DBcursor-&gt;get</a> methods
with the <a href="../../api_c/db_get.html#DB_SET_RECNO">DB_SET_RECNO</a> flag specified, the <b>data</b> field of
the key <a href="../../api_c/dbt_class.html">DBT</a> must be a pointer to a memory location of type
<b>db_recno_t</b>, as typedef'd in the standard Berkeley DB include file.
The <b>size</b> field of the key <a href="../../api_c/dbt_class.html">DBT</a> should be the size of that
type (for example, "sizeof(db_recno_t)" in the C programming language).
The <b>db_recno_t</b> type is a 32-bit unsigned type, which limits the
number of logical records in a Queue or Recno database, and the maximum
logical record which may be directly retrieved from a Btree database,
to 4,294,967,295.</p>
<p>Record numbers in Recno databases can be configured to run in either
mutable or fixed mode: mutable, where logical record numbers change as
records are deleted or inserted, and fixed, where record numbers never
change regardless of the database operation.  Record numbers in Queue
databases are always fixed, and never change regardless of the database
operation.  Record numbers in Btree databases are always mutable, and
as records are deleted or inserted, the logical record number for other
records in the database can change.  See
<a href="../../ref/am_conf/renumber.html">Logically renumbering records</a>
for more information.</p>
<p>When appending new data items into Queue databases, record numbers wrap
around.  When the tail of the queue reaches the maximum record number,
the next record appended will be given record number 1.  If the head of
the queue ever catches up to the tail of the queue, Berkeley DB will return
the system error EFBIG.  Record numbers do not wrap around when appending
new data items into Recno databases.</p>
<p>Configuring Btree databases to support record numbers can severely limit
the throughput of applications with multiple concurrent threads writing
the database, because locations used to store record counts often become
hot spots that many different threads all need to update.  In the case
of a Btree supporting duplicate data items, the logical record number
refers to a key and all of its data items, as duplicate data items are
not individually numbered.</p>
<p>The following is an example function that reads records from standard
input and stores them into a Recno database.  The function then uses a
cursor to step through the database and display the stored records.</p>
<blockquote><pre>int
recno_build(dbp)
	DB *dbp;
{
	DBC *dbcp;
	DBT key, data;
	db_recno_t recno;
	u_int32_t len;
	int ret;
	char buf[1024];
<p>
	/* Insert records into the database. */
	memset(&key, 0, sizeof(DBT));
	memset(&data, 0, sizeof(DBT));
	for (recno = 1;; ++recno) {
		printf("record #%lu&gt; ", (u_long)recno);
		fflush(stdout);
		if (fgets(buf, sizeof(buf), stdin) == NULL)
			break;
		if ((len = strlen(buf)) &lt;= 1)
			continue;
<p>
		key.data = &recno;
		key.size = sizeof(recno);
		data.data = buf;
		data.size = len - 1;
<p>
		switch (ret = dbp-&gt;put(dbp, NULL, &key, &data, 0)) {
		case 0:
			break;
		default:
			dbp-&gt;err(dbp, ret, "DB-&gt;put");
			break;
		}
	}
	printf("\n");
<p>
	/* Acquire a cursor for the database. */
	if ((ret = dbp-&gt;cursor(dbp, NULL, &dbcp, 0)) != 0) {
		dbp-&gt;err(dbp, ret, "DB-&gt;cursor");
		return (1);
	}
<p>
	/* Re-initialize the key/data pair. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
<p>
	/* Walk through the database and print out the key/data pairs. */
	while ((ret = dbcp-&gt;c_get(dbcp, &key, &data, DB_NEXT)) == 0)
		printf("%lu : %.*s\n",
		    *(u_long *)key.data, (int)data.size, (char *)data.data);
	if (ret != DB_NOTFOUND)
		dbp-&gt;err(dbp, ret, "DBcursor-&gt;get");
<p>
	/* Close the cursor. */
	if ((ret = dbcp-&gt;c_close(dbcp)) != 0) {
		dbp-&gt;err(dbp, ret, "DBcursor-&gt;close");
		return (1);
	}
	return (0);
}</pre></blockquote>
<table width="100%"><tr><td><br></td><td align=right><a href="../am_conf/select.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../toc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../am_conf/pagesize.html"><img src="../../images/next.gif" alt="Next"></a>
</td></tr></table>
<p><font size=1>Copyright (c) 1996,2008 Oracle.  All rights reserved.</font>
</body>
</html>