mirror of
https://github.com/berkeleydb/libdb.git
synced 2024-11-16 09:06:25 +00:00
165 lines
7.3 KiB
HTML
165 lines
7.3 KiB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||
<title>Logical record numbers</title>
|
||
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
|
||
<link rel="start" href="index.html" title="Berkeley DB Programmer's Reference Guide" />
|
||
<link rel="up" href="am_conf.html" title="Chapter 2. Access Method Configuration" />
|
||
<link rel="prev" href="am_conf_select.html" title="Selecting an access method" />
|
||
<link rel="next" href="general_am_conf.html" title="General access method configuration" />
|
||
</head>
|
||
<body>
|
||
<div xmlns="" class="navheader">
|
||
<div class="libver">
|
||
<p>Library Version 11.2.5.3</p>
|
||
</div>
|
||
<table width="100%" summary="Navigation header">
|
||
<tr>
|
||
<th colspan="3" align="center">Logical record numbers</th>
|
||
</tr>
|
||
<tr>
|
||
<td width="20%" align="left"><a accesskey="p" href="am_conf_select.html">Prev</a> </td>
|
||
<th width="60%" align="center">Chapter 2.
|
||
Access Method Configuration
|
||
</th>
|
||
<td width="20%" align="right"> <a accesskey="n" href="general_am_conf.html">Next</a></td>
|
||
</tr>
|
||
</table>
|
||
<hr />
|
||
</div>
|
||
<div class="sect1" lang="en" xml:lang="en">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h2 class="title" style="clear: both"><a id="am_conf_logrec"></a>Logical record numbers</h2>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<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_reference/C/dbget.html" class="olink">DB->get()</a> and <a href="../api_reference/C/dbcget.html" class="olink">DBC->get()</a> methods
|
||
with the <a href="../api_reference/C/dbget.html#dbget_DB_SET_RECNO" class="olink">DB_SET_RECNO</a> flag specified, the <span class="bold"><strong>data</strong></span> field of
|
||
the key <a href="../api_reference/C/dbt.html" class="olink">DBT</a> must be a pointer to a memory location of type
|
||
<span class="bold"><strong>db_recno_t</strong></span>, as typedef'd in the standard Berkeley DB include file.
|
||
The <span class="bold"><strong>size</strong></span> field of the key <a href="../api_reference/C/dbt.html" class="olink">DBT</a> should be the size of that
|
||
type (for example, "sizeof(db_recno_t)" in the C programming language).
|
||
The <span class="bold"><strong>db_recno_t</strong></span> 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 class="xref" href="rq_conf.html#am_conf_renumber" title="Logically renumbering records">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>
|
||
<a id="prog_am1"></a>
|
||
<pre class="programlisting">
|
||
int
|
||
recno_build(DB *dbp)
|
||
{
|
||
DBC *dbcp;
|
||
DBT key, data;
|
||
db_recno_t recno;
|
||
u_int32_t len;
|
||
int ret;
|
||
char buf[1024];
|
||
|
||
/* Insert records into the database. */
|
||
memset(&key, 0, sizeof(DBT));
|
||
memset(&data, 0, sizeof(DBT));
|
||
for (recno = 1;; ++recno) {
|
||
printf("record #%lu> ", (u_long)recno);
|
||
fflush(stdout);
|
||
if (fgets(buf, sizeof(buf), stdin) == NULL)
|
||
break;
|
||
if ((len = strlen(buf)) <= 1)
|
||
continue;
|
||
|
||
key.data = &recno;
|
||
key.size = sizeof(recno);
|
||
data.data = buf;
|
||
data.size = len - 1;
|
||
|
||
switch (ret = dbp->put(dbp, NULL, &key, &data, 0)) {
|
||
case 0:
|
||
break;
|
||
default:
|
||
dbp->err(dbp, ret, "DB->put");
|
||
break;
|
||
}
|
||
}
|
||
printf("\n");
|
||
|
||
/* Acquire a cursor for the database. */
|
||
if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) {
|
||
dbp->err(dbp, ret, "DB->cursor");
|
||
return (1);
|
||
}
|
||
|
||
/* Re-initialize the key/data pair. */
|
||
memset(&key, 0, sizeof(key));
|
||
memset(&data, 0, sizeof(data));
|
||
|
||
/* Walk through the database and print out the key/data pairs. */
|
||
while ((ret = dbcp->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->err(dbp, ret, "DBcursor->get");
|
||
|
||
/* Close the cursor. */
|
||
if ((ret = dbcp->close(dbcp)) != 0) {
|
||
dbp->err(dbp, ret, "DBcursor->close");
|
||
return (1);
|
||
}
|
||
return (0);
|
||
}</pre>
|
||
</div>
|
||
<div class="navfooter">
|
||
<hr />
|
||
<table width="100%" summary="Navigation footer">
|
||
<tr>
|
||
<td width="40%" align="left"><a accesskey="p" href="am_conf_select.html">Prev</a> </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="u" href="am_conf.html">Up</a>
|
||
</td>
|
||
<td width="40%" align="right"> <a accesskey="n" href="general_am_conf.html">Next</a></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="40%" align="left" valign="top">Selecting an access method </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="h" href="index.html">Home</a>
|
||
</td>
|
||
<td width="40%" align="right" valign="top"> General access method configuration</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</body>
|
||
</html>
|