LUCENE-2273: Fixed bug in FieldCacheImpl.getCacheEntries() that used WeakHashMap incorrectly and lead to ConcurrentModificationException

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@912330 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2010-02-21 11:16:42 +00:00
parent 0f99c02ee5
commit fbe34a8500
2 changed files with 14 additions and 12 deletions

View File

@ -82,6 +82,10 @@ Bug fixes
* LUCENE-2249: ParallelMultiSearcher should shut down thread pool on * LUCENE-2249: ParallelMultiSearcher should shut down thread pool on
close. (Martin Traverso via Uwe Schindler) close. (Martin Traverso via Uwe Schindler)
* LUCENE-2273: FieldCacheImpl.getCacheEntries() used WeakHashMap
incorrectly and lead to ConcurrentModificationException.
(Uwe Schindler, Robert Muir)
New features New features
* LUCENE-2128: Parallelized fetching document frequencies during weight * LUCENE-2128: Parallelized fetching document frequencies during weight

View File

@ -58,27 +58,25 @@ class FieldCacheImpl implements FieldCache {
caches.put(StringIndex.class, new StringIndexCache(this)); caches.put(StringIndex.class, new StringIndexCache(this));
} }
public void purgeAllCaches() { public synchronized void purgeAllCaches() {
init(); init();
} }
public void purge(IndexReader r) { public synchronized void purge(IndexReader r) {
for(Cache c : caches.values()) { for(Cache c : caches.values()) {
c.purge(r); c.purge(r);
} }
} }
public CacheEntry[] getCacheEntries() { public synchronized CacheEntry[] getCacheEntries() {
List<CacheEntry> result = new ArrayList<CacheEntry>(17); List<CacheEntry> result = new ArrayList<CacheEntry>(17);
for(final Class<?> cacheType: caches.keySet()) { for(final Map.Entry<Class<?>,Cache> cacheEntry: caches.entrySet()) {
Cache cache = caches.get(cacheType); final Cache cache = cacheEntry.getValue();
for (final Object readerKey : cache.readerCache.keySet()) { final Class<?> cacheType = cacheEntry.getKey();
// we've now materialized a hard ref synchronized(cache.readerCache) {
for (final Map.Entry<Object,Map<Entry, Object>> readerCacheEntry : cache.readerCache.entrySet()) {
// innerKeys was backed by WeakHashMap, sanity check final Object readerKey = readerCacheEntry.getKey();
// that it wasn't GCed before we made hard ref final Map<Entry, Object> innerCache = readerCacheEntry.getValue();
if (null != readerKey && cache.readerCache.containsKey(readerKey)) {
Map<Entry, Object> innerCache = cache.readerCache.get(readerKey);
for (final Map.Entry<Entry, Object> mapEntry : innerCache.entrySet()) { for (final Map.Entry<Entry, Object> mapEntry : innerCache.entrySet()) {
Entry entry = mapEntry.getKey(); Entry entry = mapEntry.getKey();
result.add(new CacheEntryImpl(readerKey, entry.field, result.add(new CacheEntryImpl(readerKey, entry.field,