Merge branch 'stable-2.8' into stable-2.9
* stable-2.8: SideBySide2: Show [ and ] shortcut keys in nav arrow tooltips Always auto confirm adding reviewers for set-reviewers SSH command Improve wording of 'parents' field description in CommitInfo Fix 'parents' field name of CommitInfo in REST documentation Implement pagination in project list screen Add option 'S' to projects REST API to support query offset Fix: Failure of acceptance tests. Do not refresh project list if filter did not change Fix inconsistent behavior of diff view when viewing binary files Update cookbook plugin to latest revision Correct Javadoc of RestReadView in extension API Fix memory leak of SubIndex.NrtFuture objects Conflicts: gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.java gerrit-server/src/main/java/com/google/gerrit/server/change/PostReviewers.java Change-Id: I4d432c6ce27d3fd76dd9f86b8685be15ec8f123d
This commit is contained in:
@@ -16,7 +16,7 @@ package com.google.gerrit.lucene;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.AbstractFuture;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
@@ -39,13 +39,12 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/** Piece of the change index that is implemented as a separate Lucene index. */
|
||||
class SubIndex {
|
||||
@@ -55,7 +54,7 @@ class SubIndex {
|
||||
private final TrackingIndexWriter writer;
|
||||
private final SearcherManager searcherManager;
|
||||
private final ControlledRealTimeReopenThread<IndexSearcher> reopenThread;
|
||||
private final ConcurrentMap<RefreshListener, Boolean> refreshListeners;
|
||||
private final Set<NrtFuture> notDoneNrtFutures;
|
||||
|
||||
SubIndex(File file, GerritIndexWriterConfig writerConfig) throws IOException {
|
||||
this(FSDirectory.open(file), file.getName(), writerConfig);
|
||||
@@ -107,7 +106,7 @@ class SubIndex {
|
||||
searcherManager = new SearcherManager(
|
||||
writer.getIndexWriter(), true, new SearcherFactory());
|
||||
|
||||
refreshListeners = Maps.newConcurrentMap();
|
||||
notDoneNrtFutures = Sets.newConcurrentHashSet();
|
||||
searcherManager.addListener(new RefreshListener() {
|
||||
@Override
|
||||
public void beforeRefresh() throws IOException {
|
||||
@@ -115,8 +114,8 @@ class SubIndex {
|
||||
|
||||
@Override
|
||||
public void afterRefresh(boolean didRefresh) throws IOException {
|
||||
for (RefreshListener l : refreshListeners.keySet()) {
|
||||
l.afterRefresh(didRefresh);
|
||||
for (NrtFuture f : notDoneNrtFutures) {
|
||||
f.removeIfDone();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -176,10 +175,8 @@ class SubIndex {
|
||||
searcherManager.release(searcher);
|
||||
}
|
||||
|
||||
private final class NrtFuture extends AbstractFuture<Void>
|
||||
implements RefreshListener {
|
||||
private final class NrtFuture extends AbstractFuture<Void> {
|
||||
private final long gen;
|
||||
private final AtomicBoolean hasListeners = new AtomicBoolean();
|
||||
|
||||
NrtFuture(long gen) {
|
||||
this.gen = gen;
|
||||
@@ -198,9 +195,12 @@ class SubIndex {
|
||||
public Void get(long timeout, TimeUnit unit) throws InterruptedException,
|
||||
TimeoutException, ExecutionException {
|
||||
if (!isDone()) {
|
||||
reopenThread.waitForGeneration(gen,
|
||||
(int) MILLISECONDS.convert(timeout, unit));
|
||||
set(null);
|
||||
if (reopenThread.waitForGeneration(gen,
|
||||
(int) MILLISECONDS.convert(timeout, unit))) {
|
||||
set(null);
|
||||
} else {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
}
|
||||
return super.get(timeout, unit);
|
||||
}
|
||||
@@ -209,7 +209,7 @@ class SubIndex {
|
||||
public boolean isDone() {
|
||||
if (super.isDone()) {
|
||||
return true;
|
||||
} else if (isSearcherCurrent()) {
|
||||
} else if (isGenAvailableNowForCurrentSearcher()) {
|
||||
set(null);
|
||||
return true;
|
||||
}
|
||||
@@ -218,33 +218,31 @@ class SubIndex {
|
||||
|
||||
@Override
|
||||
public void addListener(Runnable listener, Executor executor) {
|
||||
if (hasListeners.compareAndSet(false, true) && !isDone()) {
|
||||
searcherManager.addListener(this);
|
||||
if (!isDone()) {
|
||||
notDoneNrtFutures.add(this);
|
||||
}
|
||||
super.addListener(listener, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
if (hasListeners.get()) {
|
||||
refreshListeners.put(this, true);
|
||||
boolean result = super.cancel(mayInterruptIfRunning);
|
||||
if (result) {
|
||||
notDoneNrtFutures.remove(this);
|
||||
}
|
||||
return super.cancel(mayInterruptIfRunning);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRefresh() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterRefresh(boolean didRefresh) throws IOException {
|
||||
if (isSearcherCurrent()) {
|
||||
refreshListeners.remove(this);
|
||||
set(null);
|
||||
void removeIfDone() {
|
||||
if (isGenAvailableNowForCurrentSearcher()) {
|
||||
notDoneNrtFutures.remove(this);
|
||||
if (!isCancelled()) {
|
||||
set(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSearcherCurrent() {
|
||||
private boolean isGenAvailableNowForCurrentSearcher() {
|
||||
try {
|
||||
return reopenThread.waitForGeneration(gen, 0);
|
||||
} catch (InterruptedException e) {
|
||||
|
Reference in New Issue
Block a user