From 40163c6bb7980fa1faf8413bd0bbededd8d033d0 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 18 Jul 2013 18:52:22 +0200 Subject: [PATCH] coalesce change file events in small frame, usually merge e.g. large copy file change notifications --- .../openapi/vfs/impl/local/FileWatcher.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java index be846330cae2..f80e320d81c0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java @@ -91,6 +91,8 @@ public class FileWatcher { private final Object myLock = new Object(); private DirtyPaths myDirtyPaths = new DirtyPaths(); + private final String[] myLastChangedPathes = new String[2]; + private int myLastChangedPathIndex; /** @deprecated use {@linkplain com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl#getFileWatcher()} (to remove in IDEA 13) */ public static FileWatcher getInstance() { @@ -153,6 +155,8 @@ public class FileWatcher { synchronized (myLock) { DirtyPaths dirtyPaths = myDirtyPaths; myDirtyPaths = new DirtyPaths(); + myLastChangedPathIndex = 0; + for(int i = 0; i < myLastChangedPathes.length; ++i) myLastChangedPathes[i] = null; return dirtyPaths; } } @@ -522,6 +526,8 @@ public class FileWatcher { notifyOnEvent(); } + private int myChangeRequests, myFilteredRequests; + private void processChange(String path, WatcherOp op) { if (SystemInfo.isWindows && op == WatcherOp.RECDIRTY && path.length() == 3 && Character.isLetter(path.charAt(0))) { VirtualFile root = LocalFileSystem.getInstance().findFileByPath(path); @@ -534,6 +540,27 @@ public class FileWatcher { return; } + if (op == WatcherOp.CHANGE) { + synchronized (myLock) { + ++myChangeRequests; + + // TODO: remove logging once finalized + if ((myChangeRequests & 0x3ff) == 0) LOG.info("Change requests:" + myChangeRequests + ", filtered:" + myFilteredRequests); + + for(int i = 0; i < myLastChangedPathes.length; ++i) { + int last = myLastChangedPathIndex - i - 1; + if (last < 0) last += myLastChangedPathes.length; + String lastChangedPath = myLastChangedPathes[last]; + if (lastChangedPath != null && lastChangedPath.equals(path)) { + ++myFilteredRequests; + return; + } + } + myLastChangedPathes[myLastChangedPathIndex ++] = path; + if (myLastChangedPathIndex == myLastChangedPathes.length) myLastChangedPathIndex = 0; + } + } + boolean exactPath = op != WatcherOp.DIRTY && op != WatcherOp.RECDIRTY; Collection paths = checkWatchable(path, exactPath, false);