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;
}
)
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;
}
public void queueUpdateEncodingFromContent(@NotNull Document document) {
- myChangedDocuments.offer(new WeakReference<Document>(document));
+ myChangedDocuments.offerIfAbsent(new WeakReference<Document>(document), REFERENCE_EQUALITY);
}
@Override
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;
}
public T pullFirst() {
- T result = (T)myArray[myFirst];
+ T result = peekFirst();
myArray[myFirst] = null;
myFirst++;
if (myFirst == myArray.length) {
}
public T peekFirst() {
+ if (isEmpty()) {
+ throw new IndexOutOfBoundsException("queue is empty");
+ }
return (T)myArray[myFirst];
}
}
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;
+ }
}
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;
/**
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
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();
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() {
public void stop() {
stopped = true;
- myQueue.clear();
+ synchronized (myQueue) {
+ myQueue.clear();
+ }
}
// process all queue in current thread