diff options
author | Jean Michel-Lemieux | 2003-02-17 21:34:00 +0000 |
---|---|---|
committer | Jean Michel-Lemieux | 2003-02-17 21:34:00 +0000 |
commit | 09330ae686b9adfd9e29be80c64c2a73db791fb1 (patch) | |
tree | 68a39652b1368d124ffd8ad7194ae52af5d7068a | |
parent | ec38372516c0cab3e1d75aeef7faf446cc016b28 (diff) | |
download | eclipse.platform.team-DECORATION_PERFORMANCE_2_1m5.tar.gz eclipse.platform.team-DECORATION_PERFORMANCE_2_1m5.tar.xz eclipse.platform.team-DECORATION_PERFORMANCE_2_1m5.zip |
*** empty log message ***DECORATION_PERFORMANCE_2_1m5
12 files changed, 202 insertions, 17 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java index d081a16fe..df51bc1ce 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSProviderPlugin.java @@ -316,6 +316,10 @@ public class CVSProviderPlugin extends Plugin { workspace.removeResourceChangeListener(fileModificationManager); workspace.removeResourceChangeListener(addDeleteMoveListener); + // remove all of this plugin's save participants. This is easier than having + // each class that added itself as a participant to have to listen to shutdown. + workspace.removeSaveParticipant(this); + deleteCacheDirectory(); } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java index 63bb0f0f8..74fcea3d5 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java @@ -499,7 +499,8 @@ public class EclipseFile extends EclipseResource implements ICVSFile { EclipseSynchronizer.getInstance().flushDirtyCache(getIResource(), IResource.DEPTH_ZERO); return; } - setModified(isModified(getSyncInfo())); + //setModified(isModified(getSyncInfo())); + flushWithAncestors(); } /** @@ -514,7 +515,18 @@ public class EclipseFile extends EclipseResource implements ICVSFile { } public boolean handleModification(boolean forAddition) throws CVSException { - if (isIgnored()) return false; + if (isIgnored()) { + // Special case handling for when a resource passes from the un-managed state + // to the ignored state (e.g. ignoring the ignore file). Parent dirty state must be + // recalculated but since the resource's end state is ignored there is a lot of code + // in the plugin that simply disregards the change to the resource. + // There may be a better was of handling resources that transition from un-managed to + // ignored but for now this seems like the safest change. + if(! resource.isDerived()) { + flushWithAncestors(); + } + return false; + } if (EclipseSynchronizer.getInstance().contentsChangedByUpdate(getIFile())) return false; if (forAddition) { @@ -528,10 +540,8 @@ public class EclipseFile extends EclipseResource implements ICVSFile { } /** - * Method setModified sets the modified status of the reciever. This method + * Sets the modified status of the receiver. This method * returns true if there was a change in the modified status of the file. - * @param iFile - * @param b */ private boolean setModified(boolean modified) throws CVSException { try { diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java index 265c79dfa..fe77ff053 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFolder.java @@ -354,7 +354,9 @@ class EclipseFolder extends EclipseResource implements ICVSFolder { * @param b */ protected void adjustModifiedCount(boolean modified) throws CVSException { - flushWithAncestors(); + if (isModified() != modified) { + flushWithAncestors(); + } // if (EclipseSynchronizer.getInstance().adjustModifiedCount((IContainer)getIResource(), modified)) { // ((EclipseFolder)getParent()).adjustModifiedCount(modified); // } @@ -440,6 +442,12 @@ class EclipseFolder extends EclipseResource implements ICVSFolder { private String determineDirtyCount(String indicator, boolean shared) throws CVSException { IContainer container = (IContainer)getIResource(); ICVSResource[] children = members(ALL_UNIGNORED_MEMBERS); + + if (Policy.DEBUG_DIRTY_CACHING) { + System.out.println("checking isModified() recursively for " //$NON-NLS-1$ + +getPath()); + } + int count = 0; Set deletedChildren = new HashSet(); for (int i = 0; i < children.length; i++) { diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java index a3300cc62..60ad3d409 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java @@ -1280,6 +1280,12 @@ public class EclipseSynchronizer { */ protected boolean setModified(IResource container, boolean modified) throws CVSException { String indicator = modified ? IS_DIRTY_INDICATOR : NOT_DIRTY_INDICATOR; + + // DECORATOR this state change check is error prone. it is quite possible that + // another thread updated the dirty state (e.g. the decorator) and thus the returned + // value from this method will be wrong and lead the caller to make assumptions + // that can be wrong. That the state has not changed, but it has just too quickly. + // if it's already set, no need to set the property or adjust the parents count if (indicator.equals(getDirtyIndicator(container))) return false; // set the dirty indicator and adjust the parent accordingly @@ -1406,7 +1412,10 @@ public class EclipseSynchronizer { } getSyncInfoCacheFor(resource).flushDirtyCache(resource); } finally { - flushDirtyCacheWithAncestors(resource.getParent()); + IContainer parent = resource.getParent(); + if(! alreadyflushed(parent)) { + flushDirtyCacheWithAncestors(parent); + } } } finally { endOperation(null); @@ -1414,6 +1423,14 @@ public class EclipseSynchronizer { } /** + * @param parent + * @return boolean + */ + private boolean alreadyflushed(IContainer resource) throws CVSException { + return getSyncInfoCacheFor(resource).isDirtyCacheFlushed(resource); + } + + /** * Method updated flags the objetc as having been modfied by the updated * handler. This flag is read during the resource delta to determine whether * the modification made the file dirty or not. diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java index bd20e5e1f..8f9da8575 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java @@ -59,6 +59,9 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa if (!project.isAccessible()) { return false; } + if ((delta.getFlags() & IResourceDelta.OPEN) != 0) { + return false; + } if (RepositoryProvider.getProvider(project, CVSProviderPlugin.getTypeId()) == null) { return false; } @@ -168,9 +171,8 @@ public class FileModificationManager implements IResourceChangeListener, ISavePa private void resourceAdded(IResource resource) throws CoreException { try { EclipseResource cvsResource = (EclipseResource)CVSWorkspaceRoot.getCVSResourceFor(resource); - if (cvsResource.handleModification(true /* addition */)) { + cvsResource.handleModification(true /* addition */); modifiedResources.add(resource); - } } catch (CVSException e) { throw e.toCoreException(); } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java index fd81e87eb..c48c50875 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteFile.java @@ -107,6 +107,7 @@ public class RemoteFile extends RemoteResource implements ICVSRemoteFile { newInfo.setKeywordMode(Command.KSUBST_TEXT_EXPAND); newInfo.setTag(tag); syncBytes = newInfo.getBytes(); + setWorkspaceSyncState(workspaceSyncState); } public RemoteFile(RemoteFolder parent, byte[] syncBytes) throws CVSException { diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java index fb4f96968..a4e132cff 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SessionPropertySyncInfoCache.java @@ -15,10 +15,17 @@ import java.util.Set; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.resources.ISaveContext; +import org.eclipse.core.resources.ISaveParticipant; +import org.eclipse.core.resources.ISynchronizer; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.internal.ccvs.core.CVSException; import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; import org.eclipse.team.internal.ccvs.core.Policy; @@ -27,17 +34,31 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; /** * This cache uses session properties to hold the bytes representing the sync - * info + * info. In addition when the workbench closes or a project is closed, the dirty + * state for all cvs managed folders are persisted using the resource's plugin + * synchronizer. */ -/*package*/ class SessionPropertySyncInfoCache extends SyncInfoCache { +/*package*/ class SessionPropertySyncInfoCache extends SyncInfoCache implements ISaveParticipant { // key used on a folder to indicate that the resource sync has been cahced for it's children private static final QualifiedName RESOURCE_SYNC_CACHED_KEY = new QualifiedName(CVSProviderPlugin.ID, "resource-sync-cached"); //$NON-NLS-1$ + private static final QualifiedName FOLDER_SYNC_RESTORED_KEY = new QualifiedName(CVSProviderPlugin.ID, "folder-sync-restored"); //$NON-NLS-1$ + private static final Object RESOURCE_SYNC_CACHED = new Object(); + private static final Object FOLDER_SYNC_RESTORED = new Object(); /*package*/ static final String[] NULL_IGNORES = new String[0]; private static final FolderSyncInfo NULL_FOLDER_SYNC_INFO = new FolderSyncInfo("", "", null, false); //$NON-NLS-1$ //$NON-NLS-2$ + /*package*/ SessionPropertySyncInfoCache() { + try { + // this save participant is removed when the plugin is shutdown. + ResourcesPlugin.getWorkspace().addSaveParticipant(CVSProviderPlugin.getPlugin(), this); + } catch (CoreException e) { + CVSProviderPlugin.log(e.getStatus()); + } + } + /** * If not already cached, loads and caches the folder ignores sync for the container. * Folder must exist and must not be the workspace root. @@ -206,14 +227,28 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; } private void internalSetDirtyIndicator(IContainer container, String indicator) throws CVSException { try { - container.setPersistentProperty(IS_DIRTY, indicator); + container.setSessionProperty(IS_DIRTY, indicator); } catch (CoreException e) { throw CVSException.wrapException(e); } } private String internalGetDirtyIndicator(IContainer container) throws CVSException { try { - return container.getPersistentProperty(IS_DIRTY); + String di = (String)container.getSessionProperty(IS_DIRTY); + + // if the session property is not available then restore from persisted sync info. At this + // time the sync info is not flushed because we don't want the workspace to generate + // a delta. Since the sync info is not flushed another session property is used to remember + // that the sync info was already converted to a session property and has become stale. + if(di == null && container.getSessionProperty(FOLDER_SYNC_RESTORED_KEY) == null) { + byte [] diBytes = ResourcesPlugin.getWorkspace().getSynchronizer().getSyncInfo(RESOURCE_SYNC_KEY, container); + if(diBytes != null) { + di = new String(diBytes); + setDirtyIndicator(container, di); + } + container.setSessionProperty(FOLDER_SYNC_RESTORED_KEY, FOLDER_SYNC_RESTORED); + } + return di; } catch (CoreException e) { throw CVSException.wrapException(e); } @@ -260,7 +295,7 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; } else { resource.setSessionProperty(DIRTY_COUNT, null); resource.setSessionProperty(DELETED_CHILDREN, null); - resource.setPersistentProperty(IS_DIRTY, null); + resource.setSessionProperty(IS_DIRTY, null); } } catch (CoreException e) { throw CVSException.wrapException(e); @@ -328,6 +363,10 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; /*package*/ void markFileAsUpdated(IFile file) throws CVSException { try { file.setSessionProperty(CLEAN_UPDATE, UPDATED_INDICATOR); + + // update dirty state so that decorators don't have to recompute after + // an update is completed. + contentsChangedByUpdate(file); } catch (CoreException e) { throw CVSException.wrapException(e); } @@ -394,4 +433,88 @@ import org.eclipse.team.internal.ccvs.core.util.SyncFileWriter; throw CVSException.wrapException(e); } } -} + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.resources.SyncInfoCache#isDirtyCacheFlushed(org.eclipse.core.resources.IContainer) + */ + boolean isDirtyCacheFlushed(IContainer resource) throws CVSException { + if (resource.exists()) { + try { + return resource.getSessionProperty(IS_DIRTY) == null; + } catch (CoreException e) { + throw CVSException.wrapException(e); + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext) + */ + public void doneSaving(ISaveContext context) { + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext) + */ + public void prepareToSave(ISaveContext context) throws CoreException { + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext) + */ + public void rollback(ISaveContext context) { + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext) + */ + public void saving(ISaveContext context) throws CoreException { + boolean fullSave = (context.getKind() == ISaveContext.FULL_SAVE); + boolean projectSave = (context.getKind() == ISaveContext.PROJECT_SAVE); + + if(projectSave || fullSave) { + // persist all session properties for folders into sync info. + final ISynchronizer synchronizer = ResourcesPlugin.getWorkspace().getSynchronizer(); + synchronizer.add(RESOURCE_SYNC_KEY); + + // traverse the workspace looking for CVS managed projects or just the + // specific projects being closed + IProject[] projects; + if(projectSave) { + projects = new IProject[1]; + projects[0] = context.getProject(); + } else { + projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + } + for (int i = 0; i < projects.length; i++) { + IProject project = projects[i]; + RepositoryProvider provider = RepositoryProvider.getProvider( + project, + CVSProviderPlugin.getTypeId()); + + // found a project managed by CVS, convert each session property on a + // folder to a sync object. + if (provider != null) { + project.accept(new IResourceVisitor() { + public boolean visit(IResource resource) throws CoreException { + if(resource.getType() != IResource.FILE) { + String di = null; + try { + di = getDirtyIndicator(resource); + } catch (CVSException e) { + // continue traversal + CVSProviderPlugin.log(e); + } + if(di != null) { + synchronizer.setSyncInfo(RESOURCE_SYNC_KEY, resource, di.getBytes()); + } + } + return true; + } + }); + } + } + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SyncInfoCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SyncInfoCache.java index 6d4960048..6da5e77ab 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SyncInfoCache.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SyncInfoCache.java @@ -141,4 +141,10 @@ import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; * @param container */ /*package*/ abstract void setResourceSyncInfoCached(IContainer container) throws CVSException; + + /** + * @param resource + * @return boolean + */ + /*package*/ abstract boolean isDirtyCacheFlushed(IContainer resource) throws CVSException; } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SynchronizerSyncInfoCache.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SynchronizerSyncInfoCache.java index ba1b54c28..a3127858c 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SynchronizerSyncInfoCache.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/SynchronizerSyncInfoCache.java @@ -449,4 +449,11 @@ import org.eclipse.team.internal.ccvs.core.util.Util; boolean isFolderSyncInfoCached(IContainer container) throws CVSException { return true; } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ccvs.core.resources.SyncInfoCache#isDirtyCacheFlushed(org.eclipse.core.resources.IContainer) + */ + boolean isDirtyCacheFlushed(IContainer resource) throws CVSException { + return false; + } } diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/AddDeleteMoveListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/AddDeleteMoveListener.java index cf53ff9b9..a01d648ce 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/AddDeleteMoveListener.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/AddDeleteMoveListener.java @@ -201,6 +201,13 @@ public class AddDeleteMoveListener implements IResourceDeltaVisitor, IResourceCh for (int i = 0; i < projectDeltas.length; i++) { final IResourceDelta delta = projectDeltas[i]; IResource resource = delta.getResource(); + + if (resource.getType() == IResource.PROJECT) { + // If the project is not accessible, don't process it + if (!resource.isAccessible()) continue; + if ((delta.getFlags() & IResourceDelta.OPEN) != 0) continue; + } + RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject(), CVSProviderPlugin.getTypeId()); // Make sure that the project is a CVS folder. diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java index 5f6f54656..1eda04cf6 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java @@ -73,6 +73,7 @@ public class SyncFileChangeListener implements IResourceChangeListener { if (resource.getType() == IResource.PROJECT) { // If the project is not accessible, don't process it if (!resource.isAccessible()) return false; + if ((delta.getFlags() & IResourceDelta.OPEN) != 0) return false; } String name = resource.getName(); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java index fd1e87649..660284af0 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java @@ -431,9 +431,8 @@ public class SharingWizard extends Wizard implements IConfigurationWizard { // for now, just unmanage folder.unmanage(null); } - folder.acceptChildren(this); } - }); + }, true /* recurse */); } catch (CVSException e) { // log the exception and return null CVSUIPlugin.log(e); |