You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by us...@apache.org on 2010/02/21 12:16:42 UTC

svn commit: r912330 - in /lucene/java/trunk: CHANGES.txt src/java/org/apache/lucene/search/FieldCacheImpl.java

Author: uschindler
Date: Sun Feb 21 11:16:42 2010
New Revision: 912330

URL: http://svn.apache.org/viewvc?rev=912330&view=rev
Log:
LUCENE-2273: Fixed bug in FieldCacheImpl.getCacheEntries() that used WeakHashMap incorrectly and lead to ConcurrentModificationException

Modified:
    lucene/java/trunk/CHANGES.txt
    lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java

Modified: lucene/java/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=912330&r1=912329&r2=912330&view=diff
==============================================================================
--- lucene/java/trunk/CHANGES.txt (original)
+++ lucene/java/trunk/CHANGES.txt Sun Feb 21 11:16:42 2010
@@ -82,6 +82,10 @@
 * LUCENE-2249: ParallelMultiSearcher should shut down thread pool on
   close.  (Martin Traverso via Uwe Schindler)
   
+* LUCENE-2273: FieldCacheImpl.getCacheEntries() used WeakHashMap
+  incorrectly and lead to ConcurrentModificationException.
+  (Uwe Schindler, Robert Muir)
+  
 New features
 
 * LUCENE-2128: Parallelized fetching document frequencies during weight

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java?rev=912330&r1=912329&r2=912330&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheImpl.java Sun Feb 21 11:16:42 2010
@@ -58,27 +58,25 @@
     caches.put(StringIndex.class, new StringIndexCache(this));
   }
 
-  public void purgeAllCaches() {
+  public synchronized void purgeAllCaches() {
     init();
   }
 
-  public void purge(IndexReader r) {
+  public synchronized void purge(IndexReader r) {
     for(Cache c : caches.values()) {
       c.purge(r);
     }
   }
   
-  public CacheEntry[] getCacheEntries() {
+  public synchronized CacheEntry[] getCacheEntries() {
     List<CacheEntry> result = new ArrayList<CacheEntry>(17);
-    for(final Class<?> cacheType: caches.keySet()) {
-      Cache cache = caches.get(cacheType);
-      for (final Object readerKey : cache.readerCache.keySet()) {
-        // we've now materialized a hard ref
-        
-        // innerKeys was backed by WeakHashMap, sanity check
-        // that it wasn't GCed before we made hard ref
-        if (null != readerKey && cache.readerCache.containsKey(readerKey)) {
-          Map<Entry, Object> innerCache = cache.readerCache.get(readerKey);
+    for(final Map.Entry<Class<?>,Cache> cacheEntry: caches.entrySet()) {
+      final Cache cache = cacheEntry.getValue();
+      final Class<?> cacheType = cacheEntry.getKey();
+      synchronized(cache.readerCache) {
+        for (final Map.Entry<Object,Map<Entry, Object>> readerCacheEntry : cache.readerCache.entrySet()) {
+          final Object readerKey = readerCacheEntry.getKey();
+          final Map<Entry, Object> innerCache = readerCacheEntry.getValue();
           for (final Map.Entry<Entry, Object> mapEntry : innerCache.entrySet()) {
             Entry entry = mapEntry.getKey();
             result.add(new CacheEntryImpl(readerKey, entry.field,