KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > persist > EntityIndex


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: EntityIndex.java,v 1.16 2006/12/04 02:49:52 mark Exp $
7  */

8
9 package com.sleepycat.persist;
10
11 import java.util.Map JavaDoc;
12 import java.util.SortedMap JavaDoc;
13
14 import com.sleepycat.collections.StoredMap;
15 import com.sleepycat.collections.StoredSortedMap;
16 import com.sleepycat.je.CursorConfig;
17 import com.sleepycat.je.Database;
18 import com.sleepycat.je.DatabaseEntry;
19 import com.sleepycat.je.DatabaseException;
20 import com.sleepycat.je.Environment;
21 import com.sleepycat.je.EnvironmentConfig;
22 import com.sleepycat.je.LockMode;
23 import com.sleepycat.je.SecondaryDatabase;
24 import com.sleepycat.je.Transaction;
25
26 /**
27  * The interface for accessing keys and entities via a primary or secondary
28  * index.
29  *
30  * <p>{@code EntityIndex} objects are thread-safe. Multiple threads may safely
31  * call the methods of a shared {@code EntityIndex} object.</p>
32  *
33  * <p>An index is conceptually a <em>map</em>. {key:value} mappings are
34  * stored in the index and accessed by key. In fact, for interoperability with
35  * other libraries that use the standard Java {@link Map} or {@link SortedMap}
36  * interfaces, an {@code EntityIndex} may be accessed via these standard
37  * interfaces by calling the {@link #map} or {@link #sortedMap} methods.</p>
38  *
39  * <p>{@code EntityIndex} is an interface that is implemented by several
40  * classes in this package for different purposes. Depending on the context,
41  * the key type (K) and value type (V) of the index take on different meanings.
42  * The different classes that implement {@code EntityIndex} are:</p>
43  * <ul>
44  * <li>{@link PrimaryIndex} maps primary keys to entities.</li>
45  * <li>{@link SecondaryIndex} maps secondary keys to entities.</li>
46  * <li>{@link SecondaryIndex#keysIndex} maps secondary keys to primary
47  * keys.</li>
48  * <li>{@link SecondaryIndex#subIndex} maps primary keys to entities, for the
49  * subset of entities having a specified secondary key.</li>
50  * </ul>
51  *
52  * <p>In all cases, the index key type (K) is a primary or secondary key class.
53  * The index value type (V) is an entity class in all cases except for a {@link
54  * SecondaryIndex#keysIndex}, when it is a primary key class.</p>
55  *
56  * <p>In the following example, a {@code Employee} entity with a {@code
57  * MANY_TO_ONE} secondary key is defined.</p>
58  *
59  * <pre class="code">
60  * {@literal @Entity}
61  * class Employee {
62  *
63  * {@literal @PrimaryKey}
64  * long id;
65  *
66  * {@literal @SecondaryKey(relate=MANY_TO_ONE)}
67  * String department;
68  *
69  * String name;
70  *
71  * private Employee() {}
72  * }</pre>
73  *
74  * <p>Consider that we have stored the entities below:</p>
75  *
76  * <p><table class="code" border="1">
77  * <tr><th colspan="3">Entities</th></tr>
78  * <tr><th>ID</th><th>Department</th><th>Name</th></tr>
79  * <tr><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
80  * <tr><td>2</td><td>Sales</td><td>Joan Smith</td></tr>
81  * <tr><td>3</td><td>Engineering</td><td>John Smith</td></tr>
82  * <tr><td>4</td><td>Sales</td><td>Jim Smith</td></tr>
83  * </table></p>
84 *
85  * <p>{@link PrimaryIndex} maps primary keys to entities:</p>
86  *
87  * <pre class="code">
88  * {@code PrimaryIndex<Long,Employee>} primaryIndex =
89  * store.getPrimaryIndex(Long.class, Employee.class);</pre>
90  *
91  * <p><table class="code" border="1">
92  * <tr><th colspan="4">primaryIndex</th></tr>
93  * <tr><th>Primary Key</th><th colspan="3">Entity</th></tr>
94  * <tr><td>1</td><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
95  * <tr><td>2</td><td>2</td><td>Sales</td><td>Joan Smith</td></tr>
96  * <tr><td>3</td><td>3</td><td>Engineering</td><td>John Smith</td></tr>
97  * <tr><td>4</td><td>4</td><td>Sales</td><td>Jim Smith</td></tr>
98  * </table></p>
99  *
100  * <p>{@link SecondaryIndex} maps secondary keys to entities:</p>
101  *
102  * <pre class="code">
103  * {@code SecondaryIndex<String,Long,Employee>} secondaryIndex =
104  * store.getSecondaryIndex(primaryIndex, String.class, "department");</pre>
105  *
106  * <p><table class="code" border="1">
107  * <tr><th colspan="4">secondaryIndex</th></tr>
108  * <tr><th>Secondary Key</th><th colspan="3">Entity</th></tr>
109  * <tr><td>Engineering</td><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
110  * <tr><td>Engineering</td><td>3</td><td>Engineering</td><td>John Smith</td></tr>
111  * <tr><td>Sales</td><td>2</td><td>Sales</td><td>Joan Smith</td></tr>
112  * <tr><td>Sales</td><td>4</td><td>Sales</td><td>Jim Smith</td></tr>
113  * </table></p>
114  *
115  * <p>{@link SecondaryIndex#keysIndex} maps secondary keys to primary
116  * keys:</p>
117  *
118  * <pre class="code">
119  * {@code EntityIndex<String,Long>} keysIndex = secondaryIndex.keysIndex();</pre>
120  *
121  * <p><table class="code" border="1">
122  * <tr><th colspan="4">keysIndex</th></tr>
123  * <tr><th>Secondary Key</th><th colspan="3">Primary Key</th></tr>
124  * <tr><td>Engineering</td><td>1</td></tr>
125  * <tr><td>Engineering</td><td>3</td></tr>
126  * <tr><td>Sales</td><td>2</td></tr>
127  * <tr><td>Sales</td><td>4</td></tr>
128  * </table></p>
129  *
130  * <p>{@link SecondaryIndex#subIndex} maps primary keys to entities, for the
131  * subset of entities having a specified secondary key:</p>
132  *
133  * <pre class="code">
134  * {@code EntityIndex<Long,Entity>} subIndex = secondaryIndex.subIndex("Engineering");</pre>
135  *
136  * <p><table class="code" border="1">
137  * <tr><th colspan="4">subIndex</th></tr>
138  * <tr><th>Primary Key</th><th colspan="3">Entity</th></tr>
139  * <tr><td>1</td><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
140  * <tr><td>3</td><td>3</td><td>Engineering</td><td>John Smith</td></tr>
141  * </table></p>
142  *
143  * <h3>Accessing the Index</h3>
144  *
145  * <p>An {@code EntityIndex} provides a variety of methods for retrieving
146  * entities from an index. It also provides methods for deleting entities.
147  * However, it does not provide methods for inserting and updating. To insert
148  * and update entities, use the {@link PrimaryIndex#put} family of methods in
149  * the {@link PrimaryIndex} class.</p>
150  *
151  * <p>An {@code EntityIndex} supports two mechanisms for retrieving
152  * entities:</p>
153  * <ol>
154  * <li>The {@link #get} mehod returns a single value for a given key. If there
155  * are multiple values with the same secondary key (duplicates), it returns the
156  * first entity in the duplicate set.</li>
157  * <li>An {@link EntityCursor} can be obtained using the {@link #keys} and
158  * {@link #entities} family of methods. A cursor can be used to return all
159  * values in the index, including duplicates. A cursor can also be used to
160  * return values within a specified range of keys.</li>
161  * </ol>
162  *
163  * <p>Using the example entities above, calling {@link #get} on the primary
164  * index will always return the employee with the given ID, or null if no such
165  * ID exists. But calling {@link #get} on the secondary index will retrieve
166  * the first employee in the given department, which may not be very
167  * useful:</p>
168  *
169  * <pre class="code">
170  * Employee emp = primaryIndex.get(1); // Returns by unique ID
171  * emp = secondaryIndex.get("Engineering"); // Returns first in department</pre>
172  *
173  * <p>Using a cursor, you can iterate through all duplicates in the secondary
174  * index:</p>
175  *
176  * <pre class="code">
177  * {@code EntityCursor<Employee>} cursor = secondaryIndex.entities();
178  * try {
179  * for (Employee entity : cursor) {
180  * if (entity.department.equals("Engineering")) {
181  * // Do something with the entity...
182  * }
183  * }
184  * } finally {
185  * cursor.close();
186  * }</pre>
187  *
188  * <p>But for a large database it is much more efficient to iterate over only
189  * those entities with the secondary key you're searching for. This could be
190  * done by restricting a cursor to a range of keys:</p>
191  *
192  * <pre class="code">
193  * {@code EntityCursor<Employee>} cursor =
194  * secondaryIndex.entities("Engineering", true, "Engineering", true);
195  * try {
196  * for (Employee entity : cursor) {
197  * // Do something with the entity...
198  * }
199  * } finally {
200  * cursor.close();
201  * }</pre>
202  *
203  * <p>However, when you are interested only in the entities with a particular
204  * secondary key value, it is more convenient to use a sub-index:</p>
205  *
206  * <pre class="code">
207  * {@code EntityIndex<Long,Entity>} subIndex = secondaryIndex.subIndex("Engineering");
208  * {@code EntityCursor<Employee>} cursor = subIndex.entities();
209  * try {
210  * for (Employee entity : cursor) {
211  * // Do something with the entity...
212  * }
213  * } finally {
214  * cursor.close();
215  * }</pre>
216  *
217  * <p>In addition to being more convenient than a cursor range, a sub-index
218  * allows retrieving by primary key:</p>
219  *
220  * <pre class="code">
221  * Employee emp = subIndex.get(1);</pre>
222  *
223  * <p>When using a sub-index, all operations performed on the sub-index are
224  * restricted to the single key that was specified when the sub-index was
225  * created. For example, the following returns null because employee 2 is not
226  * in the Engineering department and therefore is not part of the
227  * sub-index:</p>
228  *
229  * <pre class="code">
230  * Employee emp = subIndex.get(2);</pre>
231  *
232  * <p>For more information on using cursors and cursor ranges, see {@link
233  * EntityCursor}.</p>
234  *
235  * <p>Note that when using an index, keys and values are stored and retrieved
236  * by value not by reference. In other words, if an entity object is stored
237  * and then retrieved, or retrieved twice, each object will be a separate
238  * instance. For example, in the code below the assertion will always
239  * fail.</p>
240  * <pre class="code">
241  * MyKey key = ...;
242  * MyEntity entity1 = index.get(key);
243  * MyEntity entity2 = index.get(key);
244  * assert entity1 == entity2; // always fails!
245  * </pre>
246  *
247  * <h3>Deleting from the Index</h3>
248  *
249  * <p>Any type of index may be used to delete entities with a specified key by
250  * calling {@link #delete}. The important thing to keep in mind is that
251  * <em>all entities</em> with the specified key are deleted. In a primay index,
252  * at most a single entity is deleted:</p>
253  *
254  * <pre class="code">
255  * primaryIndex.delete(1); // Deletes a single employee by unique ID</pre>
256  *
257  * <p>But in a secondary index, multiple entities may be deleted:</p>
258  *
259  * <pre class="code">
260  * secondaryIndex.delete("Engineering"); // Deletes all Engineering employees</pre>
261  *
262  * <p>This begs this question: How can a single entity be deleted without
263  * knowing its primary key? The answer is to use cursors. After locating an
264  * entity using a cursor, the entity can be deleted by calling {@link
265  * EntityCursor#delete}.</p>
266  *
267  * <h3>Transactions</h3>
268  *
269  * <p>Transactions can be used to provide standard ACID (Atomicity,
270  * Consistency, Integrity and Durability) guarantees when retrieving, storing
271  * and deleting entities. This section provides a brief overview of how to use
272  * transactions with the Direct Persistence Layer. For more information on
273  * using transactions, see <a
274  * HREF="{@docRoot}/../TransactionGettingStarted/index.html">Writing
275  * Transactional Applications</a>.</p>
276  *
277  * <p>Transactions may be used only with a transactional {@link EntityStore},
278  * which is one for which {@link StoreConfig#setTransactional
279  * StoreConfig.setTransactional(true)} has been called. Likewise, a
280  * transactional store may only be used with a transactional {@link
281  * Environment}, which is one for which {@link
282  * EnvironmentConfig#setTransactional EnvironmentConfig.setTransactional(true)}
283  * has been called. For example:</p>
284  *
285  * <pre class="code">
286  * EnvironmentConfig envConfig = new EnvironmentConfig();
287  * envConfig.setTransactional(true);
288  * envConfig.setAllowCreate(true);
289  * Environment env = new Environment(new File("/my/data"), envConfig);
290  *
291  * StoreConfig storeConfig = new StoreConfig();
292  * storeConfig.setTransactional(true);
293  * storeConfig.setAllowCreate(true);
294  * EntityStore store = new EntityStore(env, "myStore", storeConfig);</pre>
295  *
296  * <p>Transactions are represented by {@link Transaction} objects, which are
297  * part of the {@link com.sleepycat.je Base API}. Transactions are created
298  * using the {@link Environment#beginTransaction Environment.beginTransaction}
299  * method.</p>
300  *
301  * <p>A transaction will include all operations for which the transaction
302  * object is passed as a method argument. All retrieval, storage and deletion
303  * methods have an optional {@link Transaction} parameter for this purpose.
304  * When a transaction is passed to a method that opens a cursor, all retrieval,
305  * storage and deletion operations performed using that cursor will be included
306  * in the transaction.</p>
307  *
308  * <p>A transaction may be committed by calling {@link Transaction#commit} or
309  * aborted by calling {@link Transaction#abort}. For example, two employees
310  * may be deleted atomically with a transaction; other words, either both are
311  * deleted or neither is deleted:</p>
312  *
313  * <pre class="code">
314  * Transaction txn = env.beginTransaction(null, null);
315  * try {
316  * primaryIndex.delete(txn, 1);
317  * primaryIndex.delete(txn, 2);
318  * txn.commit();
319  * txn = null;
320  * } finally {
321  * if (txn != null) {
322  * txn.abort();
323  * }
324  * }</pre>
325  *
326  * <p><em>WARNING:</em> Transactions must always be committed or aborted to
327  * prevent resource leaks which could lead to the index becoming unusable or
328  * cause an <code>OutOfMemoryError</code>. To ensure that a transaction is
329  * aborted in the face of exceptions, call {@link Transaction#abort} in a
330  * finally block.</p>
331  *
332  * <p>For a transactional store, storage and deletion operations are always
333  * transaction protected, whether or not a transaction is explicitly used. A
334  * null transaction argument means to perform the operation using auto-commit,
335  * or the implied thread transaction if an XAEnvironment is being used. A
336  * transaction is automatically started as part of the operation and is
337  * automatically committed if the operation completes successfully. The
338  * transaction is automatically aborted if an exception occurs during the
339  * operation, and the exception is re-thrown to the caller. For example, each
340  * employee is deleted using a an auto-commit transaction below, but it is
341  * possible that employee 1 will be deleted and employee 2 will not be deleted,
342  * if an error or crash occurs while deleting employee 2:</p>
343  *
344  * <pre class="code">
345  * primaryIndex.delete(null, 1);
346  * primaryIndex.delete(null, 2);</pre>
347  *
348  * <p>When retrieving entities, a null transaction argument means to perform
349  * the operation non-transactionally. The operation is performed outside the
350  * scope of any transaction, without providing transactional ACID guarantees.
351  * If an implied thread transaction is present (i.e. if an XAEnvironment is
352  * being used), that transaction is used. When a non-transactional store is
353  * used, transactional ACID guarantees are also not provided.</p>
354  *
355  * <p>For non-transactional and auto-commit usage, overloaded signatures for
356  * retrieval, storage and deletion methods are provided to avoid having to pass
357  * a null transaction argument. For example, {@link #delete} may be called
358  * instead of {@link #delete(Transaction,Object)}. For example, the following
359  * code is equivalent to the code above where null was passed for the
360  * transaction:</p>
361  *
362  * <pre class="code">
363  * primaryIndex.delete(1);
364  * primaryIndex.delete(2);</pre>
365  *
366  * <p>For retrieval methods the overloaded signatures also include an optional
367  * {@link LockMode} parameter, and overloaded signatures for opening cursors
368  * include an optional {@link CursorConfig} parameter. These parameters are
369  * described further below in the Locking and Lock Modes section.</p>
370  *
371  * <h3>Transactions and Cursors</h3>
372  *
373  * <p>There are two special consideration when using cursors with transactions.
374  * First, for a transactional store, a non-null transaction must be passed to
375  * methods that open a cursor if that cursor will be used to delete or update
376  * entities. Cursors do not perform auto-commit when a null transaction is
377  * explicitly passed or implied by the method signature. For example, the
378  * following code will throw {@link DatabaseException} when the {@link
379  * EntityCursor#delete} method is called:</p>
380  *
381  * <pre class="code">
382  * // <strong>Does not work with a transactional store!</strong>
383  * {@code EntityCursor<Employee>} cursor = primaryIndex.entities();
384  * try {
385  * for (Employee entity : cursor) {
386  * cursor.delete(); // <strong>Will throw DatabaseException.</strong>
387  * }
388  * } finally {
389  * cursor.close();
390  * }</pre>
391  *
392  * <p>Instead, the {@link #entities(Transaction,CursorConfig)} signature must
393  * be used and a non-null transaction must be passed:</p>
394  *
395  * <pre class="code">
396  * {@code EntityCursor<Employee>} cursor = primaryIndex.entities(txn, null);
397  * try {
398  * for (Employee entity : cursor) {
399  * cursor.delete();
400  * }
401  * } finally {
402  * cursor.close();
403  * }</pre>
404  *
405  * <p>The second consideration is that error handling is more complex when
406  * using both transactions and cursors, for the following reasons:</p>
407  * <ol>
408  * <li>When an exception occurs, the transaction should be aborted.</li>
409  * <li>Cursors must be closed whether or not an exception occurs.</li>
410  * <li>Cursors must be closed before committing or aborting the
411  * transaction.</li>
412  * </ol>
413  *
414  * <p>For example:</p>
415  *
416  * <pre class="code">
417  * Transaction txn = env.beginTransaction(null, null);
418  * {@code EntityCursor<Employee>} cursor = null;
419  * try {
420  * cursor = primaryIndex.entities(txn, null);
421  * for (Employee entity : cursor) {
422  * cursor.delete();
423  * }
424  * cursor.close();
425  * cursor = null;
426  * txn.commit();
427  * txn = null;
428  * } finally {
429  * if (cursor != null) {
430  * cursor.close();
431  * }
432  * if (txn != null) {
433  * txn.abort();
434  * }
435  * }</pre>
436  *
437  * <h3>Locking and Lock Modes</h3>
438  *
439  * <p>This section provides a brief overview of locking and describes how lock
440  * modes are used with the Direct Persistence Layer. For more information on
441  * locking, see <a
442  * HREF="{@docRoot}/../TransactionGettingStarted/index.html">Writing
443  * Transactional Applications</a>.</p>
444  *
445  * <p>When using transactions, locks are normally acquired on each entity that
446  * is retrieved or stored. The locks are used to isolate one transaction from
447  * another. Locks are normally released only when the transaction is committed
448  * or aborted.</p>
449  *
450  * <p>When not using transactions, locks are also normally acquired on each
451  * entity that is retrieved or stored. However, these locks are released when
452  * the operation is complete. When using cursors, in order to provide
453  * <em>cursor stability</em> locks are held until the cursor is moved to a
454  * different entity or closed.</p>
455  *
456  * <p>This default locking behavior provides full transactional ACID guarantees
457  * and cursor stability. However, application performance can sometimes be
458  * improved by compromising these guarantees. As described in <a
459  * HREF="{@docRoot}/../TransactionGettingStarted/index.html">Writing
460  * Transactional Applications</a>, the {@link LockMode} and {@link
461  * CursorConfig} parameters are two of the mechanisms that can be used to make
462  * compromises.</p>
463  *
464  * <p>For example, imagine that you need an approximate count of all entities
465  * matching certain criterion, and it is acceptable for entities to be changed
466  * by other threads or other transactions while performing this query. {@link
467  * LockMode#READ_UNCOMMITTED} can be used to perform the retrievals without
468  * acquiring any locks. This reduces memory consumption, does less processing,
469  * and can improve concurrency.</p>
470  *
471  * <pre class="code">
472  * {@code EntityCursor<Employee>} cursor = primaryIndex.entities(txn, null);
473  * try {
474  * Employee entity;
475  * while ((entity = cursor.next(LockMode.READ_UNCOMMITTED)) != null) {
476  * // Examine the entity and accumulate totals...
477  * }
478  * } finally {
479  * cursor.close();
480  * }</pre>
481  *
482  * <p>The {@link LockMode} parameter specifies locking behavior on a
483  * per-operation basis. If null or {@link LockMode#DEFAULT} is specified, the
484  * default lock mode is used.</p>
485  *
486  * <p>It is also possible to specify the default locking behavior for a cursor
487  * using {@link CursorConfig}. The example below is equivalent to the example
488  * above:</p>
489  *
490  * <pre class="code">
491  * CursorConfig config = new CursorConfig();
492  * config.setReadUncommitted(true);
493  * {@code EntityCursor<Employee>} cursor = primaryIndex.entities(txn, config);
494  * try {
495  * Employee entity;
496  * while ((entity = cursor.next()) != null) {
497  * // Examine the entity and accumulate totals...
498  * }
499  * } finally {
500  * cursor.close();
501  * }</pre>
502  *
503  * <p>The use of other lock modes, cursor configuration, and transaction
504  * configuration are discussed in <a
505  * HREF="{@docRoot}/../TransactionGettingStarted/index.html">Writing
506  * Transactional Applications</a>.</p>
507  *
508  * <p>Deadlock handling is another important topic discussed in <a
509  * HREF="{@docRoot}/../TransactionGettingStarted/index.html">Writing
510  * Transactional Applications</a>. To go along with that material, here we
511  * show a deadlock handling loop in the context of the Direct Persistence
512  * Layer. The example below shows deleting all entities in a primary index in
513  * a single transaction. If a deadlock occurs, the transaction is aborted and
514  * the operation is retried.</p>
515  *
516  * <pre class="code">
517  * int retryCount = 0;
518  * boolean retry = true;
519  * while (retry) {
520  * Transaction txn = env.beginTransaction(null, null);
521  * {@code EntityCursor<Employee>} cursor = null;
522  * try {
523  * cursor = primaryIndex.entities(txn, null);
524  * for (Employee entity : cursor) {
525  * cursor.delete();
526  * }
527  * cursor.close();
528  * cursor = null;
529  * txn.commit();
530  * txn = null;
531  * retry = false;
532  * } catch (DeadlockException e) {
533  * retryCount += 1;
534  * if (retryCount &gt;= MAX_DEADLOCK_RETRIES) {
535  * throw e;
536  * }
537  * } finally {
538  * if (cursor != null) {
539  * cursor.close();
540  * }
541  * if (txn != null) {
542  * txn.abort();
543  * }
544  * }
545  * }</pre>
546  *
547  * <h3>Low Level Access</h3>
548  *
549  * <p>Each Direct Persistence Layer index is associated with an underlying
550  * {@link Database} or {@link SecondaryDatabase} defined in the {@link
551  * com.sleepycat.je Base API}. At this level, an index is a Btree managed by
552  * the Berkeley DB Java Edition transactional storage engine. Although you may
553  * never need to work at the {@code Base API} level, keep in mind that some
554  * types of performance tuning can be done by configuring the underlying
555  * databases. See the {@link EntityStore} class for more information on
556  * database and sequence configuration.</p>
557  *
558  * <p>If you wish to access an index using the {@code Base API}, you may call
559  * the {@link PrimaryIndex#getDatabase} or {@link SecondaryIndex#getDatabase}
560  * method to get the underying database. To translate between entity or key
561  * objects and {@link DatabaseEntry} objects at this level, use the bindings
562  * returned by {@link PrimaryIndex#getEntityBinding}, {@link
563  * PrimaryIndex#getKeyBinding}, and {@link SecondaryIndex#getKeyBinding}.</p>
564  *
565  * @author Mark Hayes
566  */

