LUCENE-2474: cutover to MapBackedSet(ConcurrentHashMap) instead of Collections.syncSet(HashSet)

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1063897 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2011-01-26 22:17:57 +00:00
parent e54599568d
commit 63097d1bd8
7 changed files with 89 additions and 15 deletions

View File

@ -27,6 +27,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.FieldSelector;
@ -36,6 +37,7 @@ import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.index.codecs.CodecProvider;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.MapBackedSet;
/**
* An IndexReader which reads indexes with multiple segments.
@ -104,7 +106,7 @@ class DirectoryReader extends IndexReader implements Cloneable {
} else {
this.codecs = codecs;
}
readerFinishedListeners = Collections.synchronizedSet(new HashSet<ReaderFinishedListener>());
readerFinishedListeners = new MapBackedSet<ReaderFinishedListener>(new ConcurrentHashMap<ReaderFinishedListener,Boolean>());
// To reduce the chance of hitting FileNotFound
// (and having to retry), we open segments in

View File

@ -23,13 +23,13 @@ import org.apache.lucene.index.IndexReader.ReaderContext;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.MapBackedSet;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
/** A <code>FilterIndexReader</code> contains another IndexReader, which it
* uses as its basic source of data, possibly transforming the data along the
@ -287,7 +287,7 @@ public class FilterIndexReader extends IndexReader {
public FilterIndexReader(IndexReader in) {
super();
this.in = in;
readerFinishedListeners = Collections.synchronizedSet(new HashSet<ReaderFinishedListener>());
readerFinishedListeners = new MapBackedSet<ReaderFinishedListener>(new ConcurrentHashMap<ReaderFinishedListener,Boolean>());
}
@Override

View File

@ -34,7 +34,6 @@ import java.io.IOException;
import java.io.Closeable;
import java.util.Collection;
import java.util.List;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@ -128,10 +127,7 @@ public abstract class IndexReader implements Cloneable,Closeable {
// Defensive (should never be null -- all impls must set
// this):
if (readerFinishedListeners != null) {
// Clone the set so that we don't have to sync on
// readerFinishedListeners while invoking them:
for(ReaderFinishedListener listener : new HashSet<ReaderFinishedListener>(readerFinishedListeners)) {
for(ReaderFinishedListener listener : readerFinishedListeners) {
listener.finished(this);
}
}

View File

@ -30,8 +30,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
@ -48,6 +48,7 @@ import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.Constants;
import org.apache.lucene.util.ThreadInterruptedException;
import org.apache.lucene.util.MapBackedSet;
/**
An <code>IndexWriter</code> creates and maintains an index.
@ -366,7 +367,7 @@ public class IndexWriter implements Closeable {
}
// Used for all SegmentReaders we open
private final Collection<IndexReader.ReaderFinishedListener> readerFinishedListeners = Collections.synchronizedSet(new HashSet<IndexReader.ReaderFinishedListener>());
private final Collection<IndexReader.ReaderFinishedListener> readerFinishedListeners = new MapBackedSet<IndexReader.ReaderFinishedListener>(new ConcurrentHashMap<IndexReader.ReaderFinishedListener,Boolean>());
Collection<IndexReader.ReaderFinishedListener> getReaderFinishedListeners() throws IOException {
return readerFinishedListeners;

View File

@ -20,14 +20,14 @@ package org.apache.lucene.index;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.HashSet;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.FieldSelector;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.ReaderUtil;
import org.apache.lucene.util.MapBackedSet;
/** An IndexReader which reads multiple indexes, appending
* their content. */
@ -83,7 +83,7 @@ public class MultiReader extends IndexReader implements Cloneable {
}
}
starts[subReaders.length] = maxDoc;
readerFinishedListeners = Collections.synchronizedSet(new HashSet<ReaderFinishedListener>());
readerFinishedListeners = new MapBackedSet<ReaderFinishedListener>(new ConcurrentHashMap<ReaderFinishedListener,Boolean>());
return ReaderUtil.buildReaderContext(this);
}

View File

@ -23,9 +23,11 @@ import org.apache.lucene.document.FieldSelectorResult;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.MapBackedSet;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/** An IndexReader which reads multiple, parallel indexes. Each index added
@ -72,7 +74,7 @@ public class ParallelReader extends IndexReader {
public ParallelReader(boolean closeSubReaders) throws IOException {
super();
this.incRefReaders = !closeSubReaders;
readerFinishedListeners = Collections.synchronizedSet(new HashSet<ReaderFinishedListener>());
readerFinishedListeners = new MapBackedSet<ReaderFinishedListener>(new ConcurrentHashMap<ReaderFinishedListener,Boolean>());
}
/** {@inheritDoc} */

View File

@ -0,0 +1,73 @@
package org.apache.lucene.util;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Map;
/**
* A Set implementation that wraps an actual Map based
* implementation.
*
* @lucene.internal
*/
public class MapBackedSet<E> extends AbstractSet<E> implements Serializable {
private static final long serialVersionUID = -6761513279741915432L;
private final Map<E, Boolean> map;
/**
* Creates a new instance which wraps the specified {@code map}.
*/
public MapBackedSet(Map<E, Boolean> map) {
this.map = map;
}
@Override
public int size() {
return map.size();
}
@Override
public boolean contains(Object o) {
return map.containsKey(o);
}
@Override
public boolean add(E o) {
return map.put(o, Boolean.TRUE) == null;
}
@Override
public boolean remove(Object o) {
return map.remove(o) != null;
}
@Override
public void clear() {
map.clear();
}
@Override
public Iterator<E> iterator() {
return map.keySet().iterator();
}
}