• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/db-4.8.30/java/src/com/sleepycat/persist/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002-2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9package com.sleepycat.persist;
10
11import java.util.Map;
12import java.util.SortedMap;
13
14import com.sleepycat.collections.StoredMap;
15import com.sleepycat.collections.StoredSortedMap;
16import com.sleepycat.db.CursorConfig;
17import com.sleepycat.db.Database;
18import com.sleepycat.db.DatabaseEntry;
19import com.sleepycat.db.DatabaseException; // for javadoc
20import com.sleepycat.db.Environment;
21import com.sleepycat.db.EnvironmentConfig;
22import com.sleepycat.db.DeadlockException; // for javadoc
23import com.sleepycat.db.LockMode;
24import com.sleepycat.db.SecondaryDatabase; // for javadoc
25import com.sleepycat.db.Transaction;
26
27/**
28 * The interface for accessing keys and entities via a primary or secondary
29 * index.
30 *
31 * <p>{@code EntityIndex} objects are thread-safe.  Multiple threads may safely
32 * call the methods of a shared {@code EntityIndex} object.</p>
33 *
34 * <p>An index is conceptually a <em>map</em>. {key:value} mappings are
35 * stored in the index and accessed by key.  In fact, for interoperability with
36 * other libraries that use the standard Java {@link Map} or {@link SortedMap}
37 * interfaces, an {@code EntityIndex} may be accessed via these standard
38 * interfaces by calling the {@link #map} or {@link #sortedMap} methods.</p>
39 *
40 * <p>{@code EntityIndex} is an interface that is implemented by several
41 * classes in this package for different purposes.  Depending on the context,
42 * the key type (K) and value type (V) of the index take on different meanings.
43 * The different classes that implement {@code EntityIndex} are:</p>
44 * <ul>
45 * <li>{@link PrimaryIndex} maps primary keys to entities.</li>
46 * <li>{@link SecondaryIndex} maps secondary keys to entities.</li>
47 * <li>{@link SecondaryIndex#keysIndex} maps secondary keys to primary
48 * keys.</li>
49 * <li>{@link SecondaryIndex#subIndex} maps primary keys to entities, for the
50 * subset of entities having a specified secondary key.</li>
51 * </ul>
52 *
53 * <p>In all cases, the index key type (K) is a primary or secondary key class.
54 * The index value type (V) is an entity class in all cases except for a {@link
55 * SecondaryIndex#keysIndex}, when it is a primary key class.</p>
56 *
57 * <p>In the following example, a {@code Employee} entity with a {@code
58 * MANY_TO_ONE} secondary key is defined.</p>
59 *
60 * <pre class="code">
61 * {@literal @Entity}
62 * class Employee {
63 *
64 *     {@literal @PrimaryKey}
65 *     long id;
66 *
67 *     {@literal @SecondaryKey(relate=MANY_TO_ONE)}
68 *     String department;
69 *
70 *     String name;
71 *
72 *     private Employee() {}
73 * }</pre>
74 *
75 * <p>Consider that we have stored the entities below:</p>
76 *
77 * <p><table class="code" border="1">
78 *   <tr><th colspan="3">Entities</th></tr>
79 *   <tr><th>ID</th><th>Department</th><th>Name</th></tr>
80 *   <tr><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
81 *   <tr><td>2</td><td>Sales</td><td>Joan Smith</td></tr>
82 *   <tr><td>3</td><td>Engineering</td><td>John Smith</td></tr>
83 *   <tr><td>4</td><td>Sales</td><td>Jim Smith</td></tr>
84 * </table></p>
85*
86 * <p>{@link PrimaryIndex} maps primary keys to entities:</p>
87 *
88 * <pre class="code">
89 * {@code PrimaryIndex<Long,Employee>} primaryIndex =
90 *     store.getPrimaryIndex(Long.class, Employee.class);</pre>
91 *
92 * <p><table class="code" border="1">
93 *   <tr><th colspan="4">primaryIndex</th></tr>
94 *   <tr><th>Primary Key</th><th colspan="3">Entity</th></tr>
95 *   <tr><td>1</td><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
96 *   <tr><td>2</td><td>2</td><td>Sales</td><td>Joan Smith</td></tr>
97 *   <tr><td>3</td><td>3</td><td>Engineering</td><td>John Smith</td></tr>
98 *   <tr><td>4</td><td>4</td><td>Sales</td><td>Jim Smith</td></tr>
99 * </table></p>
100 *
101 * <p>{@link SecondaryIndex} maps secondary keys to entities:</p>
102 *
103 * <pre class="code">
104 * {@code SecondaryIndex<String,Long,Employee>} secondaryIndex =
105 *     store.getSecondaryIndex(primaryIndex, String.class, "department");</pre>
106 *
107 * <p><table class="code" border="1">
108 *   <tr><th colspan="4">secondaryIndex</th></tr>
109 *   <tr><th>Secondary Key</th><th colspan="3">Entity</th></tr>
110 *   <tr><td>Engineering</td><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
111 *   <tr><td>Engineering</td><td>3</td><td>Engineering</td><td>John Smith</td></tr>
112 *   <tr><td>Sales</td><td>2</td><td>Sales</td><td>Joan Smith</td></tr>
113 *   <tr><td>Sales</td><td>4</td><td>Sales</td><td>Jim Smith</td></tr>
114 * </table></p>
115 *
116 * <p>{@link SecondaryIndex#keysIndex} maps secondary keys to primary
117 * keys:</p>
118 *
119 * <pre class="code">
120 * {@code EntityIndex<String,Long>} keysIndex = secondaryIndex.keysIndex();</pre>
121 *
122 * <p><table class="code" border="1">
123 *   <tr><th colspan="4">keysIndex</th></tr>
124 *   <tr><th>Secondary Key</th><th colspan="3">Primary Key</th></tr>
125 *   <tr><td>Engineering</td><td>1</td></tr>
126 *   <tr><td>Engineering</td><td>3</td></tr>
127 *   <tr><td>Sales</td><td>2</td></tr>
128 *   <tr><td>Sales</td><td>4</td></tr>
129 * </table></p>
130 *
131 * <p>{@link SecondaryIndex#subIndex} maps primary keys to entities, for the
132 * subset of entities having a specified secondary key:</p>
133 *
134 * <pre class="code">
135 * {@code EntityIndex<Long,Entity>} subIndex = secondaryIndex.subIndex("Engineering");</pre>
136 *
137 * <p><table class="code" border="1">
138 *   <tr><th colspan="4">subIndex</th></tr>
139 *   <tr><th>Primary Key</th><th colspan="3">Entity</th></tr>
140 *   <tr><td>1</td><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
141 *   <tr><td>3</td><td>3</td><td>Engineering</td><td>John Smith</td></tr>
142 * </table></p>
143 *
144 * <h3>Accessing the Index</h3>
145 *
146 * <p>An {@code EntityIndex} provides a variety of methods for retrieving
147 * entities from an index.  It also provides methods for deleting entities.
148 * However, it does not provide methods for inserting and updating.  To insert
149 * and update entities, use the {@link PrimaryIndex#put} family of methods in
150 * the {@link PrimaryIndex} class.</p>
151 *
152 * <p>An {@code EntityIndex} supports two mechanisms for retrieving
153 * entities:</p>
154 * <ol>
155 * <li>The {@link #get} method returns a single value for a given key.  If there
156 * are multiple values with the same secondary key (duplicates), it returns the
157 * first entity in the duplicate set.</li>
158 * <li>An {@link EntityCursor} can be obtained using the {@link #keys} and
159 * {@link #entities} family of methods.  A cursor can be used to return all
160 * values in the index, including duplicates.  A cursor can also be used to
161 * return values within a specified range of keys.</li>
162 * </ol>
163 *
164 * <p>Using the example entities above, calling {@link #get} on the primary
165 * index will always return the employee with the given ID, or null if no such
166 * ID exists.  But calling {@link #get} on the secondary index will retrieve
167 * the first employee in the given department, which may not be very
168 * useful:</p>
169 *
170 * <pre class="code">
171 * Employee emp = primaryIndex.get(1);      // Returns by unique ID
172 * emp = secondaryIndex.get("Engineering"); // Returns first in department</pre>
173 *
174 * <p>Using a cursor, you can iterate through all duplicates in the secondary
175 * index:</p>
176 *
177 * <pre class="code">
178 * {@code EntityCursor<Employee>} cursor = secondaryIndex.entities();
179 * try {
180 *     for (Employee entity : cursor) {
181 *         if (entity.department.equals("Engineering")) {
182 *             // Do something with the entity...
183 *         }
184 *     }
185 * } finally {
186 *     cursor.close();
187 * }</pre>
188 *
189 * <p>But for a large database it is much more efficient to iterate over only
190 * those entities with the secondary key you're searching for.  This could be
191 * done by restricting a cursor to a range of keys:</p>
192 *
193 * <pre class="code">
194 * {@code EntityCursor<Employee>} cursor =
195 *     secondaryIndex.entities("Engineering", true, "Engineering", true);
196 * try {
197 *     for (Employee entity : cursor) {
198 *         // Do something with the entity...
199 *     }
200 * } finally {
201 *     cursor.close();
202 * }</pre>
203 *
204 * <p>However, when you are interested only in the entities with a particular
205 * secondary key value, it is more convenient to use a sub-index:</p>
206 *
207 * <pre class="code">
208 * {@code EntityIndex<Long,Entity>} subIndex = secondaryIndex.subIndex("Engineering");
209 * {@code EntityCursor<Employee>} cursor = subIndex.entities();
210 * try {
211 *     for (Employee entity : cursor) {
212 *         // Do something with the entity...
213 *     }
214 * } finally {
215 *     cursor.close();
216 * }</pre>
217 *
218 * <p>In addition to being more convenient than a cursor range, a sub-index
219 * allows retrieving by primary key:</p>
220 *
221 * <pre class="code">
222 * Employee emp = subIndex.get(1);</pre>
223 *
224 * <p>When using a sub-index, all operations performed on the sub-index are
225 * restricted to the single key that was specified when the sub-index was
226 * created.  For example, the following returns null because employee 2 is not
227 * in the Engineering department and therefore is not part of the
228 * sub-index:</p>
229 *
230 * <pre class="code">
231 * Employee emp = subIndex.get(2);</pre>
232 *
233 * <p>For more information on using cursors and cursor ranges, see {@link
234 * EntityCursor}.</p>
235 *
236 * <p>Note that when using an index, keys and values are stored and retrieved
237 * by value not by reference.  In other words, if an entity object is stored
238 * and then retrieved, or retrieved twice, each object will be a separate
239 * instance.  For example, in the code below the assertion will always
240 * fail.</p>
241 * <pre class="code">
242 * MyKey key = ...;
243 * MyEntity entity1 = index.get(key);
244 * MyEntity entity2 = index.get(key);
245 * assert entity1 == entity2; // always fails!
246 * </pre>
247 *
248 * <h3>Deleting from the Index</h3>
249 *
250 * <p>Any type of index may be used to delete entities with a specified key by
251 * calling {@link #delete}.  The important thing to keep in mind is that
252 * <em>all entities</em> with the specified key are deleted.  In a primary index,
253 * at most a single entity is deleted:</p>
254 *
255 * <pre class="code">
256 * primaryIndex.delete(1); // Deletes a single employee by unique ID</pre>
257 *
258 * <p>But in a secondary index, multiple entities may be deleted:</p>
259 *
260 * <pre class="code">
261 * secondaryIndex.delete("Engineering"); // Deletes all Engineering employees</pre>
262 *
263 * <p>This begs this question: How can a single entity be deleted without
264 * knowing its primary key?  The answer is to use cursors.  After locating an
265 * entity using a cursor, the entity can be deleted by calling {@link
266 * EntityCursor#delete}.</p>
267 *
268 * <h3>Transactions</h3>
269 *
270 * <p>Transactions can be used to provide standard ACID (Atomicity,
271 * Consistency, Integrity and Durability) guarantees when retrieving, storing
272 * and deleting entities.  This section provides a brief overview of how to use
273 * transactions with the Direct Persistence Layer.  For more information on
274 * using transactions, see <a
275 * href="{@docRoot}/../gsg_txn/JAVA/index.html">Writing
276 * Transactional Applications</a>.</p>
277 *
278 * <p>Transactions may be used only with a transactional {@link EntityStore},
279 * which is one for which {@link StoreConfig#setTransactional
280 * StoreConfig.setTransactional(true)} has been called.  Likewise, a
281 * transactional store may only be used with a transactional {@link
282 * Environment}, which is one for which {@link
283 * EnvironmentConfig#setTransactional EnvironmentConfig.setTransactional(true)}
284 * has been called.  For example:</p>
285 *
286 * <pre class="code">
287 * EnvironmentConfig envConfig = new EnvironmentConfig();
288 * envConfig.setTransactional(true);
289 * envConfig.setAllowCreate(true);
290 * Environment env = new Environment(new File("/my/data"), envConfig);
291 *
292 * StoreConfig storeConfig = new StoreConfig();
293 * storeConfig.setTransactional(true);
294 * storeConfig.setAllowCreate(true);
295 * EntityStore store = new EntityStore(env, "myStore", storeConfig);</pre>
296 *
297 * <p>Transactions are represented by {@link Transaction} objects, which are
298 * part of the {@link com.sleepycat.db Base API}.  Transactions are created
299 * using the {@link Environment#beginTransaction Environment.beginTransaction}
300 * method.</p>
301 *
302 * <p>A transaction will include all operations for which the transaction
303 * object is passed as a method argument.  All retrieval, storage and deletion
304 * methods have an optional {@link Transaction} parameter for this purpose.
305 * When a transaction is passed to a method that opens a cursor, all retrieval,
306 * storage and deletion operations performed using that cursor will be included
307 * in the transaction.</p>
308 *
309 * <p>A transaction may be committed by calling {@link Transaction#commit} or
310 * aborted by calling {@link Transaction#abort}.  For example, two employees
311 * may be deleted atomically with a transaction; other words, either both are
312 * deleted or neither is deleted:</p>
313 *
314 * <pre class="code">
315 * Transaction txn = env.beginTransaction(null, null);
316 * try {
317 *     primaryIndex.delete(txn, 1);
318 *     primaryIndex.delete(txn, 2);
319 *     txn.commit();
320 *     txn = null;
321 * } finally {
322 *     if (txn != null) {
323 *         txn.abort();
324 *     }
325 * }</pre>
326 *
327 * <p><em>WARNING:</em> Transactions must always be committed or aborted to
328 * prevent resource leaks which could lead to the index becoming unusable or
329 * cause an <code>OutOfMemoryError</code>.  To ensure that a transaction is
330 * aborted in the face of exceptions, call {@link Transaction#abort} in a
331 * finally block.</p>
332 *
333 * <p>For a transactional store, storage and deletion operations are always
334 * transaction protected, whether or not a transaction is explicitly used.  A
335 * null transaction argument means to perform the operation using auto-commit,
336 * or the implied thread transaction if an XAEnvironment is being used.  A
337 * transaction is automatically started as part of the operation and is
338 * automatically committed if the operation completes successfully.  The
339 * transaction is automatically aborted if an exception occurs during the
340 * operation, and the exception is re-thrown to the caller.  For example, each
341 * employee is deleted using a an auto-commit transaction below, but it is
342 * possible that employee 1 will be deleted and employee 2 will not be deleted,
343 * if an error or crash occurs while deleting employee 2:</p>
344 *
345 * <pre class="code">
346 * primaryIndex.delete(null, 1);
347 * primaryIndex.delete(null, 2);</pre>
348 *
349 * <p>When retrieving entities, a null transaction argument means to perform
350 * the operation non-transactionally.  The operation is performed outside the
351 * scope of any transaction, without providing transactional ACID guarantees.
352 * If an implied thread transaction is present (i.e. if an XAEnvironment is
353 * being used), that transaction is used.  When a non-transactional store is
354 * used, transactional ACID guarantees are also not provided.</p>
355 *
356 * <p>For non-transactional and auto-commit usage, overloaded signatures for
357 * retrieval, storage and deletion methods are provided to avoid having to pass
358 * a null transaction argument.  For example, {@link #delete} may be called
359 * instead of {@link #delete(Transaction,Object)}.  For example, the following
360 * code is equivalent to the code above where null was passed for the
361 * transaction:</p>
362 *
363 * <pre class="code">
364 * primaryIndex.delete(1);
365 * primaryIndex.delete(2);</pre>
366 *
367 * <p>For retrieval methods the overloaded signatures also include an optional
368 * {@link LockMode} parameter, and overloaded signatures for opening cursors
369 * include an optional {@link CursorConfig} parameter.  These parameters are
370 * described further below in the Locking and Lock Modes section.</p>
371 *
372 * <h3>Transactions and Cursors</h3>
373 *
374 * <p>There are two special consideration when using cursors with transactions.
375 * First, for a transactional store, a non-null transaction must be passed to
376 * methods that open a cursor if that cursor will be used to delete or update
377 * entities.  Cursors do not perform auto-commit when a null transaction is
378 * explicitly passed or implied by the method signature.  For example, the
379 * following code will throw {@link DatabaseException} when the {@link
380 * EntityCursor#delete} method is called:</p>
381 *
382 * <pre class="code">
383 * // <strong>Does not work with a transactional store!</strong>
384 * {@code EntityCursor<Employee>} cursor = primaryIndex.entities();
385 * try {
386 *     for (Employee entity : cursor) {
387 *         cursor.delete(); // <strong>Will throw DatabaseException.</strong>
388 *     }
389 * } finally {
390 *     cursor.close();
391 * }</pre>
392 *
393 * <p>Instead, the {@link #entities(Transaction,CursorConfig)} signature must
394 * be used and a non-null transaction must be passed:</p>
395 *
396 * <pre class="code">
397 * {@code EntityCursor<Employee>} cursor = primaryIndex.entities(txn, null);
398 * try {
399 *     for (Employee entity : cursor) {
400 *         cursor.delete();
401 *     }
402 * } finally {
403 *     cursor.close();
404 * }</pre>
405 *
406 * <p>The second consideration is that error handling is more complex when
407 * using both transactions and cursors, for the following reasons:</p>
408 * <ol>
409 * <li>When an exception occurs, the transaction should be aborted.</li>
410 * <li>Cursors must be closed whether or not an exception occurs.</li>
411 * <li>Cursors must be closed before committing or aborting the
412 * transaction.</li>
413 * </ol>
414 *
415 * <p>For example:</p>
416 *
417 * <pre class="code">
418 * Transaction txn = env.beginTransaction(null, null);
419 * {@code EntityCursor<Employee>} cursor = null;
420 * try {
421 *     cursor = primaryIndex.entities(txn, null);
422 *     for (Employee entity : cursor) {
423 *         cursor.delete();
424 *     }
425 *     cursor.close();
426 *     cursor = null;
427 *     txn.commit();
428 *     txn = null;
429 * } finally {
430 *     if (cursor != null) {
431 *         cursor.close();
432 *     }
433 *     if (txn != null) {
434 *         txn.abort();
435 *     }
436 * }</pre>
437 *
438 * <h3>Locking and Lock Modes</h3>
439 *
440 * <p>This section provides a brief overview of locking and describes how lock
441 * modes are used with the Direct Persistence Layer.  For more information on
442 * locking, see <a
443 * href="{@docRoot}/../gsg_txn/JAVA/index.html">Writing
444 * Transactional Applications</a>.</p>
445 *
446 * <p>When using transactions, locks are normally acquired on each entity that
447 * is retrieved or stored.  The locks are used to isolate one transaction from
448 * another.  Locks are normally released only when the transaction is committed
449 * or aborted.</p>
450 *
451 * <p>When not using transactions, locks are also normally acquired on each
452 * entity that is retrieved or stored.  However, these locks are released when
453 * the operation is complete.  When using cursors, in order to provide
454 * <em>cursor stability</em> locks are held until the cursor is moved to a
455 * different entity or closed.</p>
456 *
457 * <p>This default locking behavior provides full transactional ACID guarantees
458 * and cursor stability.  However, application performance can sometimes be
459 * improved by compromising these guarantees.  As described in <a
460 * href="{@docRoot}/../gsg_txn/JAVA/index.html">Writing
461 * Transactional Applications</a>, the {@link LockMode} and {@link
462 * CursorConfig} parameters are two of the mechanisms that can be used to make
463 * compromises.</p>
464 *
465 * <p>For example, imagine that you need an approximate count of all entities
466 * matching certain criterion, and it is acceptable for entities to be changed
467 * by other threads or other transactions while performing this query.  {@link
468 * LockMode#READ_UNCOMMITTED} can be used to perform the retrievals without
469 * acquiring any locks.  This reduces memory consumption, does less processing,
470 * and improves concurrency.</p>
471 *
472 * <pre class="code">
473 * {@code EntityCursor<Employee>} cursor = primaryIndex.entities(txn, null);
474 * try {
475 *     Employee entity;
476 *     while ((entity = cursor.next(LockMode.READ_UNCOMMITTED)) != null) {
477 *         // Examine the entity and accumulate totals...
478 *     }
479 * } finally {
480 *     cursor.close();
481 * }</pre>
482 *
483 * <p>The {@link LockMode} parameter specifies locking behavior on a
484 * per-operation basis.  If null or {@link LockMode#DEFAULT} is specified, the
485 * default lock mode is used.</p>
486 *
487 * <p>It is also possible to specify the default locking behavior for a cursor
488 * using {@link CursorConfig}.  The example below is equivalent to the example
489 * above:</p>
490 *
491 * <pre class="code">
492 * CursorConfig config = new CursorConfig();
493 * config.setReadUncommitted(true);
494 * {@code EntityCursor<Employee>} cursor = primaryIndex.entities(txn, config);
495 * try {
496 *     Employee entity;
497 *     while ((entity = cursor.next()) != null) {
498 *         // Examine the entity and accumulate totals...
499 *     }
500 * } finally {
501 *     cursor.close();
502 * }</pre>
503 *
504 *
505 * <p>The use of other lock modes, cursor configuration, and transaction
506 * configuration are discussed in <a
507 * href="{@docRoot}/../gsg_txn/JAVA/index.html">Writing
508 * Transactional Applications</a>.</p>
509 *
510 * <a name="retries"><h3>Performing Transaction Retries</h3></a>
511 *
512 * <p>Lock conflict handling is another important topic discussed in <a
513 * href="{@docRoot}/../gsg_txn/JAVA/index.html">Writing
514 * Transactional Applications</a>.  To go along with that material, here we
515 * show a lock conflict handling loop in the context of the Direct Persistence
516 * Layer.  The example below shows deleting all entities in a primary index in
517 * a single transaction.  If a lock conflict occurs, the transaction is aborted
518 * and the operation is retried.</p>
519 *
520 *
521 * <pre class="code">
522 *  void doTransaction(final Environment env,
523 *                     final {@code PrimaryIndex<Long, Employee>} primaryIndex,
524 *                     final int maxTries)
525 *      throws DatabaseException {
526 *
527 *      boolean success = false;
528 *      for (int tries = 0; !success &amp;&amp; tries &lt; maxTries; tries++) {
529 *          try {
530 *              if (tries &gt; 0) {
531 *                  // May sleep for a short interval here ...
532 *              }
533 *              final Transaction txn = env.beginTransaction(null, null);
534 *              try {
535 *                  final {@code EntityCursor<Employee>} cursor =
536 *                      primaryIndex.entities(txn, null);
537 *                  try {
538 *                      // Perform read and write operations here ...
539 *                      for (Employee entity : cursor) {
540 *                          cursor.delete();
541 *                      }
542 *                      success = true;
543 *                  } finally {
544 *                      cursor.close();
545 *                  }
546 *              } finally {
547 *                  if (success) {
548 *                      txn.commit();
549 *                  } else {
550 *                      txn.abort();
551 *                  }
552 *              }
553 *          } catch (DeadlockException e) {
554 *              success = false;
555 *          }
556 *      }
557 *      if (success) {
558 *          // Transaction was committed.
559 *      } else {
560 *          // Maximum retry count was exceeded.
561 *      }
562 *  }</pre>
563 *
564 * <h3>Low Level Access</h3>
565 *
566 * <p>Each Direct Persistence Layer index is associated with an underlying
567 * {@link Database} or {@link SecondaryDatabase} defined in the {@link
568 * com.sleepycat.db Base API}.  At this level, an index is a Btree managed by
569 * the Berkeley DB Java Edition transactional storage engine.  Although you may
570 * never need to work at the {@code Base API} level, keep in mind that some
571 * types of performance tuning can be done by configuring the underlying
572 * databases.  See the {@link EntityStore} class for more information on
573 * database and sequence configuration.</p>
574 *
575 * <p>If you wish to access an index using the {@code Base API}, you may call
576 * the {@link PrimaryIndex#getDatabase} or {@link SecondaryIndex#getDatabase}
577 * method to get the underlying database.  To translate between entity or key
578 * objects and {@link DatabaseEntry} objects at this level, use the bindings
579 * returned by {@link PrimaryIndex#getEntityBinding}, {@link
580 * PrimaryIndex#getKeyBinding}, and {@link SecondaryIndex#getKeyBinding}.</p>
581 *
582 * @author Mark Hayes
583 */
584public interface EntityIndex<K,V> {
585
586    /**
587     * Checks for existence of a key in this index.
588     *
589     * <p>The operation will not be transaction protected, and {@link
590     * LockMode#DEFAULT} is used implicitly.</p>
591     *
592     *
593     * @param key the key to search for.
594     *
595     * @return whether the key exists in the index.
596     */
597    boolean contains(K key)
598        throws DatabaseException;
599
600    /**
601     * Checks for existence of a key in this index.
602     *
603     *
604     * @param txn the transaction used to protect this operation, or null
605     * if the operation should not be transaction protected.
606     *
607     * @param key the key to search for.
608     *
609     * @param lockMode the lock mode to use for this operation, or null to
610     * use {@link LockMode#DEFAULT}.
611     *
612     * @return whether the key exists in the index.
613     */
614    boolean contains(Transaction txn, K key, LockMode lockMode)
615        throws DatabaseException;
616
617    /**
618     * Gets an entity via a key of this index.
619     *
620     * <p>The operation will not be transaction protected, and {@link
621     * LockMode#DEFAULT} is used implicitly.</p>
622     *
623     * @param key the key to search for.
624     *
625     * @return the value mapped to the given key, or null if the key is not
626     * present in the index.
627     */
628    V get(K key)
629        throws DatabaseException;
630
631    /**
632     * Gets an entity via a key of this index.
633     *
634     * @param txn the transaction used to protect this operation, or null
635     * if the operation should not be transaction protected.
636     *
637     * @param key the key to search for.
638     *
639     * @param lockMode the lock mode to use for this operation, or null to
640     * use {@link LockMode#DEFAULT}.
641     *
642     * @return the value mapped to the given key, or null if the key is not
643     * present in the index.
644     */
645    V get(Transaction txn, K key, LockMode lockMode)
646        throws DatabaseException;
647
648    /**
649     * Returns a non-transactional count of the entities in this index.
650     *
651     * <p>This operation is faster than obtaining a count by scanning the index
652     * manually, and will not perturb the current contents of the cache.
653     * However, the count is not guaranteed to be accurate if there are
654     * concurrent updates.</p>
655     *
656     * @return the number of entities in this index.
657     */
658    long count()
659        throws DatabaseException;
660
661    /**
662     * Deletes all entities with a given index key.
663     *
664     * <p>Auto-commit is used implicitly if the store is transactional.</p>
665     *
666     * @param key the key to search for.
667     *
668     * @return whether any entities were deleted.
669     */
670    boolean delete(K key)
671        throws DatabaseException;
672
673    /**
674     * Deletes all entities with a given index key.
675     *
676     * @param txn the transaction used to protect this operation, null to use
677     * auto-commit, or null if the store is non-transactional.
678     *
679     * @param key the key to search for.
680     *
681     * @return whether any entities were deleted.
682     */
683    boolean delete(Transaction txn, K key)
684        throws DatabaseException;
685
686    /**
687     * Opens a cursor for traversing all keys in this index.
688     *
689     * <p>The operations performed with the cursor will not be transaction
690     * protected, and {@link CursorConfig#DEFAULT} is used implicitly.  If the
691     * store is transactional, the cursor may not be used to update or delete
692     * entities.</p>
693     *
694     *
695     * @return the cursor.
696     */
697    EntityCursor<K> keys()
698        throws DatabaseException;
699
700    /**
701     * Opens a cursor for traversing all keys in this index.
702     *
703     *
704     * @param txn the transaction used to protect all operations performed with
705     * the cursor, or null if the operations should not be transaction
706     * protected.  If null is specified and the store is transactional, the
707     * cursor may not be used to update or delete entities.
708     *
709     * @param config the cursor configuration that determines the default lock
710     * mode used for all cursor operations, or null to implicitly use {@link
711     * CursorConfig#DEFAULT}.
712     *
713     * @return the cursor.
714     */
715    EntityCursor<K> keys(Transaction txn, CursorConfig config)
716        throws DatabaseException;
717
718    /**
719     * Opens a cursor for traversing all entities in this index.
720     *
721     * <p>The operations performed with the cursor will not be transaction
722     * protected, and {@link CursorConfig#DEFAULT} is used implicitly.  If the
723     * store is transactional, the cursor may not be used to update or delete
724     * entities.</p>
725     *
726     * @return the cursor.
727     */
728    EntityCursor<V> entities()
729        throws DatabaseException;
730
731    /**
732     * Opens a cursor for traversing all entities in this index.
733     *
734     * @param txn the transaction used to protect all operations performed with
735     * the cursor, or null if the operations should not be transaction
736     * protected.  If null is specified and the store is transactional, the
737     * cursor may not be used to update or delete entities.
738     *
739     * @param config the cursor configuration that determines the default lock
740     * mode used for all cursor operations, or null to implicitly use {@link
741     * CursorConfig#DEFAULT}.
742     *
743     * @return the cursor.
744     */
745    EntityCursor<V> entities(Transaction txn,
746                             CursorConfig config)
747        throws DatabaseException;
748
749    /**
750     * Opens a cursor for traversing keys in a key range.
751     *
752     * <p>The operations performed with the cursor will not be transaction
753     * protected, and {@link CursorConfig#DEFAULT} is used implicitly.  If the
754     * store is transactional, the cursor may not be used to update or delete
755     * entities.</p>
756     *
757     *
758     * @param fromKey is the lower bound of the key range, or null if the range
759     * has no lower bound.
760     *
761     * @param fromInclusive is true if keys greater than or equal to fromKey
762     * should be included in the key range, or false if only keys greater than
763     * fromKey should be included.
764     *
765     * @param toKey is the upper bound of the key range, or null if the range
766     * has no upper bound.
767     *
768     * @param toInclusive is true if keys less than or equal to toKey should be
769     * included in the key range, or false if only keys less than toKey should
770     * be included.
771     *
772     * @return the cursor.
773     */
774    EntityCursor<K> keys(K fromKey,
775                         boolean fromInclusive,
776                         K toKey,
777                         boolean toInclusive)
778        throws DatabaseException;
779
780    /**
781     * Opens a cursor for traversing keys in a key range.
782     *
783     *
784     * @param txn the transaction used to protect all operations performed with
785     * the cursor, or null if the operations should not be transaction
786     * protected.  If null is specified and the store is transactional, the
787     * cursor may not be used to update or delete entities.
788     *
789     * @param fromKey is the lower bound of the key range, or null if the range
790     * has no lower bound.
791     *
792     * @param fromInclusive is true if keys greater than or equal to fromKey
793     * should be included in the key range, or false if only keys greater than
794     * fromKey should be included.
795     *
796     * @param toKey is the upper bound of the key range, or null if the range
797     * has no upper bound.
798     *
799     * @param toInclusive is true if keys less than or equal to toKey should be
800     * included in the key range, or false if only keys less than toKey should
801     * be included.
802     *
803     * @param config the cursor configuration that determines the default lock
804     * mode used for all cursor operations, or null to implicitly use {@link
805     * CursorConfig#DEFAULT}.
806     *
807     * @return the cursor.
808     */
809    EntityCursor<K> keys(Transaction txn,
810                         K fromKey,
811                         boolean fromInclusive,
812                         K toKey,
813                         boolean toInclusive,
814                         CursorConfig config)
815        throws DatabaseException;
816
817    /**
818     * Opens a cursor for traversing entities in a key range.
819     *
820     * <p>The operations performed with the cursor will not be transaction
821     * protected, and {@link CursorConfig#DEFAULT} is used implicitly.  If the
822     * store is transactional, the cursor may not be used to update or delete
823     * entities.</p>
824     *
825     * @param fromKey is the lower bound of the key range, or null if the range
826     * has no lower bound.
827     *
828     * @param fromInclusive is true if keys greater than or equal to fromKey
829     * should be included in the key range, or false if only keys greater than
830     * fromKey should be included.
831     *
832     * @param toKey is the upper bound of the key range, or null if the range
833     * has no upper bound.
834     *
835     * @param toInclusive is true if keys less than or equal to toKey should be
836     * included in the key range, or false if only keys less than toKey should
837     * be included.
838     *
839     * @return the cursor.
840     */
841    EntityCursor<V> entities(K fromKey,
842                             boolean fromInclusive,
843                             K toKey,
844                             boolean toInclusive)
845        throws DatabaseException;
846
847    /**
848     * Opens a cursor for traversing entities in a key range.
849     *
850     * @param txn the transaction used to protect all operations performed with
851     * the cursor, or null if the operations should not be transaction
852     * protected.  If null is specified and the store is transactional, the
853     * cursor may not be used to update or delete entities.
854     *
855     * @param fromKey is the lower bound of the key range, or null if the range
856     * has no lower bound.
857     *
858     * @param fromInclusive is true if keys greater than or equal to fromKey
859     * should be included in the key range, or false if only keys greater than
860     * fromKey should be included.
861     *
862     * @param toKey is the upper bound of the key range, or null if the range
863     * has no upper bound.
864     *
865     * @param toInclusive is true if keys less than or equal to toKey should be
866     * included in the key range, or false if only keys less than toKey should
867     * be included.
868     *
869     * @param config the cursor configuration that determines the default lock
870     * mode used for all cursor operations, or null to implicitly use {@link
871     * CursorConfig#DEFAULT}.
872     *
873     * @return the cursor.
874     */
875    EntityCursor<V> entities(Transaction txn,
876                             K fromKey,
877                             boolean fromInclusive,
878                             K toKey,
879                             boolean toInclusive,
880                             CursorConfig config)
881        throws DatabaseException;
882
883    /*
884     * Opens a cursor for traversing all keys in this index in arbitrary order.
885     *
886     * <p>Normally entities and keys are returned in key order.  This method
887     * takes advantage of optimizations in the Berkeley DB engine to return
888     * entities in physical storage order, potentially decreasing the amount of
889     * physical I/O.</p>
890     *
891     * <p>The operations performed with the cursor will not be transaction
892     * protected, and {@link CursorConfig#DEFAULT} is used implicitly.</p>
893     *
894     * @param selector the filter for selecting keys to be returned, or null
895     * to select all keys.
896     *
897     * @return the cursor.
898     *
899    ForwardCursor<K> unsortedKeys(KeySelector<K> selector)
900        throws DatabaseException;
901     */
902
903    /*
904     * Opens a cursor for traversing all keys in this index in arbitrary order.
905     *
906     * <p>Normally entities and keys are returned in key order.  This method
907     * takes advantage of optimizations in the Berkeley DB engine to return
908     * entities in physical storage order, potentially decreasing the amount of
909     * physical I/O.</p>
910     *
911     * @param txn the transaction used to protect all operations performed with
912     * the cursor, or null if the operations should not be transaction
913     * protected.
914     *
915     * @param selector the filter for selecting keys to be returned, or null
916     * to select all keys.
917     *
918     * @param config the cursor configuration that determines the default lock
919     * mode used for all cursor operations, or null to implicitly use {@link
920     * CursorConfig#DEFAULT}.
921     *
922     * @return the cursor.
923     *
924    ForwardCursor<K> unsortedKeys(Transaction txn,
925                                  KeySelector<K> selector,
926                                  CursorConfig config)
927        throws DatabaseException;
928     */
929
930    /*
931     * Opens a cursor for traversing all entities in this index in arbitrary
932     * order.
933     *
934     * <p>Normally entities and keys are returned in key order.  This method
935     * takes advantage of optimizations in the Berkeley DB engine to return
936     * entities in physical storage order, potentially decreasing the amount of
937     * physical I/O.</p>
938     *
939     * <p>The operations performed with the cursor will not be transaction
940     * protected, and {@link CursorConfig#DEFAULT} is used implicitly.</p>
941
942     * @param selector the filter for selecting keys to be returned, or null
943     * to select all keys.
944     *
945     * @return the cursor.
946     *
947    ForwardCursor<V> unsortedEntities(KeySelector<K> selector)
948        throws DatabaseException;
949     */
950
951    /*
952     * Opens a cursor for traversing all entities in this index in arbitrary
953     * order.
954     *
955     * <p>Normally entities and keys are returned in key order.  This method
956     * takes advantage of optimizations in the Berkeley DB engine to return
957     * entities in physical storage order, potentially decreasing the amount of
958     * physical I/O.</p>
959     *
960     * @param txn the transaction used to protect all operations performed with
961     * the cursor, or null if the operations should not be transaction
962     * protected.
963     *
964     * @param selector the filter for selecting keys to be returned, or null
965     * to select all keys.
966     *
967     * @param config the cursor configuration that determines the default lock
968     * mode used for all cursor operations, or null to implicitly use {@link
969     * CursorConfig#DEFAULT}.
970     *
971     * @return the cursor.
972     *
973    ForwardCursor<V> unsortedEntities(Transaction txn,
974                                      KeySelector<K> selector,
975                                      CursorConfig config)
976        throws DatabaseException;
977     */
978
979    /**
980     * Returns a standard Java map based on this entity index.  The {@link
981     * StoredMap} returned is defined by the {@linkplain
982     * com.sleepycat.collections Collections API}.  Stored collections conform
983     * to the standard Java collections framework interface.
984     *
985     * @return the map.
986     */
987    Map<K,V> map();
988
989    /**
990     * Returns a standard Java sorted map based on this entity index.  The
991     * {@link StoredSortedMap} returned is defined by the {@linkplain
992     * com.sleepycat.collections Collections API}.  Stored collections conform
993     * to the standard Java collections framework interface.
994     *
995     * @return the map.
996     */
997    SortedMap<K,V> sortedMap();
998}
999