From 441989ab39049e20b90419ff2475342acde02cee Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 25 Jan 2011 18:38:18 +0300 Subject: [PATCH] VCS: conflicts tracker's document listener actions were buffered and moved onto background thread. review=dmitry avdeev --- .../intellij/openapi/vcs/ZipperUpdater.java | 30 ++++--- .../conflicts/ChangelistConflictTracker.java | 82 +++++++++++++------ .../patch/ApplyPatchDifferentiatedDialog.java | 2 +- .../svn/history/MergeInfoUpdatesListener.java | 6 +- 4 files changed, 81 insertions(+), 39 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ZipperUpdater.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ZipperUpdater.java index 1d379e0261dc..6c8a8d8fdf35 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ZipperUpdater.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ZipperUpdater.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.vcs; +import com.intellij.openapi.Disposable; import com.intellij.openapi.progress.SomeQueue; import com.intellij.util.Alarm; @@ -25,9 +26,13 @@ public class ZipperUpdater { private final Object myLock = new Object(); private final int myDelay; - public ZipperUpdater(final int delay) { + public ZipperUpdater(final int delay, Disposable parentDisposable) { + this(delay, Alarm.ThreadToUse.SHARED_THREAD, parentDisposable); + } + + public ZipperUpdater(final int delay, final Alarm.ThreadToUse threadToUse, Disposable parentDisposable) { myDelay = delay; - myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); + myAlarm = new Alarm(threadToUse, parentDisposable); } public void queue(final Runnable runnable) { @@ -36,16 +41,19 @@ public class ZipperUpdater { public void queue(final Runnable runnable, final boolean urgent) { synchronized (myLock) { + final boolean wasRaised = myRaised; myRaised = true; - } - myAlarm.addRequest(new Runnable() { - public void run() { - synchronized (myLock) { - if (! myRaised) return; - myRaised = false; - } - runnable.run(); + if (! wasRaised) { + myAlarm.addRequest(new Runnable() { + public void run() { + synchronized (myLock) { + if (! myRaised) return; + myRaised = false; + } + runnable.run(); + } + }, urgent ? 0 : myDelay); } - }, urgent ? 0 : myDelay); + } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictTracker.java index 9b24b07643d0..9514ea20f1fc 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictTracker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictTracker.java @@ -16,6 +16,8 @@ package com.intellij.openapi.vcs.changes.conflicts; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.event.DocumentAdapter; @@ -24,12 +26,15 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.FileStatusManager; +import com.intellij.openapi.vcs.ZipperUpdater; import com.intellij.openapi.vcs.changes.*; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.EditorNotifications; +import com.intellij.util.Alarm; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.hash.HashSet; import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.util.xmlb.XmlSerializer; import org.jdom.Element; @@ -38,6 +43,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; /** * @author Dmitry Avdeev @@ -57,6 +63,8 @@ public class ChangelistConflictTracker { private final DocumentAdapter myDocumentListener; private final FileStatusManager myFileStatusManager; + private final Set myCheckSet; + private final Object myCheckSetLock; public ChangelistConflictTracker(Project project, ChangeListManager changeListManager, @@ -68,7 +76,26 @@ public class ChangelistConflictTracker { myEditorNotifications = editorNotifications; myDocumentManager = FileDocumentManager.getInstance(); myFileStatusManager = fileStatusManager; + myCheckSetLock = new Object(); + myCheckSet = new HashSet(); + final Application application = ApplicationManager.getApplication(); + final ZipperUpdater zipperUpdater = new ZipperUpdater(300, Alarm.ThreadToUse.SHARED_THREAD, myProject); + final Runnable runnable = new Runnable() { + @Override + public void run() { + if (application.isDisposed() || myProject.isDisposed() || (! myProject.isOpen())) return; + final Set localSet; + synchronized (myCheckSetLock) { + localSet = new HashSet(); + localSet.addAll(myCheckSet); + myCheckSet.clear(); + } + for (VirtualFile file : localSet) { + checkFile(file); + } + } + }; myDocumentListener = new DocumentAdapter() { @Override public void documentChanged(DocumentEvent e) { @@ -77,31 +104,10 @@ public class ChangelistConflictTracker { } Document document = e.getDocument(); final VirtualFile file = myDocumentManager.getFile(document); - if (file == null || isFromActiveChangelist(file) || ChangesUtil.isInternalOperation(file)) { - return; + synchronized (myCheckSetLock) { + myCheckSet.add(file); } - myChangeListManager.invokeAfterUpdate(new Runnable() { - public void run() { - - if (!isFromActiveChangelist(file)) { - String path = file.getPath(); - Conflict conflict = myConflicts.get(path); - boolean newConflict = false; - if (conflict == null) { - conflict = new Conflict(); - myConflicts.put(path, conflict); - newConflict = true; - } - conflict.timestamp = System.currentTimeMillis(); - conflict.changelistId = myChangeListManager.getDefaultChangeList().getId(); - - if (newConflict && myOptions.HIGHLIGHT_CONFLICTS) { - myFileStatusManager.fileStatusChanged(file); - myEditorNotifications.updateNotifications(file); - } - } - } - }, InvokeAfterUpdateMode.SILENT, null, null); + zipperUpdater.queue(runnable); } }; @@ -128,6 +134,34 @@ public class ChangelistConflictTracker { }; } + private void checkFile(final VirtualFile file) { + if (file == null || isFromActiveChangelist(file) || ChangesUtil.isInternalOperation(file)) { + return; + } + myChangeListManager.invokeAfterUpdate(new Runnable() { + public void run() { + + if (!isFromActiveChangelist(file)) { + String path = file.getPath(); + Conflict conflict = myConflicts.get(path); + boolean newConflict = false; + if (conflict == null) { + conflict = new Conflict(); + myConflicts.put(path, conflict); + newConflict = true; + } + conflict.timestamp = System.currentTimeMillis(); + conflict.changelistId = myChangeListManager.getDefaultChangeList().getId(); + + if (newConflict && myOptions.HIGHLIGHT_CONFLICTS) { + myFileStatusManager.fileStatusChanged(file); + myEditorNotifications.updateNotifications(file); + } + } + } + }, InvokeAfterUpdateMode.SILENT, null, null); + } + public boolean isWritingAllowed(@NotNull VirtualFile file) { if (isFromActiveChangelist(file)) return true; Conflict conflict = myConflicts.get(file.getPath()); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java index c18e9899d49d..f33b7bfc2b38 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java @@ -103,7 +103,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper { }); myProject = project; - myLoadQueue = new ZipperUpdater(500); + myLoadQueue = new ZipperUpdater(500, getDisposable()); myPatches = new LinkedList(); myRecentPathFileChange = new AtomicReference(); myChangesTreeList = new MyChangeTreeList(project, Collections.emptyList(), diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/MergeInfoUpdatesListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/MergeInfoUpdatesListener.java index 30223d00d542..7fd2fa302e54 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/MergeInfoUpdatesListener.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/MergeInfoUpdatesListener.java @@ -20,15 +20,15 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsListener; import com.intellij.openapi.vcs.ZipperUpdater; -import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vcs.changes.committed.CommittedChangesTreeBrowser; import com.intellij.openapi.vcs.changes.committed.VcsConfigurationChangeListener; +import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.idea.svn.SvnVcs; -import org.jetbrains.idea.svn.integrate.Merger; import org.jetbrains.idea.svn.dialogs.SvnMapDialog; +import org.jetbrains.idea.svn.integrate.Merger; import org.jetbrains.idea.svn.mergeinfo.SvnMergeInfoCache; import java.util.ArrayList; @@ -45,7 +45,7 @@ public class MergeInfoUpdatesListener { public MergeInfoUpdatesListener(final Project project, final MessageBusConnection connection) { myConnection = connection; myProject = project; - myUpdater = new ZipperUpdater(DELAY); + myUpdater = new ZipperUpdater(DELAY, myProject); } public void addPanel(final RootsAndBranches action) {