mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
performance: do not process changed document twice
This commit is contained in:
+8
-1
@@ -47,6 +47,7 @@ import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.Processor;
|
||||
import gnu.trove.Equality;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -69,6 +70,12 @@ import java.util.Set;
|
||||
}
|
||||
)
|
||||
public class EncodingManagerImpl extends EncodingManager implements PersistentStateComponent<Element>, Disposable {
|
||||
public static final Equality<Reference<Document>> REFERENCE_EQUALITY = new Equality<Reference<Document>>() {
|
||||
@Override
|
||||
public boolean equals(Reference<Document> o1, Reference<Document> o2) {
|
||||
return o1.get() == o2.get();
|
||||
}
|
||||
};
|
||||
private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this);
|
||||
private String myDefaultEncoding = CharsetToolkit.UTF8;
|
||||
private Charset myCachedCharset = null;
|
||||
@@ -129,7 +136,7 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
|
||||
}
|
||||
|
||||
public void queueUpdateEncodingFromContent(@NotNull Document document) {
|
||||
myChangedDocuments.offer(new WeakReference<Document>(document));
|
||||
myChangedDocuments.offerIfAbsent(new WeakReference<Document>(document), REFERENCE_EQUALITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -66,7 +68,7 @@ public class Queue<T> {
|
||||
}
|
||||
|
||||
public T pullFirst() {
|
||||
T result = (T)myArray[myFirst];
|
||||
T result = peekFirst();
|
||||
myArray[myFirst] = null;
|
||||
myFirst++;
|
||||
if (myFirst == myArray.length) {
|
||||
@@ -77,6 +79,9 @@ public class Queue<T> {
|
||||
}
|
||||
|
||||
public T peekFirst() {
|
||||
if (isEmpty()) {
|
||||
throw new IndexOutOfBoundsException("queue is empty");
|
||||
}
|
||||
return (T)myArray[myFirst];
|
||||
}
|
||||
|
||||
@@ -99,10 +104,27 @@ public class Queue<T> {
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
for (int i = 0; i < myArray.length; i++) {
|
||||
myArray[i] = null;
|
||||
}
|
||||
isWrapped = false;
|
||||
Arrays.fill(myArray, null);
|
||||
myFirst = myLast = 0;
|
||||
}
|
||||
|
||||
public boolean process(@NotNull Processor<T> processor) {
|
||||
if (isWrapped) {
|
||||
for (int i = myFirst; i < myArray.length; i++) {
|
||||
T t = (T)myArray[i];
|
||||
if (!processor.process(t)) return false;
|
||||
}
|
||||
for (int i = 0; i < myLast; i++) {
|
||||
T t = (T)myArray[i];
|
||||
if (!processor.process(t)) return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = myFirst; i < myLast; i++) {
|
||||
T t = (T)myArray[i];
|
||||
if (!processor.process(t)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,11 @@ package com.intellij.util.containers;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.util.Processor;
|
||||
import gnu.trove.Equality;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
@@ -38,7 +37,7 @@ public class TransferToEDTQueue<T> {
|
||||
private final Condition<?> myShutUpCondition;
|
||||
private final int myMaxUnitOfWorkThresholdMs; //-1 means indefinite
|
||||
|
||||
private final Queue<T> myQueue = new ConcurrentLinkedQueue<T>();
|
||||
private final Queue<T> myQueue = new Queue<T>(10);
|
||||
private final AtomicBoolean invokeLaterScheduled = new AtomicBoolean();
|
||||
private final Runnable myUpdateRunnable = new Runnable() {
|
||||
@Override
|
||||
@@ -61,14 +60,23 @@ public class TransferToEDTQueue<T> {
|
||||
long finish = System.currentTimeMillis();
|
||||
if (myMaxUnitOfWorkThresholdMs != -1 && finish - start > myMaxUnitOfWorkThresholdMs) break;
|
||||
}
|
||||
if (!myQueue.isEmpty()) {
|
||||
if (!isEmpty()) {
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private boolean isEmpty() {
|
||||
synchronized (myQueue) {
|
||||
return myQueue.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean processNext() {
|
||||
T thing = myQueue.poll();
|
||||
T thing;
|
||||
synchronized (myQueue) {
|
||||
thing = myQueue.isEmpty() ? null : myQueue.pullFirst();
|
||||
}
|
||||
if (thing == null) return false;
|
||||
if (!myProcessor.process(thing)) {
|
||||
stop();
|
||||
@@ -84,9 +92,29 @@ public class TransferToEDTQueue<T> {
|
||||
myMaxUnitOfWorkThresholdMs = maxUnitOfWorkThresholdMs;
|
||||
}
|
||||
|
||||
public void offer(@NotNull T thing) {
|
||||
myQueue.offer(thing);
|
||||
public boolean offer(@NotNull T thing) {
|
||||
synchronized (myQueue) {
|
||||
myQueue.addLast(thing);
|
||||
}
|
||||
scheduleUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean offerIfAbsent(@NotNull final T thing, @NotNull final Equality<T> equality) {
|
||||
boolean absent;
|
||||
synchronized (myQueue) {
|
||||
absent = myQueue.process(new Processor<T>() {
|
||||
@Override
|
||||
public boolean process(T t) {
|
||||
return !equality.equals(t, thing);
|
||||
}
|
||||
});
|
||||
if (absent) {
|
||||
myQueue.addLast(thing);
|
||||
scheduleUpdate();
|
||||
}
|
||||
}
|
||||
return absent;
|
||||
}
|
||||
|
||||
private void scheduleUpdate() {
|
||||
@@ -101,7 +129,9 @@ public class TransferToEDTQueue<T> {
|
||||
|
||||
public void stop() {
|
||||
stopped = true;
|
||||
myQueue.clear();
|
||||
synchronized (myQueue) {
|
||||
myQueue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// process all queue in current thread
|
||||
|
||||
Reference in New Issue
Block a user