Source Code Cross Referenced for ReadAheadCache.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » ejb » plugins » cmp » jdbc » 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 » EJB Server JBoss 4.2.1 » server » org.jboss.ejb.plugins.cmp.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.ejb.plugins.cmp.jdbc;
023:
024:        import org.jboss.ejb.EntityEnterpriseContext;
025:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge;
026:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge;
027:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
028:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
029:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData;
030:        import org.jboss.logging.Logger;
031:        import org.jboss.tm.TransactionLocal;
032:
033:        import javax.transaction.Transaction;
034:        import javax.transaction.SystemException;
035:        import java.lang.ref.SoftReference;
036:        import java.util.Collection;
037:        import java.util.Collections;
038:        import java.util.HashMap;
039:        import java.util.HashSet;
040:        import java.util.Iterator;
041:        import java.util.LinkedList;
042:        import java.util.List;
043:        import java.util.Map;
044:
045:        /**
046:         * ReadAheadCache stores all of the data readahead for an entity.
047:         * Data is stored in the JDBCStoreManager entity tx data map on a per entity
048:         * basis. The read ahead data for each entity is stored with a soft reference.
049:         *
050:         * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
051:         * @version $Revision: 57209 $
052:         */
053:        public final class ReadAheadCache {
054:            /**
055:             * To simplify null values handling in the preloaded data pool we use
056:             * this value instead of 'null'
057:             */
058:            private static final Object NULL_VALUE = new Object();
059:
060:            private final JDBCStoreManager manager;
061:            private final Logger log;
062:
063:            private final TransactionLocal listMapTxLocal = new TransactionLocal() {
064:                protected Object initialValue() {
065:                    return new HashMap();
066:                }
067:
068:                public Transaction getTransaction() {
069:                    try {
070:                        return transactionManager.getTransaction();
071:                    } catch (SystemException e) {
072:                        throw new IllegalStateException(
073:                                "An error occured while getting the "
074:                                        + "transaction associated with the current thread: "
075:                                        + e);
076:                    }
077:                }
078:            };
079:
080:            private ListCache listCache;
081:            private int listCacheMax;
082:
083:            public ReadAheadCache(JDBCStoreManager manager) {
084:                this .manager = manager;
085:
086:                // Create the Log
087:                log = Logger.getLogger(this .getClass().getName() + "."
088:                        + manager.getMetaData().getName());
089:            }
090:
091:            public void create() {
092:                // Create the list cache
093:                listCacheMax = ((JDBCEntityBridge) manager.getEntityBridge())
094:                        .getListCacheMax();
095:                listCache = new ListCache(listCacheMax);
096:            }
097:
098:            public void start() {
099:            }
100:
101:            public void stop() {
102:                listCache.clear();
103:            }
104:
105:            public void destroy() {
106:                listCache = null;
107:            }
108:
109:            public void addFinderResults(List results,
110:                    JDBCReadAheadMetaData readahead) {
111:                if (listCacheMax == 0 || results.size() < 2) {
112:                    // nothing to see here... move along
113:                    return;
114:                }
115:
116:                Map listMap = getListMap();
117:                if (listMap == null) {
118:                    // no active transaction
119:                    return;
120:                }
121:
122:                if (log.isTraceEnabled()) {
123:                    log
124:                            .trace("Add finder results:" + " entity="
125:                                    + manager.getEntityBridge().getEntityName()
126:                                    + " results=" + results + " readahead="
127:                                    + readahead);
128:                }
129:
130:                // add the finder to the LRU list
131:                if (!readahead.isNone()) {
132:                    listCache.add(results);
133:                }
134:
135:                //
136:                // Create a map between the entity primary keys and the list.
137:                // The primary key will point to the last list added that contained the
138:                // primary key.
139:                //
140:                HashSet dereferencedResults = new HashSet();
141:                Iterator iter = results.iterator();
142:                for (int i = 0; iter.hasNext(); i++) {
143:                    Object pk = iter.next();
144:
145:                    // create the new entry object
146:                    EntityMapEntry entry;
147:                    if (readahead.isNone()) {
148:                        entry = new EntityMapEntry(0, Collections
149:                                .singletonList(pk), readahead);
150:                    } else {
151:                        entry = new EntityMapEntry(i, results, readahead);
152:                    }
153:
154:                    // Keep track of the results that have been dereferenced. Later we
155:                    // all results from the list cache that are no longer referenced.
156:                    EntityMapEntry oldInfo = (EntityMapEntry) listMap.put(pk,
157:                            entry);
158:                    if (oldInfo != null) {
159:                        dereferencedResults.add(oldInfo.results);
160:                    }
161:                }
162:
163:                //
164:                // Now we remove all lists from the list cache that are no longer
165:                // referenced in the list map.
166:                //
167:
168:                // if we don't have any dereferenced results at this point we are done
169:                if (dereferencedResults.isEmpty()) {
170:                    return;
171:                }
172:
173:                //
174:                // Go through the dereferenced results set and look at the PKs for each
175:                // dereferenced list.  If you find one key that references the
176:                // dereferenced list, remove it from the dereferenced results set and
177:                // move on to the next dereferenced results.
178:                //
179:                iter = dereferencedResults.iterator();
180:                while (iter.hasNext()) {
181:                    List dereferencedList = (List) iter.next();
182:
183:                    boolean listHasReference = false;
184:                    Iterator iter2 = dereferencedList.iterator();
185:                    while (!listHasReference && iter2.hasNext()) {
186:                        EntityMapEntry entry = (EntityMapEntry) listMap
187:                                .get(iter2.next());
188:                        if (entry != null && entry.results == dereferencedList) {
189:                            listHasReference = true;
190:                        }
191:                    }
192:
193:                    if (listHasReference) {
194:                        // this list does not have any references
195:                        iter.remove();
196:                    }
197:                }
198:
199:                // if we don't have any dereferenced results at this point we are done
200:                if (dereferencedResults.isEmpty()) {
201:                    return;
202:                }
203:
204:                // remove all results from the cache that are no longer referenced
205:                iter = dereferencedResults.iterator();
206:                while (iter.hasNext()) {
207:                    List list = (List) iter.next();
208:                    if (log.isTraceEnabled()) {
209:                        log.trace("Removing dereferenced results: " + list);
210:                    }
211:                    listCache.remove(list);
212:                }
213:            }
214:
215:            private void removeFinderResult(List results) {
216:                Map listMap = getListMap();
217:                if (listMap == null) {
218:                    // no active transaction
219:                    return;
220:                }
221:
222:                // remove the list from the list cache
223:                listCache.remove(results);
224:
225:                // remove all primary keys from the listMap that reference this list
226:                if (!listMap.isEmpty()) {
227:                    Iterator iter = listMap.values().iterator();
228:                    while (iter.hasNext()) {
229:                        EntityMapEntry entry = (EntityMapEntry) iter.next();
230:
231:                        // use == because only identity matters here
232:                        if (entry.results == results) {
233:                            iter.remove();
234:                        }
235:                    }
236:                }
237:            }
238:
239:            public EntityReadAheadInfo getEntityReadAheadInfo(Object pk) {
240:                Map listMap = getListMap();
241:                if (listMap == null) {
242:                    // no active transaction
243:                    return new EntityReadAheadInfo(Collections
244:                            .singletonList(pk));
245:                }
246:
247:                EntityMapEntry entry = (EntityMapEntry) getListMap().get(pk);
248:                if (entry != null) {
249:                    // we're using these results so promote it to the head of the
250:                    // LRU list
251:                    if (!entry.readahead.isNone()) {
252:                        listCache.promote(entry.results);
253:                    }
254:
255:                    // get the readahead metadata
256:                    JDBCReadAheadMetaData readahead = entry.readahead;
257:                    if (readahead == null) {
258:                        readahead = manager.getMetaData().getReadAhead();
259:                    }
260:
261:                    int from = entry.index;
262:                    int to = Math.min(entry.results.size(), entry.index
263:                            + readahead.getPageSize());
264:                    List loadKeys = entry.results.subList(from, to);
265:
266:                    return new EntityReadAheadInfo(loadKeys, readahead);
267:                } else {
268:                    return new EntityReadAheadInfo(Collections
269:                            .singletonList(pk));
270:                }
271:            }
272:
273:            /**
274:             * Loads all of the preloaded data for the ctx into it.
275:             * @param ctx the context that will be loaded
276:             * @return true if at least one field was loaded.
277:             */
278:            public boolean load(EntityEnterpriseContext ctx) {
279:                if (log.isTraceEnabled()) {
280:                    log.trace("load data:" + " entity="
281:                            + manager.getEntityBridge().getEntityName()
282:                            + " pk=" + ctx.getId());
283:                }
284:
285:                // get the preload data map
286:                Map preloadDataMap = getPreloadDataMap(ctx.getId(), false);
287:                if (preloadDataMap == null || preloadDataMap.isEmpty()) {
288:                    // no preloaded data for this entity
289:                    if (log.isTraceEnabled()) {
290:                        log.trace("No preload data found:" + " entity="
291:                                + manager.getEntityBridge().getEntityName()
292:                                + " pk=" + ctx.getId());
293:                    }
294:                    return false;
295:                }
296:
297:                boolean cleanReadAhead = manager.getMetaData()
298:                        .isCleanReadAheadOnLoad();
299:
300:                boolean loaded = false;
301:                JDBCCMRFieldBridge onlyOneSingleValuedCMR = null;
302:
303:                // iterate over the keys in the preloaded map
304:                Iterator iter = preloadDataMap.entrySet().iterator();
305:                while (iter.hasNext()) {
306:                    Map.Entry entry = (Map.Entry) iter.next();
307:                    Object field = entry.getKey();
308:
309:                    // get the value that was preloaded for this field
310:                    Object value = entry.getValue();
311:
312:                    // if we didn't get a value something is seriously hosed
313:                    if (value == null) {
314:                        throw new IllegalStateException(
315:                                "Preloaded value not found");
316:                    }
317:
318:                    if (cleanReadAhead) {
319:                        // remove this value from the preload cache as it is about to be loaded
320:                        iter.remove();
321:                    }
322:
323:                    // check for null value standin
324:                    if (value == NULL_VALUE) {
325:                        value = null;
326:                    }
327:
328:                    if (field instanceof  JDBCCMPFieldBridge) {
329:                        JDBCCMPFieldBridge cmpField = (JDBCCMPFieldBridge) field;
330:
331:                        if (!cmpField.isLoaded(ctx)) {
332:                            if (log.isTraceEnabled()) {
333:                                log.trace("Preloading data:"
334:                                        + " entity="
335:                                        + manager.getEntityBridge()
336:                                                .getEntityName() + " pk="
337:                                        + ctx.getId() + " cmpField="
338:                                        + cmpField.getFieldName());
339:                            }
340:
341:                            // set the value
342:                            cmpField.setInstanceValue(ctx, value);
343:
344:                            // mark this field clean as it's value was just loaded
345:                            cmpField.setClean(ctx);
346:
347:                            loaded = true;
348:                        } else {
349:                            if (log.isTraceEnabled()) {
350:                                log.trace("CMPField already loaded:"
351:                                        + " entity="
352:                                        + manager.getEntityBridge()
353:                                                .getEntityName() + " pk="
354:                                        + ctx.getId() + " cmpField="
355:                                        + cmpField.getFieldName());
356:                            }
357:                        }
358:                    } else if (field instanceof  JDBCCMRFieldBridge) {
359:                        JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge) field;
360:
361:                        if (!cmrField.isLoaded(ctx)) {
362:                            if (log.isTraceEnabled()) {
363:                                log.trace("Preloading data:"
364:                                        + " entity="
365:                                        + manager.getEntityBridge()
366:                                                .getEntityName() + " pk="
367:                                        + ctx.getId() + " cmrField="
368:                                        + cmrField.getFieldName());
369:                            }
370:
371:                            // set the value
372:                            cmrField.load(ctx, (List) value);
373:
374:                            // add the loaded list to the related entity's readahead cache
375:                            JDBCStoreManager relatedManager = (JDBCStoreManager) cmrField
376:                                    .getRelatedCMRField().getManager();
377:                            ReadAheadCache relatedReadAheadCache = relatedManager
378:                                    .getReadAheadCache();
379:                            relatedReadAheadCache.addFinderResults(
380:                                    (List) value, cmrField.getReadAhead());
381:
382:                            if (!loaded) {
383:                                // this is a hack to fix on-load read-ahead for 1:m relationships
384:                                if (cmrField.isSingleValued()
385:                                        && onlyOneSingleValuedCMR == null) {
386:                                    onlyOneSingleValuedCMR = cmrField;
387:                                } else {
388:                                    loaded = true;
389:                                }
390:                            }
391:                        } else {
392:                            if (log.isTraceEnabled()) {
393:                                log.trace("CMRField already loaded:"
394:                                        + " entity="
395:                                        + manager.getEntityBridge()
396:                                                .getEntityName() + " pk="
397:                                        + ctx.getId() + " cmrField="
398:                                        + cmrField.getFieldName());
399:                            }
400:                        }
401:                    }
402:                }
403:
404:                if (cleanReadAhead) {
405:                    // remove all preload data map as all of the data has been loaded
406:                    manager.removeEntityTxData(new PreloadKey(ctx.getId()));
407:                }
408:
409:                return loaded;
410:            }
411:
412:            /**
413:             * Returns the cached value of a CMR field or null if nothing was cached for this field.
414:             * @param pk  primary key.
415:             * @param cmrField  the field to get the cached value for.
416:             * @return cached value for the <code>cmrField</code> or null if no value cached.
417:             */
418:            public Collection getCachedCMRValue(Object pk,
419:                    JDBCCMRFieldBridge cmrField) {
420:                Map preloadDataMap = getPreloadDataMap(pk, true);
421:                return (Collection) preloadDataMap.get(cmrField);
422:            }
423:
424:            /**
425:             * Add preloaded data for an entity within the scope of a transaction
426:             */
427:            public void addPreloadData(Object pk, JDBCFieldBridge field,
428:                    Object fieldValue) {
429:                if (field instanceof  JDBCCMRFieldBridge) {
430:                    if (fieldValue == null) {
431:                        fieldValue = Collections.EMPTY_LIST;
432:                    } else if (!(fieldValue instanceof  Collection)) {
433:                        fieldValue = Collections.singletonList(fieldValue);
434:                    }
435:                }
436:
437:                if (log.isTraceEnabled()) {
438:                    log.trace("Add preload data:" + " entity="
439:                            + manager.getEntityBridge().getEntityName()
440:                            + " pk=" + pk + " field=" + field.getFieldName());
441:                }
442:
443:                // convert null values to a null value standing object
444:                if (fieldValue == null) {
445:                    fieldValue = NULL_VALUE;
446:                }
447:
448:                // store the preloaded data
449:                Map preloadDataMap = getPreloadDataMap(pk, true);
450:                Object overriden = preloadDataMap.put(field, fieldValue);
451:
452:                if (log.isTraceEnabled() && overriden != null) {
453:                    log.trace("Overriding cached value " + overriden + " with "
454:                            + (fieldValue == NULL_VALUE ? null : fieldValue)
455:                            + ". pk=" + pk + ", field=" + field.getFieldName());
456:                }
457:            }
458:
459:            public void removeCachedData(Object primaryKey) {
460:                if (log.isTraceEnabled()) {
461:                    log.trace("Removing cached data for " + primaryKey);
462:                }
463:
464:                Map listMap = getListMap();
465:                if (listMap == null) {
466:                    // no active tx
467:                    return;
468:                }
469:
470:                // remove the preloaded data
471:                manager.removeEntityTxData(new PreloadKey(primaryKey));
472:
473:                // if the entity didn't have readahead entry, or it was read-ahead
474:                // none; return
475:                EntityMapEntry oldInfo = (EntityMapEntry) listMap
476:                        .remove(primaryKey);
477:                if (oldInfo == null || oldInfo.readahead.isNone()) {
478:                    return;
479:                }
480:
481:                // check to see if the dereferenced finder result is still referenced
482:                Iterator iter = listMap.values().iterator();
483:                while (iter.hasNext()) {
484:                    EntityMapEntry entry = (EntityMapEntry) iter.next();
485:
486:                    // use == because only identity matters here
487:                    if (entry.results == oldInfo.results) {
488:                        // ok it is still referenced
489:                        return;
490:                    }
491:                }
492:
493:                // a reference to the old finder set was not found so remove it
494:                if (log.isTraceEnabled()) {
495:                    log.trace("Removing dereferenced finder results: "
496:                            + oldInfo.results);
497:                }
498:                listCache.remove(oldInfo.results);
499:            }
500:
501:            /**
502:             * Gets the map of preloaded data.
503:             * @param entityPrimaryKey the primary key of the entity
504:             * @param create should a new preload data map be created if one is not found
505:             * @return the preload data map for null if one is not found
506:             */
507:            public Map getPreloadDataMap(Object entityPrimaryKey, boolean create) {
508:                //
509:                // Be careful in this code. A soft reference may be cleared at any time,
510:                // so don't check if a reference has a value and then get that value.
511:                // Instead get the value and then check if it is null.
512:                //
513:
514:                // create a preload key for the entity
515:                PreloadKey preloadKey = new PreloadKey(entityPrimaryKey);
516:
517:                // get the soft reference to the preload data map
518:                SoftReference ref = (SoftReference) manager
519:                        .getEntityTxData(preloadKey);
520:
521:                // did we get a reference
522:                if (ref != null) {
523:                    // get the  map from the reference
524:                    Map preloadDataMap = (Map) ref.get();
525:
526:                    // did we actually get a map? (will be null if it has been GC'd)
527:                    if (preloadDataMap != null) {
528:                        return preloadDataMap;
529:                    }
530:                }
531:
532:                //
533:                // at this point we did not get an existing value
534:                //
535:                // if we got a dead reference remove it
536:                if (ref != null) {
537:                    //log.info(manager.getMetaData().getName() + " was GC'd from read ahead");
538:                    manager.removeEntityTxData(preloadKey);
539:                }
540:
541:                // if we are not creating, we're done
542:                if (!create) {
543:                    return null;
544:                }
545:
546:                // create the new preload data map
547:                Map preloadDataMap = new HashMap();
548:
549:                // create new soft reference
550:                ref = new SoftReference(preloadDataMap);
551:
552:                // store the reference
553:                manager.putEntityTxData(preloadKey, ref);
554:
555:                // return the new preload data map
556:                return preloadDataMap;
557:            }
558:
559:            private Map getListMap() {
560:                return (Map) listMapTxLocal.get();
561:            }
562:
563:            private final class ListCache {
564:                private final TransactionLocal cacheTxLocal = new TransactionLocal() {
565:                    protected Object initialValue() {
566:                        return new LinkedList();
567:                    }
568:
569:                    public Transaction getTransaction() {
570:                        try {
571:                            return transactionManager.getTransaction();
572:                        } catch (SystemException e) {
573:                            throw new IllegalStateException(
574:                                    "An error occured while getting the "
575:                                            + "transaction associated with the current thread: "
576:                                            + e);
577:                        }
578:                    }
579:                };
580:                private int max;
581:
582:                public ListCache(int max) {
583:                    if (max < 0)
584:                        throw new IllegalArgumentException(
585:                                "list-cache-max is negative: " + max);
586:                    this .max = max;
587:                }
588:
589:                public void add(List list) {
590:                    if (max == 0) {
591:                        // we're not caching lists, so we're done
592:                        return;
593:                    }
594:
595:                    LinkedList cache = getCache();
596:                    if (cache == null)
597:                        return;
598:                    cache.addFirst(new IdentityObject(list));
599:
600:                    // shrink size to max
601:                    while (cache.size() > max) {
602:                        IdentityObject object = (IdentityObject) cache
603:                                .removeLast();
604:                        ageOut((List) object.getObject());
605:                    }
606:                }
607:
608:                public void promote(List list) {
609:                    if (max == 0) {
610:                        // we're not caching lists, so we're done
611:                        return;
612:                    }
613:
614:                    LinkedList cache = getCache();
615:                    if (cache == null)
616:                        return;
617:
618:                    IdentityObject object = new IdentityObject(list);
619:                    if (cache.remove(object)) {
620:                        // it was in the cache so add it to the front
621:                        cache.addFirst(object);
622:                    }
623:                }
624:
625:                public void remove(List list) {
626:                    if (max == 0) {
627:                        // we're not caching lists, so we're done
628:                        return;
629:                    }
630:                    LinkedList cache = getCache();
631:                    if (cache != null)
632:                        cache.remove(new IdentityObject(list));
633:                }
634:
635:                public void clear() {
636:                    if (max == 0) {
637:                        // we're not caching lists, so we're done
638:                        return;
639:                    }
640:                }
641:
642:                private void ageOut(List list) {
643:                    removeFinderResult(list);
644:                }
645:
646:                private LinkedList getCache() {
647:                    return (LinkedList) cacheTxLocal.get();
648:                }
649:            }
650:
651:            /**
652:             * Wraps an entity primary key, so it does not collide with other
653:             * data stored in the entityTxDataMap.
654:             */
655:            private static final class PreloadKey {
656:                private final Object entityPrimaryKey;
657:
658:                public PreloadKey(Object entityPrimaryKey) {
659:                    if (entityPrimaryKey == null) {
660:                        throw new IllegalArgumentException(
661:                                "Entity primary key is null");
662:                    }
663:                    this .entityPrimaryKey = entityPrimaryKey;
664:                }
665:
666:                public boolean equals(Object object) {
667:                    if (object instanceof  PreloadKey) {
668:                        PreloadKey preloadKey = (PreloadKey) object;
669:                        return preloadKey.entityPrimaryKey
670:                                .equals(entityPrimaryKey);
671:                    }
672:                    return false;
673:                }
674:
675:                public int hashCode() {
676:                    return entityPrimaryKey.hashCode();
677:                }
678:
679:                public String toString() {
680:                    return "PreloadKey: entityId=" + entityPrimaryKey;
681:                }
682:            }
683:
684:            private static final class EntityMapEntry {
685:                public final int index;
686:                public final List results;
687:                public final JDBCReadAheadMetaData readahead;
688:
689:                private EntityMapEntry(int index, List results,
690:                        JDBCReadAheadMetaData readahead) {
691:
692:                    this .index = index;
693:                    this .results = results;
694:                    this .readahead = readahead;
695:                }
696:            }
697:
698:            public final static class EntityReadAheadInfo {
699:                private final List loadKeys;
700:                private final JDBCReadAheadMetaData readahead;
701:
702:                private EntityReadAheadInfo(List loadKeys) {
703:                    this (loadKeys, null);
704:                }
705:
706:                private EntityReadAheadInfo(List loadKeys,
707:                        JDBCReadAheadMetaData r) {
708:                    this .loadKeys = loadKeys;
709:                    this .readahead = r;
710:                }
711:
712:                public List getLoadKeys() {
713:                    return loadKeys;
714:                }
715:
716:                public JDBCReadAheadMetaData getReadAhead() {
717:                    return readahead;
718:                }
719:            }
720:
721:            /**
722:             * Wraps an Object and does equals/hashCode based on object identity.
723:             */
724:            private static final class IdentityObject {
725:                private final Object object;
726:
727:                public IdentityObject(Object object) {
728:                    if (object == null) {
729:                        throw new IllegalArgumentException("Object is null");
730:                    }
731:                    this .object = object;
732:                }
733:
734:                public Object getObject() {
735:                    return object;
736:                }
737:
738:                public boolean equals(Object object) {
739:                    return this .object == object;
740:                }
741:
742:                public int hashCode() {
743:                    return object.hashCode();
744:                }
745:
746:                public String toString() {
747:                    return object.toString();
748:                }
749:            }
750:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.