SOLR-9524: SolrIndexSearcher.getIndexFingerprint uses dubious synchronization

This commit is contained in:
Noble Paul 2016-09-21 11:29:53 +05:30
parent 3d130097b7
commit afc57347b4
2 changed files with 16 additions and 9 deletions

View File

@ -137,6 +137,8 @@ Bug Fixes
* SOLR-9512: CloudSolrClient will try and keep up with leader changes if its
state cache points to a down server (Alan Woodward, noble)
* SOLR-9524: SolrIndexSearcher.getIndexFingerprint uses dubious synchronization (Mike Drob, noble)
Optimizations
----------------------

View File

@ -36,6 +36,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import com.google.common.base.Function;
import com.google.common.base.Objects;
@ -2384,15 +2385,19 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
* gets a cached version of the IndexFingerprint for this searcher
**/
public IndexFingerprint getIndexFingerprint(long maxVersion) throws IOException {
IndexFingerprint fingerprint = maxVersionFingerprintCache.get(maxVersion);
if (fingerprint != null) return fingerprint;
// possibly expensive, so prevent more than one thread from calculating it for this searcher
synchronized (maxVersionFingerprintCache) {
fingerprint = maxVersionFingerprintCache.get(maxVersionFingerprintCache);
if (fingerprint != null) return fingerprint;
fingerprint = IndexFingerprint.getFingerprint(this, maxVersion);
maxVersionFingerprintCache.put(maxVersion, fingerprint);
return fingerprint;
final SolrIndexSearcher searcher = this;
final AtomicReference<IOException> exception = new AtomicReference<>();
try {
return maxVersionFingerprintCache.computeIfAbsent(maxVersion, key -> {
try {
return IndexFingerprint.getFingerprint(searcher, key);
} catch (IOException e) {
exception.set(e);
return null;
}
});
} finally {
if (exception.get() != null) throw exception.get();
}
}