567 public interface EntityIndex<K,V> {
568
569     /**
570      * Checks for existence of a key in this index.
571      *
572      * <p>The operation will not be transaction protected, and {@link
573      * LockMode#DEFAULT} is used implicitly.</p>
574      *
575      * @param key the key to search for.
576      *
577      * @return whether the key exists in the index.
578      */

579     boolean contains(K key)
580         throws DatabaseException;
581
582     /**
583      * Checks for existence of a key in this index.
584      *
585      * @param txn the transaction used to protect this operation, or null
586      * if the operation should not be transaction protected.
587      *
588      * @param key the key to search for.
589      *
590      * @param lockMode the lock mode to use for this operation, or null to
591      * use {@link LockMode#DEFAULT}.
592      *
593      * @return whether the key exists in the index.
594      */

595     boolean contains(Transaction txn, K key, LockMode lockMode)
596         throws DatabaseException;
597
598     /**
599      * Gets an entity via a key of this index.
600      *
601      * <p>The operation will not be transaction protected, and {@link
602      * LockMode#DEFAULT} is used implicitly.</p>
603      *
604      * @param key the key to search for.
605      *
606      * @return the value mapped to the given key, or null if the key is not
607      * present in the index.
608      */

609     V get(K key)
610         throws DatabaseException;
611
612     /**
613      * Gets an entity via a key of this index.
614      *
615      * @param txn the transaction used to protect this operation, or null
616      * if the operation should not be transaction protected.
617      *
618      * @param key the key to search for.
619      *
620      * @param lockMode the lock mode to use for this operation, or null to
621      * use {@link LockMode#DEFAULT}.
622      *
623      * @return the value mapped to the given key, or null if the key is not
624      * present in the index.
625      */

626     V get(Transaction txn, K key, LockMode lockMode)
627         throws DatabaseException;
628
629     /**
630      * Returns a non-transactional count of the entities in this index.
631      *
632      * <p>This operation is faster than obtaining a count by scanning the index
633      * manually, and will not perturb the current contents of the cache.
634      * However, the count is not guaranteed to be accurate if there are
635      * concurrent updates.</p>
636      *
637      * @return the number of entities in this index.
638      */

639     long count()
640         throws DatabaseException;
641
642     /**
643      * Deletes all entities with a given index key.
644      *
645      * <p>Auto-commit is used implicitly if the store is transactional.</p>
646      *
647      * @param key the key to search for.
648      *
649      * @return whether any entities were deleted.
650      */

651     boolean delete(K key)
652         throws DatabaseException;
653
654     /**
655      * Deletes all entities with a given index key.
656      *
657      * @param txn the transaction used to protect this operation, null to use
658      * auto-commit, or null if the store is non-transactional.
659      *
660      * @param key the key to search for.
661      *
662      * @return whether any entities were deleted.
663      */

664     boolean delete(Transaction txn, K key)
665         throws DatabaseException;
666
667     /**
668      * Opens a cursor for traversing all keys in this index.
669      *
670      * <p>The operations performed with the cursor will not be transaction
671      * protected, and {@link CursorConfig#DEFAULT} is used implicitly. If the
672      * store is transactional, the cursor may not be used to update or delete
673      * entities.</p>
674      *
675      * @return the cursor.
676      */

677     EntityCursor<K> keys()
678         throws DatabaseException;
679
680     /**
681      * Opens a cursor for traversing all keys in this index.
682      *
683      * @param txn the transaction used to protect all operations performed with
684      * the cursor, or null if the operations should not be transaction
685      * protected. If null is specified and the store is transactional, the
686      * cursor may not be used to update or delete entities.
687      *
688      * @param config the cursor configuration that determines the default lock
689      * mode used for all cursor operations, or null to implicitly use {@link
690      * CursorConfig#DEFAULT}.
691      *
692      * @return the cursor.
693      */

694     EntityCursor<K> keys(Transaction txn, CursorConfig config)
695         throws DatabaseException;
696
697     /**
698      * Opens a cursor for traversing all entities in this index.
699      *
700      * <p>The operations performed with the cursor will not be transaction
701      * protected, and {@link CursorConfig#DEFAULT} is used implicitly. If the
702      * store is transactional, the cursor may not be used to update or delete
703      * entities.</p>
704      *
705      * @return the cursor.
706      */

707     EntityCursor<V> entities()
708         throws DatabaseException;
709
710     /**
711      * Opens a cursor for traversing all entities in this index.
712      *
713      * @param txn the transaction used to protect all operations performed with
714      * the cursor, or null if the operations should not be transaction
715      * protected. If null is specified and the store is transactional, the
716      * cursor may not be used to update or delete entities.
717      *
718      * @param config the cursor configuration that determines the default lock
719      * mode used for all cursor operations, or null to implicitly use {@link
720      * CursorConfig#DEFAULT}.
721      *
722      * @return the cursor.
723      */

724     EntityCursor<V> entities(Transaction txn,
725                              CursorConfig config)
726         throws DatabaseException;
727
728     /**
729      * Opens a cursor for traversing keys in a key range.
730      *
731      * <p>The operations performed with the cursor will not be transaction
732      * protected, and {@link CursorConfig#DEFAULT} is used implicitly. If the
733      * store is transactional, the cursor may not be used to update or delete
734      * entities.</p>
735      *
736      * @param fromKey is the lower bound of the key range, or null if the range
737      * has no lower bound.
738      *
739      * @param fromInclusive is true if keys greater than or equal to fromKey
740      * should be included in the key range, or false if only keys greater than
741      * fromKey should be included.
742      *
743      * @param toKey is the upper bound of the key range, or null if the range
744      * has no upper bound.
745      *
746      * @param toInclusive is true if keys less than or equal to toKey should be
747      * included in the key range, or false if only keys less than toKey should
748      * be included.
749      *
750      * @return the cursor.
751      */

752     EntityCursor<K> keys(K fromKey,
753                          boolean fromInclusive,
754                          K toKey,
755                          boolean toInclusive)
756         throws DatabaseException;
757
758     /**
759      * Opens a cursor for traversing keys in a key range.
760      *
761      * @param txn the transaction used to protect all operations performed with
762      * the cursor, or null if the operations should not be transaction
763      * protected. If null is specified and the store is transactional, the
764      * cursor may not be used to update or delete entities.
765      *
766      * @param fromKey is the lower bound of the key range, or null if the range
767      * has no lower bound.
768      *
769      * @param fromInclusive is true if keys greater than or equal to fromKey
770      * should be included in the key range, or false if only keys greater than
771      * fromKey should be included.
772      *
773      * @param toKey is the upper bound of the key range, or null if the range
774      * has no upper bound.
775      *
776      * @param toInclusive is true if keys less than or equal to toKey should be
777      * included in the key range, or false if only keys less than toKey should
778      * be included.
779      *
780      * @param config the cursor configuration that determines the default lock
781      * mode used for all cursor operations, or null to implicitly use {@link
782      * CursorConfig#DEFAULT}.
783      *
784      * @return the cursor.
785      */

786     EntityCursor<K> keys(Transaction txn,
787                          K fromKey,
788                          boolean fromInclusive,
789                          K toKey,
790                          boolean toInclusive,
791                          CursorConfig config)
792         throws DatabaseException;
793
794     /**
795      * Opens a cursor for traversing entities in a key range.
796      *
797      * <p>The operations performed with the cursor will not be transaction
798      * protected, and {@link CursorConfig#DEFAULT} is used implicitly. If the
799      * store is transactional, the cursor may not be used to update or delete
800      * entities.</p>
801      *
802      * @param fromKey is the lower bound of the key range, or null if the range
803      * has no lower bound.
804      *
805      * @param fromInclusive is true if keys greater than or equal to fromKey
806      * should be included in the key range, or false if only keys greater than
807      * fromKey should be included.
808      *
809      * @param toKey is the upper bound of the key range, or null if the range
810      * has no upper bound.
811      *
812      * @param toInclusive is true if keys less than or equal to toKey should be
813      * included in the key range, or false if only keys less than toKey should
814      * be included.
815      *
816      * @return the cursor.
817      */

818     EntityCursor<V> entities(K fromKey,
819                              boolean fromInclusive,
820                              K toKey,
821                              boolean toInclusive)
822         throws DatabaseException;
823
824     /**
825      * Opens a cursor for traversing entities in a key range.
826      *
827      * @param txn the transaction used to protect all operations performed with
828      * the cursor, or null if the operations should not be transaction
829      * protected. If null is specified and the store is transactional, the
830      * cursor may not be used to update or delete entities.
831      *
832      * @param fromKey is the lower bound of the key range, or null if the range
833      * has no lower bound.
834      *
835      * @param fromInclusive is true if keys greater than or equal to fromKey
836      * should be included in the key range, or false if only keys greater than
837      * fromKey should be included.
838      *
839      * @param toKey is the upper bound of the key range, or null if the range
840      * has no upper bound.
841      *
842      * @param toInclusive is true if keys less than or equal to toKey should be
843      * included in the key range, or false if only keys less than toKey should
844      * be included.
845      *
846      * @param config the cursor configuration that determines the default lock
847      * mode used for all cursor operations, or null to implicitly use {@link
848      * CursorConfig#DEFAULT}.
849      *
850      * @return the cursor.
851      */

852     EntityCursor<V> entities(Transaction txn,
853                              K fromKey,
854                              boolean fromInclusive,
855                              K toKey,
856                              boolean toInclusive,
857                              CursorConfig config)
858         throws DatabaseException;
859
860     /*
861      * Opens a cursor for traversing all keys in this index in arbitrary order.
862      *
863      * <p>Normally entities and keys are returned in key order. This method
864      * takes advantage of optimizations in the Berkeley DB engine to return
865      * entities in physical storage order, potentially decreasing the amount of
866      * physical I/O.</p>
867      *
868      * <p>The operations performed with the cursor will not be transaction
869      * protected, and {@link CursorConfig#DEFAULT} is used implicitly. If the
870      * store is transactional, the cursor may not be used to update or delete
871      * entities.</p>
872
873      * @param selector the filter for selecting keys to be returned, or null
874      * to select all keys.
875      *
876      * @return the cursor.
877      *
878     ForwardCursor<K> unsortedKeys(KeySelector<K> selector)
879         throws DatabaseException;
880      */

881
882     /*
883      * Opens a cursor for traversing all keys in this index in arbitrary order.
884      *
885      * <p>Normally entities and keys are returned in key order. This method
886      * takes advantage of optimizations in the Berkeley DB engine to return
887      * entities in physical storage order, potentially decreasing the amount of
888      * physical I/O.</p>
889      *
890      * @param txn the transaction used to protect all operations performed with
891      * the cursor, or null if the operations should not be transaction
892      * protected. If null is specified and the store is transactional, the
893      * cursor may not be used to update or delete entities.
894
895      * @param selector the filter for selecting keys to be returned, or null
896      * to select all keys.
897      *
898      * @param config the cursor configuration that determines the default lock
899      * mode used for all cursor operations, or null to implicitly use {@link
900      * CursorConfig#DEFAULT}.
901      *
902      * @return the cursor.
903      *
904     ForwardCursor<K> unsortedKeys(Transaction txn,
905                                   KeySelector<K> selector,
906                                   CursorConfig config)
907         throws DatabaseException;
908      */

909
910     /*
911      * Opens a cursor for traversing all entities in this index in arbitrary
912      * order.
913      *
914      * <p>Normally entities and keys are returned in key order. This method
915      * takes advantage of optimizations in the Berkeley DB engine to return
916      * entities in physical storage order, potentially decreasing the amount of
917      * physical I/O.</p>
918      *
919      * <p>The operations performed with the cursor will not be transaction
920      * protected, and {@link CursorConfig#DEFAULT} is used implicitly. If the
921      * store is transactional, the cursor may not be used to update or delete
922      * entities.</p>
923
924      * @param selector the filter for selecting keys to be returned, or null
925      * to select all keys.
926      *
927      * @return the cursor.
928      *
929     ForwardCursor<V> unsortedEntities(KeySelector<K> selector)
930         throws DatabaseException;
931      */

932
933     /*
934      * Opens a cursor for traversing all entities in this index in arbitrary
935      * order.
936      *
937      * <p>Normally entities and keys are returned in key order. This method
938      * takes advantage of optimizations in the Berkeley DB engine to return
939      * entities in physical storage order, potentially decreasing the amount of
940      * physical I/O.</p>
941      *
942      * @param txn the transaction used to protect all operations performed with
943      * the cursor, or null if the operations should not be transaction
944      * protected. If null is specified and the store is transactional, the
945      * cursor may not be used to update or delete entities.
946
947      * @param selector the filter for selecting keys to be returned, or null
948      * to select all keys.
949      *
950      * @param config the cursor configuration that determines the default lock
951      * mode used for all cursor operations, or null to implicitly use {@link
952      * CursorConfig#DEFAULT}.
953      *
954      * @return the cursor.
955      *
956     ForwardCursor<V> unsortedEntities(Transaction txn,
957                                       KeySelector<K> selector,
958                                       CursorConfig config)
959         throws DatabaseException;
960      */

961
962     /**
963      * Returns a standard Java map based on this entity index. The {@link
964      * StoredMap} returned is defined by the {@linkplain
965      * com.sleepycat.collections Collections API}. Stored collections conform
966      * to the standard Java collections framework interface.
967      *
968      * @return the map.
969      */

970     Map JavaDoc<K,V> map();
971
972     /**
973      * Returns a standard Java sorted map based on this entity index. The
974      * {@link StoredSortedMap} returned is defined by the {@linkplain
975      * com.sleepycat.collections Collections API}. Stored collections conform
976      * to the standard Java collections framework interface.
977      *
978      * @return the map.
979      */

980     SortedMap JavaDoc<K,V> sortedMap();
981 }
982
Popular Tags