Source Code Cross Referenced for IndexTest.java in  » JMX » je » com » sleepycat » persist » test » 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.test 
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: IndexTest.java,v 1.15.2.3 2008/01/07 15:14:35 cwl Exp $
007:         */
008:
009:        package com.sleepycat.persist.test;
010:
011:        import static com.sleepycat.persist.model.Relationship.MANY_TO_MANY;
012:        import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE;
013:        import static com.sleepycat.persist.model.Relationship.ONE_TO_MANY;
014:        import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE;
015:
016:        import java.util.ArrayList;
017:        import java.util.Collection;
018:        import java.util.Collections;
019:        import java.util.Iterator;
020:        import java.util.List;
021:        import java.util.Set;
022:        import java.util.SortedMap;
023:        import java.util.SortedSet;
024:        import java.util.TreeMap;
025:        import java.util.TreeSet;
026:
027:        import junit.framework.Test;
028:
029:        import com.sleepycat.collections.MapEntryParameter;
030:        import com.sleepycat.je.DatabaseException;
031:        import com.sleepycat.je.Transaction;
032:        import com.sleepycat.je.test.TxnTestCase;
033:        import com.sleepycat.persist.EntityCursor;
034:        import com.sleepycat.persist.EntityIndex;
035:        import com.sleepycat.persist.EntityStore;
036:        import com.sleepycat.persist.PrimaryIndex;
037:        import com.sleepycat.persist.SecondaryIndex;
038:        import com.sleepycat.persist.StoreConfig;
039:        import com.sleepycat.persist.model.Entity;
040:        import com.sleepycat.persist.model.PrimaryKey;
041:        import com.sleepycat.persist.model.SecondaryKey;
042:        import com.sleepycat.persist.raw.RawObject;
043:        import com.sleepycat.persist.raw.RawStore;
044:        import com.sleepycat.persist.raw.RawType;
045:
046:        /**
047:         * Tests EntityIndex and EntityCursor in all their permutations.
048:         *
049:         * @author Mark Hayes
050:         */
051:        public class IndexTest extends TxnTestCase {
052:
053:            private static final int N_RECORDS = 5;
054:            private static final int THREE_TO_ONE = 3;
055:
056:            public static Test suite() {
057:                return txnTestSuite(IndexTest.class, null, null);
058:                //new String[] { TxnTestCase.TXN_NULL});
059:            }
060:
061:            private EntityStore store;
062:            private PrimaryIndex<Integer, MyEntity> primary;
063:            private SecondaryIndex<Integer, Integer, MyEntity> oneToOne;
064:            private SecondaryIndex<Integer, Integer, MyEntity> manyToOne;
065:            private SecondaryIndex<Integer, Integer, MyEntity> oneToMany;
066:            private SecondaryIndex<Integer, Integer, MyEntity> manyToMany;
067:            private RawStore rawStore;
068:            private RawType entityType;
069:            private PrimaryIndex<Object, RawObject> primaryRaw;
070:            private SecondaryIndex<Object, Object, RawObject> oneToOneRaw;
071:            private SecondaryIndex<Object, Object, RawObject> manyToOneRaw;
072:            private SecondaryIndex<Object, Object, RawObject> oneToManyRaw;
073:            private SecondaryIndex<Object, Object, RawObject> manyToManyRaw;
074:
075:            /**
076:             * Opens the store.
077:             */
078:            private void open() throws DatabaseException {
079:
080:                StoreConfig config = new StoreConfig();
081:                config.setAllowCreate(envConfig.getAllowCreate());
082:                config.setTransactional(envConfig.getTransactional());
083:
084:                store = new EntityStore(env, "test", config);
085:
086:                primary = store.getPrimaryIndex(Integer.class, MyEntity.class);
087:                oneToOne = store.getSecondaryIndex(primary, Integer.class,
088:                        "oneToOne");
089:                manyToOne = store.getSecondaryIndex(primary, Integer.class,
090:                        "manyToOne");
091:                oneToMany = store.getSecondaryIndex(primary, Integer.class,
092:                        "oneToMany");
093:                manyToMany = store.getSecondaryIndex(primary, Integer.class,
094:                        "manyToMany");
095:
096:                assertNotNull(primary);
097:                assertNotNull(oneToOne);
098:                assertNotNull(manyToOne);
099:                assertNotNull(oneToMany);
100:                assertNotNull(manyToMany);
101:
102:                rawStore = new RawStore(env, "test", config);
103:                String clsName = MyEntity.class.getName();
104:                entityType = rawStore.getModel().getRawType(clsName);
105:                assertNotNull(entityType);
106:
107:                primaryRaw = rawStore.getPrimaryIndex(clsName);
108:                oneToOneRaw = rawStore.getSecondaryIndex(clsName, "oneToOne");
109:                manyToOneRaw = rawStore.getSecondaryIndex(clsName, "manyToOne");
110:                oneToManyRaw = rawStore.getSecondaryIndex(clsName, "oneToMany");
111:                manyToManyRaw = rawStore.getSecondaryIndex(clsName,
112:                        "manyToMany");
113:
114:                assertNotNull(primaryRaw);
115:                assertNotNull(oneToOneRaw);
116:                assertNotNull(manyToOneRaw);
117:                assertNotNull(oneToManyRaw);
118:                assertNotNull(manyToManyRaw);
119:            }
120:
121:            /**
122:             * Closes the store.
123:             */
124:            private void close() throws DatabaseException {
125:
126:                store.close();
127:                store = null;
128:                rawStore.close();
129:                rawStore = null;
130:            }
131:
132:            /**
133:             * The store must be closed before closing the environment.
134:             */
135:            public void tearDown() throws Exception {
136:
137:                try {
138:                    if (rawStore != null) {
139:                        rawStore.close();
140:                    }
141:                } catch (Throwable e) {
142:                    System.out.println("During tearDown: " + e);
143:                }
144:                try {
145:                    if (store != null) {
146:                        store.close();
147:                    }
148:                } catch (Throwable e) {
149:                    System.out.println("During tearDown: " + e);
150:                }
151:                store = null;
152:                rawStore = null;
153:                super .tearDown();
154:            }
155:
156:            /**
157:             * Primary keys: {0, 1, 2, 3, 4}
158:             */
159:            public void testPrimary() throws DatabaseException {
160:
161:                SortedMap<Integer, SortedSet<Integer>> expected = new TreeMap<Integer, SortedSet<Integer>>();
162:
163:                for (int priKey = 0; priKey < N_RECORDS; priKey += 1) {
164:                    SortedSet<Integer> values = new TreeSet<Integer>();
165:                    values.add(priKey);
166:                    expected.put(priKey, values);
167:                }
168:
169:                open();
170:                addEntities(primary);
171:                checkIndex(primary, expected, keyGetter, entityGetter);
172:                checkIndex(primaryRaw, expected, rawKeyGetter, rawEntityGetter);
173:
174:                /* Close and reopen, then recheck indices. */
175:                close();
176:                open();
177:                checkIndex(primary, expected, keyGetter, entityGetter);
178:                checkIndex(primaryRaw, expected, rawKeyGetter, rawEntityGetter);
179:
180:                /* Check primary delete, last key first for variety. */
181:                for (int priKey = N_RECORDS - 1; priKey >= 0; priKey -= 1) {
182:                    boolean useRaw = ((priKey & 1) != 0);
183:                    Transaction txn = txnBegin();
184:                    if (useRaw) {
185:                        primaryRaw.delete(txn, priKey);
186:                    } else {
187:                        primary.delete(txn, priKey);
188:                    }
189:                    txnCommit(txn);
190:                    expected.remove(priKey);
191:                    checkIndex(primary, expected, keyGetter, entityGetter);
192:                }
193:                checkAllEmpty();
194:
195:                /* Check PrimaryIndex put operations. */
196:                MyEntity e;
197:                Transaction txn = txnBegin();
198:                /* put() */
199:                e = primary.put(txn, new MyEntity(1));
200:                assertNull(e);
201:                e = primary.get(txn, 1, null);
202:                assertEquals(1, e.key);
203:                /* putNoReturn() */
204:                primary.putNoReturn(txn, new MyEntity(2));
205:                e = primary.get(txn, 2, null);
206:                assertEquals(2, e.key);
207:                /* putNoOverwrite */
208:                assertTrue(!primary.putNoOverwrite(txn, new MyEntity(1)));
209:                assertTrue(!primary.putNoOverwrite(txn, new MyEntity(2)));
210:                assertTrue(primary.putNoOverwrite(txn, new MyEntity(3)));
211:                e = primary.get(txn, 3, null);
212:                assertEquals(3, e.key);
213:                txnCommit(txn);
214:                close();
215:            }
216:
217:            /**
218:             * { 0:0, 1:-1, 2:-2, 3:-3, 4:-4 }
219:             */
220:            public void testOneToOne() throws DatabaseException {
221:
222:                SortedMap<Integer, SortedSet<Integer>> expected = new TreeMap<Integer, SortedSet<Integer>>();
223:
224:                for (int priKey = 0; priKey < N_RECORDS; priKey += 1) {
225:                    SortedSet<Integer> values = new TreeSet<Integer>();
226:                    values.add(priKey);
227:                    Integer secKey = (-priKey);
228:                    expected.put(secKey, values);
229:                }
230:
231:                open();
232:                addEntities(primary);
233:                checkSecondary(oneToOne, oneToOneRaw, expected);
234:                checkDelete(oneToOne, oneToOneRaw, expected);
235:                close();
236:            }
237:
238:            /**
239:             * { 0:0, 1:1, 2:2, 3:0, 4:1 }
240:             */
241:            public void testManyToOne() throws DatabaseException {
242:
243:                SortedMap<Integer, SortedSet<Integer>> expected = new TreeMap<Integer, SortedSet<Integer>>();
244:
245:                for (int priKey = 0; priKey < N_RECORDS; priKey += 1) {
246:                    Integer secKey = priKey % THREE_TO_ONE;
247:                    SortedSet<Integer> values = expected.get(secKey);
248:                    if (values == null) {
249:                        values = new TreeSet<Integer>();
250:                        expected.put(secKey, values);
251:                    }
252:                    values.add(priKey);
253:                }
254:
255:                open();
256:                addEntities(primary);
257:                checkSecondary(manyToOne, manyToOneRaw, expected);
258:                checkDelete(manyToOne, manyToOneRaw, expected);
259:                close();
260:            }
261:
262:            /**
263:             * { 0:{}, 1:{10}, 2:{20,21}, 3:{30,31,32}, 4:{40,41,42,43}
264:             */
265:            public void testOneToMany() throws DatabaseException {
266:
267:                SortedMap<Integer, SortedSet<Integer>> expected = new TreeMap<Integer, SortedSet<Integer>>();
268:
269:                for (int priKey = 0; priKey < N_RECORDS; priKey += 1) {
270:                    for (int i = 0; i < priKey; i += 1) {
271:                        Integer secKey = (N_RECORDS * priKey) + i;
272:                        SortedSet<Integer> values = expected.get(secKey);
273:                        if (values == null) {
274:                            values = new TreeSet<Integer>();
275:                            expected.put(secKey, values);
276:                        }
277:                        values.add(priKey);
278:                    }
279:                }
280:
281:                open();
282:                addEntities(primary);
283:                checkSecondary(oneToMany, oneToManyRaw, expected);
284:                checkDelete(oneToMany, oneToManyRaw, expected);
285:                close();
286:            }
287:
288:            /**
289:             * { 0:{}, 1:{0}, 2:{0,1}, 3:{0,1,2}, 4:{0,1,2,3}
290:             */
291:            public void testManyToMany() throws DatabaseException {
292:
293:                SortedMap<Integer, SortedSet<Integer>> expected = new TreeMap<Integer, SortedSet<Integer>>();
294:
295:                for (int priKey = 0; priKey < N_RECORDS; priKey += 1) {
296:                    for (int i = 0; i < priKey; i += 1) {
297:                        Integer secKey = i;
298:                        SortedSet<Integer> values = expected.get(secKey);
299:                        if (values == null) {
300:                            values = new TreeSet<Integer>();
301:                            expected.put(secKey, values);
302:                        }
303:                        values.add(priKey);
304:                    }
305:                }
306:
307:                open();
308:                addEntities(primary);
309:                checkSecondary(manyToMany, manyToManyRaw, expected);
310:                checkDelete(manyToMany, manyToManyRaw, expected);
311:                close();
312:            }
313:
314:            private void addEntities(PrimaryIndex<Integer, MyEntity> primary)
315:                    throws DatabaseException {
316:
317:                Transaction txn = txnBegin();
318:                for (int priKey = 0; priKey < N_RECORDS; priKey += 1) {
319:                    MyEntity prev = primary.put(txn, new MyEntity(priKey));
320:                    assertNull(prev);
321:                }
322:                txnCommit(txn);
323:            }
324:
325:            private void checkDelete(
326:                    SecondaryIndex<Integer, Integer, MyEntity> index,
327:                    SecondaryIndex<Object, Object, RawObject> indexRaw,
328:                    SortedMap<Integer, SortedSet<Integer>> expected)
329:                    throws DatabaseException {
330:
331:                SortedMap<Integer, SortedSet<Integer>> expectedSubIndex = new TreeMap<Integer, SortedSet<Integer>>();
332:
333:                while (expected.size() > 0) {
334:                    Integer delSecKey = expected.firstKey();
335:                    SortedSet<Integer> deletedPriKeys = expected
336:                            .remove(delSecKey);
337:                    for (SortedSet<Integer> priKeys : expected.values()) {
338:                        priKeys.removeAll(deletedPriKeys);
339:                    }
340:                    Transaction txn = txnBegin();
341:                    boolean deleted = index.delete(txn, delSecKey);
342:                    assertEquals(deleted, !deletedPriKeys.isEmpty());
343:                    deleted = index.delete(txn, delSecKey);
344:                    assertTrue(!deleted);
345:                    assertNull(index.get(txn, delSecKey, null));
346:                    txnCommit(txn);
347:                    checkSecondary(index, indexRaw, expected);
348:                }
349:
350:                /*
351:                 * Delete remaining records so that the primary index is empty.  Use
352:                 * the RawStore for variety.
353:                 */
354:                Transaction txn = txnBegin();
355:                for (int priKey = 0; priKey < N_RECORDS; priKey += 1) {
356:                    primaryRaw.delete(txn, priKey);
357:                }
358:                txnCommit(txn);
359:                checkAllEmpty();
360:            }
361:
362:            private void checkSecondary(
363:                    SecondaryIndex<Integer, Integer, MyEntity> index,
364:                    SecondaryIndex<Object, Object, RawObject> indexRaw,
365:                    SortedMap<Integer, SortedSet<Integer>> expected)
366:                    throws DatabaseException {
367:
368:                checkIndex(index, expected, keyGetter, entityGetter);
369:                checkIndex(index.keysIndex(), expected, keyGetter, keyGetter);
370:
371:                checkIndex(indexRaw, expected, rawKeyGetter, rawEntityGetter);
372:                checkIndex(indexRaw.keysIndex(), expected, rawKeyGetter,
373:                        rawKeyGetter);
374:
375:                SortedMap<Integer, SortedSet<Integer>> expectedSubIndex = new TreeMap<Integer, SortedSet<Integer>>();
376:
377:                for (Integer secKey : expected.keySet()) {
378:                    expectedSubIndex.clear();
379:                    for (Integer priKey : expected.get(secKey)) {
380:                        SortedSet<Integer> values = new TreeSet<Integer>();
381:                        values.add(priKey);
382:                        expectedSubIndex.put(priKey, values);
383:                    }
384:                    checkIndex(index.subIndex(secKey), expectedSubIndex,
385:                            keyGetter, entityGetter);
386:                    checkIndex(indexRaw.subIndex(secKey), expectedSubIndex,
387:                            rawKeyGetter, rawEntityGetter);
388:                }
389:            }
390:
391:            private <K, V> void checkIndex(EntityIndex<K, V> index,
392:                    SortedMap<Integer, SortedSet<Integer>> expected,
393:                    Getter<K> kGetter, Getter<V> vGetter)
394:                    throws DatabaseException {
395:
396:                SortedMap<K, V> map = index.sortedMap();
397:
398:                Transaction txn = txnBegin();
399:                for (int i : expected.keySet()) {
400:                    K k = kGetter.fromInt(i);
401:                    SortedSet<Integer> dups = expected.get(i);
402:                    if (dups.isEmpty()) {
403:
404:                        /* EntityIndex */
405:                        V v = index.get(txn, k, null);
406:                        assertNull(v);
407:                        assertTrue(!index.contains(txn, k, null));
408:
409:                        /* Map/Collection */
410:                        v = map.get(i);
411:                        assertNull(v);
412:                        assertTrue(!map.containsKey(i));
413:                    } else {
414:                        int j = dups.first();
415:
416:                        /* EntityIndex */
417:                        V v = index.get(txn, k, null);
418:                        assertNotNull(v);
419:                        assertEquals(j, vGetter.getKey(v));
420:                        assertTrue(index.contains(txn, k, null));
421:
422:                        /* Map/Collection */
423:                        v = map.get(i);
424:                        assertNotNull(v);
425:                        assertEquals(j, vGetter.getKey(v));
426:                        assertTrue(map.containsKey(i));
427:                        assertTrue("" + i + ' ' + j + ' ' + v + ' ' + map, map
428:                                .containsValue(v));
429:                        assertTrue(map.keySet().contains(i));
430:                        assertTrue(map.values().contains(v));
431:                        assertTrue(map.entrySet().contains(
432:                                new MapEntryParameter(i, v)));
433:                    }
434:                }
435:                txnCommit(txn);
436:
437:                int keysSize = expandKeySize(expected);
438:                int valuesSize = expandValueSize(expected);
439:
440:                /* EntityIndex.count */
441:                assertEquals("keysSize=" + keysSize, (long) valuesSize, index
442:                        .count());
443:
444:                /* Map/Collection size */
445:                assertEquals(valuesSize, map.size());
446:                assertEquals(valuesSize, map.values().size());
447:                assertEquals(valuesSize, map.entrySet().size());
448:                assertEquals(keysSize, map.keySet().size());
449:
450:                /* Map/Collection isEmpty */
451:                assertEquals(valuesSize == 0, map.isEmpty());
452:                assertEquals(valuesSize == 0, map.values().isEmpty());
453:                assertEquals(valuesSize == 0, map.entrySet().isEmpty());
454:                assertEquals(keysSize == 0, map.keySet().isEmpty());
455:
456:                txn = txnBeginCursor();
457:
458:                /* Unconstrained cursors. */
459:                checkCursor(index.keys(txn, null), map.keySet(), true,
460:                        expandKeys(expected), kGetter);
461:                checkCursor(index.entities(txn, null), map.values(), false,
462:                        expandValues(expected), vGetter);
463:
464:                /* Range cursors. */
465:                if (expected.isEmpty()) {
466:                    checkOpenRanges(txn, 0, index, expected, kGetter, vGetter);
467:                    checkClosedRanges(txn, 0, 1, index, expected, kGetter,
468:                            vGetter);
469:                } else {
470:                    int firstKey = expected.firstKey();
471:                    int lastKey = expected.lastKey();
472:                    for (int i = firstKey - 1; i <= lastKey + 1; i += 1) {
473:                        checkOpenRanges(txn, i, index, expected, kGetter,
474:                                vGetter);
475:                        int j = i + 1;
476:                        if (j < lastKey + 1) {
477:                            checkClosedRanges(txn, i, j, index, expected,
478:                                    kGetter, vGetter);
479:                        }
480:                    }
481:                }
482:
483:                txnCommit(txn);
484:            }
485:
486:            private <K, V> void checkOpenRanges(Transaction txn, int i,
487:                    EntityIndex<K, V> index,
488:                    SortedMap<Integer, SortedSet<Integer>> expected,
489:                    Getter<K> kGetter, Getter<V> vGetter)
490:                    throws DatabaseException {
491:
492:                SortedMap<K, V> map = index.sortedMap();
493:                SortedMap<Integer, SortedSet<Integer>> rangeExpected;
494:                K k = kGetter.fromInt(i);
495:                K kPlusOne = kGetter.fromInt(i + 1);
496:
497:                /* Head range exclusive. */
498:                rangeExpected = expected.headMap(i);
499:                checkCursor(index.keys(txn, null, false, k, false, null), map
500:                        .headMap(k).keySet(), true, expandKeys(rangeExpected),
501:                        kGetter);
502:                checkCursor(index.entities(txn, null, false, k, false, null),
503:                        map.headMap(k).values(), false,
504:                        expandValues(rangeExpected), vGetter);
505:
506:                /* Head range inclusive. */
507:                rangeExpected = expected.headMap(i + 1);
508:                checkCursor(index.keys(txn, null, false, k, true, null), map
509:                        .headMap(kPlusOne).keySet(), true,
510:                        expandKeys(rangeExpected), kGetter);
511:                checkCursor(index.entities(txn, null, false, k, true, null),
512:                        map.headMap(kPlusOne).values(), false,
513:                        expandValues(rangeExpected), vGetter);
514:
515:                /* Tail range exclusive. */
516:                rangeExpected = expected.tailMap(i + 1);
517:                checkCursor(index.keys(txn, k, false, null, false, null), map
518:                        .tailMap(kPlusOne).keySet(), true,
519:                        expandKeys(rangeExpected), kGetter);
520:                checkCursor(index.entities(txn, k, false, null, false, null),
521:                        map.tailMap(kPlusOne).values(), false,
522:                        expandValues(rangeExpected), vGetter);
523:
524:                /* Tail range inclusive. */
525:                rangeExpected = expected.tailMap(i);
526:                checkCursor(index.keys(txn, k, true, null, false, null), map
527:                        .tailMap(k).keySet(), true, expandKeys(rangeExpected),
528:                        kGetter);
529:                checkCursor(index.entities(txn, k, true, null, false, null),
530:                        map.tailMap(k).values(), false,
531:                        expandValues(rangeExpected), vGetter);
532:            }
533:
534:            private <K, V> void checkClosedRanges(Transaction txn, int i,
535:                    int j, EntityIndex<K, V> index,
536:                    SortedMap<Integer, SortedSet<Integer>> expected,
537:                    Getter<K> kGetter, Getter<V> vGetter)
538:                    throws DatabaseException {
539:
540:                SortedMap<K, V> map = index.sortedMap();
541:                SortedMap<Integer, SortedSet<Integer>> rangeExpected;
542:                K k = kGetter.fromInt(i);
543:                K kPlusOne = kGetter.fromInt(i + 1);
544:                K l = kGetter.fromInt(j);
545:                K lPlusOne = kGetter.fromInt(j + 1);
546:
547:                /* Sub range exclusive. */
548:                rangeExpected = expected.subMap(i + 1, j);
549:                checkCursor(index.keys(txn, k, false, l, false, null), map
550:                        .subMap(kPlusOne, l).keySet(), true,
551:                        expandKeys(rangeExpected), kGetter);
552:                checkCursor(index.entities(txn, k, false, l, false, null), map
553:                        .subMap(kPlusOne, l).values(), false,
554:                        expandValues(rangeExpected), vGetter);
555:
556:                /* Sub range inclusive. */
557:                rangeExpected = expected.subMap(i, j + 1);
558:                checkCursor(index.keys(txn, k, true, l, true, null), map
559:                        .subMap(k, lPlusOne).keySet(), true,
560:                        expandKeys(rangeExpected), kGetter);
561:                checkCursor(index.entities(txn, k, true, l, true, null), map
562:                        .subMap(k, lPlusOne).values(), false,
563:                        expandValues(rangeExpected), vGetter);
564:            }
565:
566:            private List<List<Integer>> expandKeys(
567:                    SortedMap<Integer, SortedSet<Integer>> map) {
568:
569:                List<List<Integer>> list = new ArrayList<List<Integer>>();
570:                for (Integer key : map.keySet()) {
571:                    SortedSet<Integer> values = map.get(key);
572:                    List<Integer> dups = new ArrayList<Integer>();
573:                    for (int i = 0; i < values.size(); i += 1) {
574:                        dups.add(key);
575:                    }
576:                    list.add(dups);
577:                }
578:                return list;
579:            }
580:
581:            private List<List<Integer>> expandValues(
582:                    SortedMap<Integer, SortedSet<Integer>> map) {
583:
584:                List<List<Integer>> list = new ArrayList<List<Integer>>();
585:                for (SortedSet<Integer> values : map.values()) {
586:                    list.add(new ArrayList<Integer>(values));
587:                }
588:                return list;
589:            }
590:
591:            private int expandKeySize(SortedMap<Integer, SortedSet<Integer>> map) {
592:
593:                int size = 0;
594:                for (SortedSet<Integer> values : map.values()) {
595:                    if (values.size() > 0) {
596:                        size += 1;
597:                    }
598:                }
599:                return size;
600:            }
601:
602:            private int expandValueSize(
603:                    SortedMap<Integer, SortedSet<Integer>> map) {
604:
605:                int size = 0;
606:                for (SortedSet<Integer> values : map.values()) {
607:                    size += values.size();
608:                }
609:                return size;
610:            }
611:
612:            private <T> void checkCursor(EntityCursor<T> cursor,
613:                    Collection<T> collection, boolean collectionIsKeySet,
614:                    List<List<Integer>> expected, Getter<T> getter)
615:                    throws DatabaseException {
616:
617:                boolean first;
618:                boolean firstDup;
619:                Iterator<T> iterator = collection.iterator();
620:
621:                for (List<Integer> dups : expected) {
622:                    for (int i : dups) {
623:                        T o = cursor.next();
624:                        assertNotNull(o);
625:                        assertEquals(i, getter.getKey(o));
626:                        /* Value iterator over duplicates. */
627:                        if (!collectionIsKeySet) {
628:                            assertTrue(iterator.hasNext());
629:                            o = iterator.next();
630:                            assertNotNull(o);
631:                            assertEquals(i, getter.getKey(o));
632:                        }
633:                    }
634:                }
635:
636:                first = true;
637:                for (List<Integer> dups : expected) {
638:                    firstDup = true;
639:                    for (int i : dups) {
640:                        T o = first ? cursor.first() : (firstDup ? cursor
641:                                .next() : cursor.nextDup());
642:                        assertNotNull(o);
643:                        assertEquals(i, getter.getKey(o));
644:                        first = false;
645:                        firstDup = false;
646:                    }
647:                }
648:
649:                first = true;
650:                for (List<Integer> dups : expected) {
651:                    if (!dups.isEmpty()) {
652:                        int i = dups.get(0);
653:                        T o = first ? cursor.first() : cursor.nextNoDup();
654:                        assertNotNull(o);
655:                        assertEquals(i, getter.getKey(o));
656:                        /* Key iterator over non-duplicates. */
657:                        if (collectionIsKeySet) {
658:                            assertTrue(iterator.hasNext());
659:                            o = iterator.next();
660:                            assertNotNull(o);
661:                            assertEquals(i, getter.getKey(o));
662:                        }
663:                        first = false;
664:                    }
665:                }
666:
667:                List<List<Integer>> reversed = new ArrayList<List<Integer>>();
668:                for (List<Integer> dups : expected) {
669:                    ArrayList<Integer> reversedDups = new ArrayList<Integer>(
670:                            dups);
671:                    Collections.reverse(reversedDups);
672:                    reversed.add(reversedDups);
673:                }
674:                Collections.reverse(reversed);
675:
676:                first = true;
677:                for (List<Integer> dups : reversed) {
678:                    for (int i : dups) {
679:                        T o = first ? cursor.last() : cursor.prev();
680:                        assertNotNull(o);
681:                        assertEquals(i, getter.getKey(o));
682:                        first = false;
683:                    }
684:                }
685:
686:                first = true;
687:                for (List<Integer> dups : reversed) {
688:                    firstDup = true;
689:                    for (int i : dups) {
690:                        T o = first ? cursor.last() : (firstDup ? cursor.prev()
691:                                : cursor.prevDup());
692:                        assertNotNull(o);
693:                        assertEquals(i, getter.getKey(o));
694:                        first = false;
695:                        firstDup = false;
696:                    }
697:                }
698:
699:                first = true;
700:                for (List<Integer> dups : reversed) {
701:                    if (!dups.isEmpty()) {
702:                        int i = dups.get(0);
703:                        T o = first ? cursor.last() : cursor.prevNoDup();
704:                        assertNotNull(o);
705:                        assertEquals(i, getter.getKey(o));
706:                        first = false;
707:                    }
708:                }
709:
710:                cursor.close();
711:            }
712:
713:            private void checkAllEmpty() throws DatabaseException {
714:
715:                checkEmpty(primary);
716:                checkEmpty(oneToOne);
717:                checkEmpty(oneToMany);
718:                checkEmpty(manyToOne);
719:                checkEmpty(manyToMany);
720:            }
721:
722:            private <K, V> void checkEmpty(EntityIndex<K, V> index)
723:                    throws DatabaseException {
724:
725:                EntityCursor<K> keys = index.keys();
726:                assertNull(keys.next());
727:                assertTrue(!keys.iterator().hasNext());
728:                keys.close();
729:                EntityCursor<V> entities = index.entities();
730:                assertNull(entities.next());
731:                assertTrue(!entities.iterator().hasNext());
732:                entities.close();
733:            }
734:
735:            private interface Getter<T> {
736:                int getKey(T o);
737:
738:                T fromInt(int i);
739:            }
740:
741:            private static Getter<MyEntity> entityGetter = new Getter<MyEntity>() {
742:                public int getKey(MyEntity o) {
743:                    return o.key;
744:                }
745:
746:                public MyEntity fromInt(int i) {
747:                    throw new UnsupportedOperationException();
748:                }
749:            };
750:
751:            private static Getter<Integer> keyGetter = new Getter<Integer>() {
752:                public int getKey(Integer o) {
753:                    return o;
754:                }
755:
756:                public Integer fromInt(int i) {
757:                    return Integer.valueOf(i);
758:                }
759:            };
760:
761:            private static Getter<RawObject> rawEntityGetter = new Getter<RawObject>() {
762:                public int getKey(RawObject o) {
763:                    Object val = o.getValues().get("key");
764:                    return ((Integer) val).intValue();
765:                }
766:
767:                public RawObject fromInt(int i) {
768:                    throw new UnsupportedOperationException();
769:                }
770:            };
771:
772:            private static Getter<Object> rawKeyGetter = new Getter<Object>() {
773:                public int getKey(Object o) {
774:                    return ((Integer) o).intValue();
775:                }
776:
777:                public Object fromInt(int i) {
778:                    return Integer.valueOf(i);
779:                }
780:            };
781:
782:            @Entity
783:            private static class MyEntity {
784:
785:                @PrimaryKey
786:                private int key;
787:
788:                @SecondaryKey(relate=ONE_TO_ONE)
789:                private int oneToOne;
790:
791:                @SecondaryKey(relate=MANY_TO_ONE)
792:                private int manyToOne;
793:
794:                @SecondaryKey(relate=ONE_TO_MANY)
795:                private Set<Integer> oneToMany = new TreeSet<Integer>();
796:
797:                @SecondaryKey(relate=MANY_TO_MANY)
798:                private Set<Integer> manyToMany = new TreeSet<Integer>();
799:
800:                private MyEntity() {
801:                }
802:
803:                private MyEntity(int key) {
804:
805:                    /* example keys: {0, 1, 2, 3, 4} */
806:                    this .key = key;
807:
808:                    /* { 0:0, 1:-1, 2:-2, 3:-3, 4:-4 } */
809:                    oneToOne = -key;
810:
811:                    /* { 0:0, 1:1, 2:2, 3:0, 4:1 } */
812:                    manyToOne = key % THREE_TO_ONE;
813:
814:                    /* { 0:{}, 1:{10}, 2:{20,21}, 3:{30,31,32}, 4:{40,41,42,43} */
815:                    for (int i = 0; i < key; i += 1) {
816:                        oneToMany.add((N_RECORDS * key) + i);
817:                    }
818:
819:                    /* { 0:{}, 1:{0}, 2:{0,1}, 3:{0,1,2}, 4:{0,1,2,3} */
820:                    for (int i = 0; i < key; i += 1) {
821:                        manyToMany.add(i);
822:                    }
823:                }
824:
825:                @Override
826:                public String toString() {
827:                    return "MyEntity " + key;
828:                }
829:            }
830:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.