1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
<?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 12.1.6.1</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>
|