je/docs/GettingStartedGuide/comparator.html

261 lines
10 KiB
HTML
Raw Normal View History

2021-06-06 17:46:45 +00:00
<?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>Using Comparators</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="Getting Started with Berkeley DB Java Edition" />
<link rel="up" href="DBEntry.html" title="Chapter 8. Database Records" />
<link rel="prev" href="bindAPI.html" title="Using the BIND APIs" />
<link rel="next" href="dbtUsage.html" title="Database Record Example" />
</head>
<body>
<div xmlns="" class="navheader">
<div class="libver">
<p>Library Version 12.2.7.5</p>
</div>
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Using Comparators</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="bindAPI.html">Prev</a> </td>
<th width="60%" align="center">Chapter 8. Database Records</th>
<td width="20%" align="right"> <a accesskey="n" href="dbtUsage.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="comparator"></a>Using Comparators</h2>
</div>
</div>
</div>
<div class="toc">
<dl>
<dt>
<span class="sect2">
<a href="comparator.html#writeCompare">Writing Comparators</a>
</span>
</dt>
<dt>
<span class="sect2">
<a href="comparator.html#setCompare">Setting Comparators</a>
</span>
</dt>
</dl>
</div>
<p>Internally, JE databases are organized as BTrees.
This means that most database operations
(inserts, deletes, reads, and so forth) involve BTree node
comparisons. This comparison most frequently occurs based on database
keys, but if your database supports duplicate records then
comparisons can also occur based on the database data.
</p>
<p>
By default, JE performs all such comparisons using a byte-by-byte
lexicographic comparison. This mechanism works well for most data.
However, in some cases you may need to specify your own comparison
routine. One frequent reason for this is to perform a language sensitive
lexical ordering of string keys.
</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="writeCompare"></a>Writing Comparators</h3>
</div>
</div>
</div>
<p>
You override the default comparison function by providing a Java
<code class="classname">Comparator</code> class to the database.
The Java <code class="classname">Comparator</code> interface requires you to implement the
<code class="methodname">Comparator.compare()</code> method
(see <a class="ulink" href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html" target="_top">http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html</a> for details).
</p>
<p>
JE passes your <code class="methodname">Comparator.compare()</code> method
the <code class="literal">byte</code> arrays that you stored in the database. If
you know how your data is organized in the <code class="literal">byte</code>
array, then you can write a comparison routine that directly examines
the contents of the arrays. Otherwise, you have to reconstruct your
original objects, and then perform the comparison.
</p>
<p>
For example, suppose you want to perform unicode lexical comparisons
instead of UTF-8 byte-by-byte comparisons. Then you could provide a
comparator that uses <code class="methodname">String.compareTo()</code>,
which performs a Unicode comparison of two strings (note that for
single-byte roman characters, Unicode comparison and UTF-8
byte-by-byte comparisons are identical this is something you
would only want to do if you were using multibyte unicode characters
with JE). In this case, your comparator would look like the
following:
</p>
<a id="je_dbt14"></a>
<pre class="programlisting">package je.gettingStarted;
import java.util.Comparator;
public class MyDataComparator implements Comparator {
public MyDataComparator() {}
public int compare(Object d1, Object d2) {
byte[] b1 = (byte[])d1;
byte[] b2 = (byte[])d2;
String s1 = new String(b1, "UTF-8");
String s2 = new String(b2, "UTF-8");
return s1.compareTo(s2);
}
} </pre>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a id="setCompare"></a>Setting Comparators</h3>
</div>
</div>
</div>
<p>
You specify a <code class="classname">Comparator</code> using the following
methods. Note that by default these methods can only be used at database
creation time, and they are ignored for normal database opens. Also,
note that JE uses the no-argument constructor for these comparators.
Further, it is not allowable for there to be a mutable state in these
comparators or else unpredictable results will occur.
</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<code class="methodname">DatabaseConfig.setBtreeComparator()</code>
</p>
<p>
Sets the Java <code class="classname">Comparator</code> class used
to compare two keys in the database.
</p>
</li>
<li>
<p>
<code class="methodname">DatabaseConfig.setDuplicateComparator()</code>
</p>
<p>
Sets the Java <code class="classname">Comparator</code> class used to compare the
data on two duplicate records in the database. This comparator is
used only if the database supports duplicate records.
</p>
</li>
</ul>
</div>
<p>
You can use the above methods to set a database's comparator after
database creation time if you explicitly indicate that the comparator
is to be overridden. You do this by using the following methods:
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title">Note</h3>
<p>
If you override your comparator, the new comparator must preserve the
sort order implemented by your original comparator. That is, the new
comparator and the old comparator must return the same value for the
comparison of any two valid objects. Failure to observe this constraint
will cause unpredictable results for your application.
</p>
<p>
If you want to change the fundamental sort order for your database, back
up the contents of the database, delete the database, recreate it, and
then reload its data.
</p>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>
<code class="methodname">DatabaseConfig.setOverrideBtreeComparator()</code>
</p>
<p>
If set to <code class="literal">true</code>, causes the database's Btree
comparator to be overridden with the
<code class="classname">Comparator</code> specified on
<code class="methodname">DatabaseConfig.setBtreeComparator()</code>. This
method can be used to change the comparator post-environment
creation.
</p>
</li>
<li>
<p>
<code class="methodname">DatabaseConfig.setOverrideDuplicateComparator()</code>
</p>
<p>
If set to <code class="literal">true</code>, causes the database's
duplicates comparator to be overridden with the
<code class="classname">Comparator</code> specified on
<code class="methodname">DatabaseConfig.setDuplicateComparator()</code>.
</p>
</li>
</ul>
</div>
<p>For example, to use the <code class="classname">Comparator</code>
described in the previous section:</p>
<a id="je_dbt15"></a>
<pre class="programlisting">package je.gettingStarted;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseException;
import java.util.Comparator;
...
// Environment open omitted for brevity
try {
// Get the database configuration object
DatabaseConfig myDbConfig = new DatabaseConfig();
myDbConfig.setAllowCreate(true);
// Set the duplicate comparator class
myDbConfig.setDuplicateComparator(MyDataComparator.class);
// Open the database that you will use to store your data
myDbConfig.setSortedDuplicates(true);
Database myDatabase = myDbEnv.openDatabase(null, "myDb", myDbConfig);
} catch (DatabaseException dbe) {
// Exception handling goes here
}</pre>
</div>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="bindAPI.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="DBEntry.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="dbtUsage.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Using the BIND APIs </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> Database Record Example</td>
</tr>
</table>
</div>
</body>
</html>