1<!--$Id: logrec.so,v 10.31 2004/08/05 14:16:56 bostic Exp $-->
2<!--Copyright (c) 1997,2008 Oracle.  All rights reserved.-->
3<!--See the file LICENSE for redistribution information.-->
4<html>
5<head>
6<title>Berkeley DB Reference Guide: Logical record numbers</title>
7<meta name="description" content="Berkeley DB: An embedded database programmatic toolkit.">
8<meta name="keywords" content="embedded,database,programmatic,toolkit,btree,hash,hashing,transaction,transactions,locking,logging,access method,access methods,Java,C,C++">
9</head>
10<body bgcolor=white>
11<a name="2"><!--meow--></a>
12<table width="100%"><tr valign=top>
13<td><b><dl><dt>Berkeley DB Reference Guide:<dd>Access Methods</dl></b></td>
14<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>
15</td></tr></table>
16<p align=center><b>Logical record numbers</b></p>
17<p>The Berkeley DB Btree, Queue and Recno access methods can operate on logical
18record numbers.  Record numbers are 1-based, not 0-based, that is, the
19first record in a database is record number 1.</p>
20<p>In all cases for the Queue and Recno access methods, and when calling
21the 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
22with the <a href="../../api_c/db_get.html#DB_SET_RECNO">DB_SET_RECNO</a> flag specified, the <b>data</b> field of
23the key <a href="../../api_c/dbt_class.html">DBT</a> must be a pointer to a memory location of type
24<b>db_recno_t</b>, as typedef'd in the standard Berkeley DB include file.
25The <b>size</b> field of the key <a href="../../api_c/dbt_class.html">DBT</a> should be the size of that
26type (for example, "sizeof(db_recno_t)" in the C programming language).
27The <b>db_recno_t</b> type is a 32-bit unsigned type, which limits the
28number of logical records in a Queue or Recno database, and the maximum
29logical record which may be directly retrieved from a Btree database,
30to 4,294,967,295.</p>
31<p>Record numbers in Recno databases can be configured to run in either
32mutable or fixed mode: mutable, where logical record numbers change as
33records are deleted or inserted, and fixed, where record numbers never
34change regardless of the database operation.  Record numbers in Queue
35databases are always fixed, and never change regardless of the database
36operation.  Record numbers in Btree databases are always mutable, and
37as records are deleted or inserted, the logical record number for other
38records in the database can change.  See
39<a href="../../ref/am_conf/renumber.html">Logically renumbering records</a>
40for more information.</p>
41<p>When appending new data items into Queue databases, record numbers wrap
42around.  When the tail of the queue reaches the maximum record number,
43the next record appended will be given record number 1.  If the head of
44the queue ever catches up to the tail of the queue, Berkeley DB will return
45the system error EFBIG.  Record numbers do not wrap around when appending
46new data items into Recno databases.</p>
47<p>Configuring Btree databases to support record numbers can severely limit
48the throughput of applications with multiple concurrent threads writing
49the database, because locations used to store record counts often become
50hot spots that many different threads all need to update.  In the case
51of a Btree supporting duplicate data items, the logical record number
52refers to a key and all of its data items, as duplicate data items are
53not individually numbered.</p>
54<p>The following is an example function that reads records from standard
55input and stores them into a Recno database.  The function then uses a
56cursor to step through the database and display the stored records.</p>
57<blockquote><pre>int
58recno_build(dbp)
59	DB *dbp;
60{
61	DBC *dbcp;
62	DBT key, data;
63	db_recno_t recno;
64	u_int32_t len;
65	int ret;
66	char buf[1024];
67<p>
68	/* Insert records into the database. */
69	memset(&key, 0, sizeof(DBT));
70	memset(&data, 0, sizeof(DBT));
71	for (recno = 1;; ++recno) {
72		printf("record #%lu&gt; ", (u_long)recno);
73		fflush(stdout);
74		if (fgets(buf, sizeof(buf), stdin) == NULL)
75			break;
76		if ((len = strlen(buf)) &lt;= 1)
77			continue;
78<p>
79		key.data = &recno;
80		key.size = sizeof(recno);
81		data.data = buf;
82		data.size = len - 1;
83<p>
84		switch (ret = dbp-&gt;put(dbp, NULL, &key, &data, 0)) {
85		case 0:
86			break;
87		default:
88			dbp-&gt;err(dbp, ret, "DB-&gt;put");
89			break;
90		}
91	}
92	printf("\n");
93<p>
94	/* Acquire a cursor for the database. */
95	if ((ret = dbp-&gt;cursor(dbp, NULL, &dbcp, 0)) != 0) {
96		dbp-&gt;err(dbp, ret, "DB-&gt;cursor");
97		return (1);
98	}
99<p>
100	/* Re-initialize the key/data pair. */
101	memset(&key, 0, sizeof(key));
102	memset(&data, 0, sizeof(data));
103<p>
104	/* Walk through the database and print out the key/data pairs. */
105	while ((ret = dbcp-&gt;c_get(dbcp, &key, &data, DB_NEXT)) == 0)
106		printf("%lu : %.*s\n",
107		    *(u_long *)key.data, (int)data.size, (char *)data.data);
108	if (ret != DB_NOTFOUND)
109		dbp-&gt;err(dbp, ret, "DBcursor-&gt;get");
110<p>
111	/* Close the cursor. */
112	if ((ret = dbcp-&gt;c_close(dbcp)) != 0) {
113		dbp-&gt;err(dbp, ret, "DBcursor-&gt;close");
114		return (1);
115	}
116	return (0);
117}</pre></blockquote>
118<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>
119</td></tr></table>
120<p><font size=1>Copyright (c) 1996,2008 Oracle.  All rights reserved.</font>
121</body>
122</html>
123