<p>The Btree data structure is a sorted, balanced tree structure storing
associated key/data pairs. By default, the sort order is lexicographical,
with shorter keys collating before longer keys. The user can specify the
sort order for the Btree by using the <ahref="../api_reference/C/dbset_bt_compare.html"class="olink">DB->set_bt_compare()</a> method.</p>
<p>Sort routines are passed pointers to keys as arguments. The keys are
represented as <ahref="../api_reference/C/dbt.html"class="olink">DBT</a> structures. The routine must return an integer
less than, equal to, or greater than zero if the first argument is
considered to be respectively less than, equal to, or greater than the
second argument. The only fields that the routines may examine in the
<ahref="../api_reference/C/dbt.html"class="olink">DBT</a> structures are <spanclass="bold"><strong>data</strong></span> and <spanclass="bold"><strong>size</strong></span> fields.</p>
<p>An example routine that might be used to sort integer keys in the database
is as follows:</p>
<aid="prog_am2"></a>
<preclass="programlisting">
int
compare_int(DB *dbp, const DBT *a, const DBT *b)
{
int ai, bi;
/*
* Returns:
* < 0 if a < b
* = 0 if a = b
* > 0 if a > b
*/
memcpy(&ai, a->data, sizeof(int));
memcpy(&bi, b->data, sizeof(int));
return (ai - bi);
}
</pre>
<p>Note that the data must first be copied into memory that is appropriately
aligned, as Berkeley DB does not guarantee any kind of alignment of the
underlying data, including for comparison routines. When writing
comparison routines, remember that databases created on machines of
different architectures may have different integer byte orders, for which
your code may need to compensate.</p>
<p>An example routine that might be used to sort keys based on the first
five bytes of the key (ignoring any subsequent bytes) is as follows:</p>
<aid="prog_am3"></a>
<preclass="programlisting">
int
compare_dbt(DB *dbp, const DBT *a, const DBT *b)
{
int len;
u_char *p1, *p2;
/*
* Returns:
* < 0 if a < b
* = 0 if a = b
* > 0 if a > b
*/
for (p1 = a->data, p2 = b->data, len = 5; len--; ++p1, ++p2)
if (*p1 != *p2)
return ((long)*p1 - (long)*p2);
return (0);
}
</pre>
<p>All comparison functions must cause the keys in the database to be
well-ordered. The most important implication of being well-ordered is
that the key relations must be transitive, that is, if key A is less
than key B, and key B is less than key C, then the comparison routine
must also return that key A is less than key C.</p>
<p>It is reasonable for a comparison function to not examine an entire key
in some applications, which implies partial keys may be specified to the
Berkeley DB interfaces. When partial keys are specified to Berkeley DB, interfaces
which retrieve data items based on a user-specified key (for example,
<ahref="../api_reference/C/dbget.html"class="olink">DB->get()</a> and <ahref="../api_reference/C/dbcget.html"class="olink">DBC->get()</a> with the <ahref="../api_reference/C/dbcget.html#dbcget_DB_SET"class="olink">DB_SET</a> flag), will
modify the user-specified key by returning the actual key stored in the
<p>The prefix comparison routine must be compatible with the overall
comparison function of the Btree, since what distinguishes any two keys
depends entirely on the function used to compare them. This means that
if a prefix comparison routine is specified by the application, a
compatible overall comparison routine must also have been specified.</p>
<p>Prefix comparison routines are passed pointers to keys as arguments.
The keys are represented as <ahref="../api_reference/C/dbt.html"class="olink">DBT</a> structures. The only fields
the routines may examine in the <ahref="../api_reference/C/dbt.html"class="olink">DBT</a> structures are <spanclass="bold"><strong>data</strong></span>
and <spanclass="bold"><strong>size</strong></span> fields.</p>
<p>The prefix comparison function must return the number of bytes necessary
to distinguish the two keys. If the keys are identical (equal and equal
in length), the length should be returned. If the keys are equal up to
the smaller of the two lengths, then the length of the smaller key plus
1 should be returned.</p>
<p>An example prefix comparison routine follows:</p>
<p>Using this calculation, if the page size is 8KB and the default
<spanclass="bold"><strong>minimum_keys</strong></span> value of 2 is used, then any key or data items
larger than 2KB will be forced to an overflow page. If an application
were to specify a <spanclass="bold"><strong>minimum_key</strong></span> value of 100, then any key or data
items larger than roughly 40 bytes would be forced to overflow pages.</p>
<p>It is important to remember that accesses to overflow pages do not perform
as well as accesses to the standard Btree leaf pages, and so setting the
value incorrectly can result in overusing overflow pages and decreasing
the application's overall performance.</p>
</div>
<divclass="sect2"lang="en"xml:lang="en">
<divclass="titlepage">
<div>
<div>
<h3class="title"><aid="am_conf_bt_recnum"></a>Retrieving Btree records by logical record number</h3>
</div>
</div>
</div>
<p>The Btree access method optionally supports retrieval by logical record
numbers. To configure a Btree to support record numbers, call the
<ahref="../api_reference/C/dbset_flags.html"class="olink">DB->set_flags()</a> method with the <ahref="../api_reference/C/dbset_flags.html#dbset_flags_DB_RECNUM"class="olink">DB_RECNUM</a> flag.</p>
<p>Configuring a Btree for record numbers should not be done lightly.
While often useful, it may significantly slow down the speed at which
items can be stored into the database, and can severely impact
application throughput. Generally it should be avoided in trees with
a need for high write concurrency.</p>
<p>To retrieve by record number, use the <ahref="../api_reference/C/dbget.html#dbget_DB_SET_RECNO"class="olink">DB_SET_RECNO</a> flag to the
<ahref="../api_reference/C/dbget.html"class="olink">DB->get()</a> and <ahref="../api_reference/C/dbcget.html"class="olink">DBC->get()</a> methods. The following is an example of
a routine that displays the data item for a Btree database created with
the <ahref="../api_reference/C/dbset_flags.html#dbset_flags_DB_RECNUM"class="olink">DB_RECNUM</a> option.</p>
<aid="prog_am5"></a>
<preclass="programlisting">
int
rec_display(DB *dbp, db_recno_t recno)
{
DBT key, data;
int ret;
memset(&key, 0, sizeof(key));
key.data = &recno;
key.size = sizeof(recno);
memset(&data, 0, sizeof(data));
if ((ret = dbp->get(dbp, NULL, &key, &data, DB_SET_RECNO)) != 0)