mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
IDEA-328027 TextLayoutCache - get rid of our LinkedHashMap and use fastutil (less code to maintain, more faster and modern implementation)
GitOrigin-RevId: edc79264d35e97b4729e34afa8edac641aa8c7f3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7c369a97a6
commit
e1e3a2de7b
@@ -9,14 +9,15 @@ import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.ex.PrioritizedDocumentListener;
|
||||
import com.intellij.openapi.editor.impl.EditorDocumentPriorities;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.util.containers.hash.LinkedHashMap;
|
||||
import com.intellij.util.ui.update.Activatable;
|
||||
import com.intellij.util.ui.update.UiNotifyConnector;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Editor text layout storage. Layout is stored on a per-logical-line basis,
|
||||
@@ -37,19 +38,7 @@ final class TextLayoutCache implements PrioritizedDocumentListener, Disposable {
|
||||
private int myDocumentChangeOldEndLine;
|
||||
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
|
||||
private Map<LineLayout.Chunk, Object> myLaidOutChunks =
|
||||
// using our own LinkedHashMap implementation to avoid IDEA-205735
|
||||
new LinkedHashMap<>(MAX_CHUNKS_IN_ACTIVE_EDITOR, true) {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<LineLayout.Chunk, Object> eldest) {
|
||||
if (size() > getChunkCacheSizeLimit()) {
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Clearing chunk for " + myView.getEditor().getVirtualFile());
|
||||
eldest.getKey().clearCache();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
private final ObjectLinkedOpenHashSet<LineLayout.Chunk> laidOutChunks = new ObjectLinkedOpenHashSet<>(MAX_CHUNKS_IN_ACTIVE_EDITOR);
|
||||
|
||||
TextLayoutCache(EditorView view) {
|
||||
myView = view;
|
||||
@@ -91,7 +80,7 @@ final class TextLayoutCache implements PrioritizedDocumentListener, Disposable {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myLines = null;
|
||||
myLaidOutChunks = null;
|
||||
laidOutChunks.clear();
|
||||
}
|
||||
|
||||
private int getAdjustedLineNumber(int offset) {
|
||||
@@ -130,7 +119,8 @@ final class TextLayoutCache implements PrioritizedDocumentListener, Disposable {
|
||||
}
|
||||
if (oldEndLine < newEndLine) {
|
||||
myLines.addAll(oldEndLine + 1, Collections.nCopies(newEndLine - oldEndLine, null));
|
||||
} else if (oldEndLine > newEndLine) {
|
||||
}
|
||||
else if (oldEndLine > newEndLine) {
|
||||
List<LineLayout> layouts = myLines.subList(newEndLine + 1, oldEndLine + 1);
|
||||
for (LineLayout layout : layouts) {
|
||||
if (layout != null) {
|
||||
@@ -162,28 +152,33 @@ final class TextLayoutCache implements PrioritizedDocumentListener, Disposable {
|
||||
return myView.getEditor().getContentComponent().isShowing() ? MAX_CHUNKS_IN_ACTIVE_EDITOR : MAX_CHUNKS_IN_INACTIVE_EDITOR;
|
||||
}
|
||||
|
||||
void onChunkAccess(LineLayout.Chunk chunk) {
|
||||
myLaidOutChunks.put(chunk, this); // value doesn't matter, null is not supported by our map implementation
|
||||
void onChunkAccess(@NotNull LineLayout.Chunk chunk) {
|
||||
if (laidOutChunks.addAndMoveToFirst(chunk) && laidOutChunks.size() > getChunkCacheSizeLimit()) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Clearing chunk for " + myView.getEditor().getVirtualFile());
|
||||
}
|
||||
laidOutChunks.removeLast().clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeChunksFromCache(LineLayout layout) {
|
||||
layout.getChunksInLogicalOrder().forEach(myLaidOutChunks::remove);
|
||||
layout.getChunksInLogicalOrder().forEach(laidOutChunks::remove);
|
||||
}
|
||||
|
||||
private void trimChunkCache() {
|
||||
int limit = getChunkCacheSizeLimit();
|
||||
if (myLaidOutChunks.size() > limit) {
|
||||
Iterator<LineLayout.Chunk> it = myLaidOutChunks.keySet().iterator();
|
||||
while (myLaidOutChunks.size() > limit) {
|
||||
LineLayout.Chunk chunk = it.next();
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Clearing chunk for " + myView.getEditor().getVirtualFile());
|
||||
chunk.clearCache();
|
||||
it.remove();
|
||||
while (laidOutChunks.size() > limit) {
|
||||
LineLayout.Chunk chunk = laidOutChunks.removeLast();
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Clearing chunk for " + myView.getEditor().getVirtualFile());
|
||||
}
|
||||
chunk.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDisposed() {
|
||||
if (myLines == null) myView.getEditor().throwDisposalError("Editor is already disposed");
|
||||
if (myLines == null) {
|
||||
myView.getEditor().throwDisposalError("Editor is already disposed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user