Source Code Cross Referenced for EntityIndex.java in  » JMX » je » com » sleepycat » persist » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » JMX » je » com.sleepycat.persist 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*-
002:         * See the file LICENSE for redistribution information.
003:         *
004:         * Copyright (c) 2002,2008 Oracle.  All rights reserved.
005:         *
006:         * $Id: EntityIndex.java,v 1.16.2.4 2008/01/07 15:14:18 cwl Exp $
007:         */
008:
009:        package com.sleepycat.persist;
010:
011:        import java.util.Map;
012:        import java.util.SortedMap;
013:
014:        import com.sleepycat.collections.StoredMap;
015:        import com.sleepycat.collections.StoredSortedMap;
016:        import com.sleepycat.je.CursorConfig;
017:        import com.sleepycat.je.Database;
018:        import com.sleepycat.je.DatabaseEntry;
019:        import com.sleepycat.je.DatabaseException;
020:        import com.sleepycat.je.Environment;
021:        import com.sleepycat.je.EnvironmentConfig;
022:        import com.sleepycat.je.LockMode;
023:        import com.sleepycat.je.SecondaryDatabase;
024:        import com.sleepycat.je.Transaction;
025:
026:        /**
027:         * The interface for accessing keys and entities via a primary or secondary
028:         * index.
029:         *
030:         * <p>{@code EntityIndex} objects are thread-safe.  Multiple threads may safely
031:         * call the methods of a shared {@code EntityIndex} object.</p>
032:         *
033:         * <p>An index is conceptually a <em>map</em>. {key:value} mappings are
034:         * stored in the index and accessed by key.  In fact, for interoperability with
035:         * other libraries that use the standard Java {@link Map} or {@link SortedMap}
036:         * interfaces, an {@code EntityIndex} may be accessed via these standard
037:         * interfaces by calling the {@link #map} or {@link #sortedMap} methods.</p>
038:         *
039:         * <p>{@code EntityIndex} is an interface that is implemented by several
040:         * classes in this package for different purposes.  Depending on the context,
041:         * the key type (K) and value type (V) of the index take on different meanings.
042:         * The different classes that implement {@code EntityIndex} are:</p>
043:         * <ul>
044:         * <li>{@link PrimaryIndex} maps primary keys to entities.</li>
045:         * <li>{@link SecondaryIndex} maps secondary keys to entities.</li>
046:         * <li>{@link SecondaryIndex#keysIndex} maps secondary keys to primary
047:         * keys.</li>
048:         * <li>{@link SecondaryIndex#subIndex} maps primary keys to entities, for the
049:         * subset of entities having a specified secondary key.</li>
050:         * </ul>
051:         *
052:         * <p>In all cases, the index key type (K) is a primary or secondary key class.
053:         * The index value type (V) is an entity class in all cases except for a {@link
054:         * SecondaryIndex#keysIndex}, when it is a primary key class.</p>
055:         *
056:         * <p>In the following example, a {@code Employee} entity with a {@code
057:         * MANY_TO_ONE} secondary key is defined.</p>
058:         *
059:         * <pre class="code">
060:         * {@literal @Entity}
061:         * class Employee {
062:         *
063:         *     {@literal @PrimaryKey}
064:         *     long id;
065:         *
066:         *     {@literal @SecondaryKey(relate=MANY_TO_ONE)}
067:         *     String department;
068:         *
069:         *     String name;
070:         *
071:         *     private Employee() {}
072:         * }</pre>
073:         *
074:         * <p>Consider that we have stored the entities below:</p>
075:         *
076:         * <p><table class="code" border="1">
077:         *   <tr><th colspan="3">Entities</th></tr>
078:         *   <tr><th>ID</th><th>Department</th><th>Name</th></tr>
079:         *   <tr><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
080:         *   <tr><td>2</td><td>Sales</td><td>Joan Smith</td></tr>
081:         *   <tr><td>3</td><td>Engineering</td><td>John Smith</td></tr>
082:         *   <tr><td>4</td><td>Sales</td><td>Jim Smith</td></tr>
083:         * </table></p>
084:         *
085:         * <p>{@link PrimaryIndex} maps primary keys to entities:</p>
086:         *
087:         * <pre class="code">
088:         * {@code PrimaryIndex<Long,Employee>} primaryIndex =
089:         *     store.getPrimaryIndex(Long.class, Employee.class);</pre>
090:         *
091:         * <p><table class="code" border="1">
092:         *   <tr><th colspan="4">primaryIndex</th></tr>
093:         *   <tr><th>Primary Key</th><th colspan="3">Entity</th></tr>
094:         *   <tr><td>1</td><td>1</td><td>Engineering</td><td>Jane Smith</td></tr>
095:         *   <tr><td>2</td><td>2</td><td>Sales</td><td>Joan Smith</td></tr>
096:         *   <tr><td>3</td><td>3</td><td>Engineering</td><td>John Smith</td></tr>
097:         *   <tr><td>4</td><td>4</td><td>Sales</td><td>Jim Smith</td></tr>
098:         * </table></p>
099:         *
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) throws DatabaseException;
580:
581:            /**
582:             * Checks for existence of a key in this index.
583:             *
584:             * @param txn the transaction used to protect this operation, or null
585:             * if the operation should not be transaction protected.
586:             *
587:             * @param key the key to search for.
588:             *
589:             * @param lockMode the lock mode to use for this operation, or null to
590:             * use {@link LockMode#DEFAULT}.
591:             *
592:             * @return whether the key exists in the index.
593:             */
594:            boolean contains(Transaction txn, K key, LockMode lockMode)
595:                    throws DatabaseException;
596:
597:            /**
598:             * Gets an entity via a key of this index.
599:             *
600:             * <p>The operation will not be transaction protected, and {@link
601:             * LockMode#DEFAULT} is used implicitly.</p>
602:             *
603:             * @param key the key to search for.
604:             *
605:             * @return the value mapped to the given key, or null if the key is not
606:             * present in the index.
607:             */
608:            V get(K key) throws DatabaseException;
609:
610:            /**
611:             * Gets an entity via a key of this index.
612:             *
613:             * @param txn the transaction used to protect this operation, or null
614:             * if the operation should not be transaction protected.
615:             *
616:             * @param key the key to search for.
617:             *
618:             * @param lockMode the lock mode to use for this operation, or null to
619:             * use {@link LockMode#DEFAULT}.
620:             *
621:             * @return the value mapped to the given key, or null if the key is not
622:             * present in the index.
623:             */
624:            V get(Transaction txn, K key, LockMode lockMode)
625:                    throws DatabaseException;
626:
627:            /**
628:             * Returns a non-transactional count of the entities in this index.
629:             *
630:             * <p>This operation is faster than obtaining a count by scanning the index
631:             * manually, and will not perturb the current contents of the cache.
632:             * However, the count is not guaranteed to be accurate if there are
633:             * concurrent updates.</p>
634:             *
635:             * @return the number of entities in this index.
636:             */
637:            long count() throws DatabaseException;
638:
639:            /**
640:             * Deletes all entities with a given index key.
641:             *
642:             * <p>Auto-commit is used implicitly if the store is transactional.</p>
643:             *
644:             * @param key the key to search for.
645:             *
646:             * @return whether any entities were deleted.
647:             */
648:            boolean delete(K key) throws DatabaseException;
649:
650:            /**
651:             * Deletes all entities with a given index key.
652:             *
653:             * @param txn the transaction used to protect this operation, null to use
654:             * auto-commit, or null if the store is non-transactional.
655:             *
656:             * @param key the key to search for.
657:             *
658:             * @return whether any entities were deleted.
659:             */
660:            boolean delete(Transaction txn, K key) throws DatabaseException;
661:
662:            /**
663:             * Opens a cursor for traversing all keys in this index.
664:             *
665:             * <p>The operations performed with the cursor will not be transaction
666:             * protected, and {@link CursorConfig#DEFAULT} is used implicitly.  If the
667:             * store is transactional, the cursor may not be used to update or delete
668:             * entities.</p>
669:             *
670:             * @return the cursor.
671:             */
672:            EntityCursor<K> keys() throws DatabaseException;
673:
674:            /**
675:             * Opens a cursor for traversing all keys in this index.
676:             *
677:             * @param txn the transaction used to protect all operations performed with
678:             * the cursor, or null if the operations should not be transaction
679:             * protected.  If null is specified and the store is transactional, the
680:             * cursor may not be used to update or delete entities.
681:             *
682:             * @param config the cursor configuration that determines the default lock
683:             * mode used for all cursor operations, or null to implicitly use {@link
684:             * CursorConfig#DEFAULT}.
685:             *
686:             * @return the cursor.
687:             */
688:            EntityCursor<K> keys(Transaction txn, CursorConfig config)
689:                    throws DatabaseException;
690:
691:            /**
692:             * Opens a cursor for traversing all entities in this index.
693:             *
694:             * <p>The operations performed with the cursor will not be transaction
695:             * protected, and {@link CursorConfig#DEFAULT} is used implicitly.  If the
696:             * store is transactional, the cursor may not be used to update or delete
697:             * entities.</p>
698:             *
699:             * @return the cursor.
700:             */
701:            EntityCursor<V> entities() throws DatabaseException;
702:
703:            /**
704:             * Opens a cursor for traversing all entities in this index.
705:             *
706:             * @param txn the transaction used to protect all operations performed with
707:             * the cursor, or null if the operations should not be transaction
708:             * protected.  If null is specified and the store is transactional, the
709:             * cursor may not be used to update or delete entities.
710:             *
711:             * @param config the cursor configuration that determines the default lock
712:             * mode used for all cursor operations, or null to implicitly use {@link
713:             * CursorConfig#DEFAULT}.
714:             *
715:             * @return the cursor.
716:             */
717:            EntityCursor<V> entities(Transaction txn, CursorConfig config)
718:                    throws DatabaseException;
719:
720:            /**
721:             * Opens a cursor for traversing keys in a key range.
722:             *
723:             * <p>The operations performed with the cursor will not be transaction
724:             * protected, and {@link CursorConfig#DEFAULT} is used implicitly.  If the
725:             * store is transactional, the cursor may not be used to update or delete
726:             * entities.</p>
727:             *
728:             * @param fromKey is the lower bound of the key range, or null if the range
729:             * has no lower bound.
730:             *
731:             * @param fromInclusive is true if keys greater than or equal to fromKey
732:             * should be included in the key range, or false if only keys greater than
733:             * fromKey should be included.
734:             *
735:             * @param toKey is the upper bound of the key range, or null if the range
736:             * has no upper bound.
737:             *
738:             * @param toInclusive is true if keys less than or equal to toKey should be
739:             * included in the key range, or false if only keys less than toKey should
740:             * be included.
741:             *
742:             * @return the cursor.
743:             */
744:            EntityCursor<K> keys(K fromKey, boolean fromInclusive, K toKey,
745:                    boolean toInclusive) throws DatabaseException;
746:
747:            /**
748:             * Opens a cursor for traversing keys in a key range.
749:             *
750:             * @param txn the transaction used to protect all operations performed with
751:             * the cursor, or null if the operations should not be transaction
752:             * protected.  If null is specified and the store is transactional, the
753:             * cursor may not be used to update or delete entities.
754:             *
755:             * @param fromKey is the lower bound of the key range, or null if the range
756:             * has no lower bound.
757:             *
758:             * @param fromInclusive is true if keys greater than or equal to fromKey
759:             * should be included in the key range, or false if only keys greater than
760:             * fromKey should be included.
761:             *
762:             * @param toKey is the upper bound of the key range, or null if the range
763:             * has no upper bound.
764:             *
765:             * @param toInclusive is true if keys less than or equal to toKey should be
766:             * included in the key range, or false if only keys less than toKey should
767:             * be included.
768:             *
769:             * @param config the cursor configuration that determines the default lock
770:             * mode used for all cursor operations, or null to implicitly use {@link
771:             * CursorConfig#DEFAULT}.
772:             *
773:             * @return the cursor.
774:             */
775:            EntityCursor<K> keys(Transaction txn, K fromKey,
776:                    boolean fromInclusive, K toKey, boolean toInclusive,
777:                    CursorConfig config) throws DatabaseException;
778:
779:            /**
780:             * Opens a cursor for traversing entities in a key range.
781:             *
782:             * <p>The operations performed with the cursor will not be transaction
783:             * protected, and {@link CursorConfig#DEFAULT} is used implicitly.  If the
784:             * store is transactional, the cursor may not be used to update or delete
785:             * entities.</p>
786:             *
787:             * @param fromKey is the lower bound of the key range, or null if the range
788:             * has no lower bound.
789:             *
790:             * @param fromInclusive is true if keys greater than or equal to fromKey
791:             * should be included in the key range, or false if only keys greater than
792:             * fromKey should be included.
793:             *
794:             * @param toKey is the upper bound of the key range, or null if the range
795:             * has no upper bound.
796:             *
797:             * @param toInclusive is true if keys less than or equal to toKey should be
798:             * included in the key range, or false if only keys less than toKey should
799:             * be included.
800:             *
801:             * @return the cursor.
802:             */
803:            EntityCursor<V> entities(K fromKey, boolean fromInclusive, K toKey,
804:                    boolean toInclusive) throws DatabaseException;
805:
806:            /**
807:             * Opens a cursor for traversing entities in a key range.
808:             *
809:             * @param txn the transaction used to protect all operations performed with
810:             * the cursor, or null if the operations should not be transaction
811:             * protected.  If null is specified and the store is transactional, the
812:             * cursor may not be used to update or delete entities.
813:             *
814:             * @param fromKey is the lower bound of the key range, or null if the range
815:             * has no lower bound.
816:             *
817:             * @param fromInclusive is true if keys greater than or equal to fromKey
818:             * should be included in the key range, or false if only keys greater than
819:             * fromKey should be included.
820:             *
821:             * @param toKey is the upper bound of the key range, or null if the range
822:             * has no upper bound.
823:             *
824:             * @param toInclusive is true if keys less than or equal to toKey should be
825:             * included in the key range, or false if only keys less than toKey should
826:             * be included.
827:             *
828:             * @param config the cursor configuration that determines the default lock
829:             * mode used for all cursor operations, or null to implicitly use {@link
830:             * CursorConfig#DEFAULT}.
831:             *
832:             * @return the cursor.
833:             */
834:            EntityCursor<V> entities(Transaction txn, K fromKey,
835:                    boolean fromInclusive, K toKey, boolean toInclusive,
836:                    CursorConfig config) throws DatabaseException;
837:
838:            /*
839:             * Opens a cursor for traversing all keys in this index in arbitrary order.
840:             *
841:             * <p>Normally entities and keys are returned in key order.  This method
842:             * takes advantage of optimizations in the Berkeley DB engine to return
843:             * entities in physical storage order, potentially decreasing the amount of
844:             * physical I/O.</p>
845:             *
846:             * <p>The operations performed with the cursor will not be transaction
847:             * protected, and {@link CursorConfig#DEFAULT} is used implicitly.</p>
848:             *
849:             * @param selector the filter for selecting keys to be returned, or null
850:             * to select all keys.
851:             *
852:             * @return the cursor.
853:             *
854:            ForwardCursor<K> unsortedKeys(KeySelector<K> selector)
855:                throws DatabaseException;
856:             */
857:
858:            /*
859:             * Opens a cursor for traversing all keys in this index in arbitrary order.
860:             *
861:             * <p>Normally entities and keys are returned in key order.  This method
862:             * takes advantage of optimizations in the Berkeley DB engine to return
863:             * entities in physical storage order, potentially decreasing the amount of
864:             * physical I/O.</p>
865:             *
866:             * @param txn the transaction used to protect all operations performed with
867:             * the cursor, or null if the operations should not be transaction
868:             * protected.
869:             *
870:             * @param selector the filter for selecting keys to be returned, or null
871:             * to select all keys.
872:             *
873:             * @param config the cursor configuration that determines the default lock
874:             * mode used for all cursor operations, or null to implicitly use {@link
875:             * CursorConfig#DEFAULT}.
876:             *
877:             * @return the cursor.
878:             *
879:            ForwardCursor<K> unsortedKeys(Transaction txn,
880:                                          KeySelector<K> selector,
881:                                          CursorConfig config)
882:                throws DatabaseException;
883:             */
884:
885:            /*
886:             * Opens a cursor for traversing all entities in this index in arbitrary
887:             * order.
888:             *
889:             * <p>Normally entities and keys are returned in key order.  This method
890:             * takes advantage of optimizations in the Berkeley DB engine to return
891:             * entities in physical storage order, potentially decreasing the amount of
892:             * physical I/O.</p>
893:             *
894:             * <p>The operations performed with the cursor will not be transaction
895:             * protected, and {@link CursorConfig#DEFAULT} is used implicitly.</p>
896:
897:             * @param selector the filter for selecting keys to be returned, or null
898:             * to select all keys.
899:             *
900:             * @return the cursor.
901:             *
902:            ForwardCursor<V> unsortedEntities(KeySelector<K> selector)
903:                throws DatabaseException;
904:             */
905:
906:            /*
907:             * Opens a cursor for traversing all entities in this index in arbitrary
908:             * order.
909:             *
910:             * <p>Normally entities and keys are returned in key order.  This method
911:             * takes advantage of optimizations in the Berkeley DB engine to return
912:             * entities in physical storage order, potentially decreasing the amount of
913:             * physical I/O.</p>
914:             *
915:             * @param txn the transaction used to protect all operations performed with
916:             * the cursor, or null if the operations should not be transaction
917:             * protected.
918:             *
919:             * @param selector the filter for selecting keys to be returned, or null
920:             * to select all keys.
921:             *
922:             * @param config the cursor configuration that determines the default lock
923:             * mode used for all cursor operations, or null to implicitly use {@link
924:             * CursorConfig#DEFAULT}.
925:             *
926:             * @return the cursor.
927:             *
928:            ForwardCursor<V> unsortedEntities(Transaction txn,
929:                                              KeySelector<K> selector,
930:                                              CursorConfig config)
931:                throws DatabaseException;
932:             */
933:
934:            /**
935:             * Returns a standard Java map based on this entity index.  The {@link
936:             * StoredMap} returned is defined by the {@linkplain
937:             * com.sleepycat.collections Collections API}.  Stored collections conform
938:             * to the standard Java collections framework interface.
939:             *
940:             * @return the map.
941:             */
942:            Map<K, V> map();
943:
944:            /**
945:             * Returns a standard Java sorted map based on this entity index.  The
946:             * {@link StoredSortedMap} returned is defined by the {@linkplain
947:             * com.sleepycat.collections Collections API}.  Stored collections conform
948:             * to the standard Java collections framework interface.
949:             *
950:             * @return the map.
951:             */
952:            SortedMap<K, V> sortedMap();
953:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.