Bug 573421 - Avoid local history for derived files Added a configuration whether history for derived files is kept. Off by default. Change-Id: I27eba608269c2d96827066bab86496bd1bfa20f2 Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.resources/+/180356 Tested-by: Lars Vogel <Lars.Vogel@vogella.com> Reviewed-by: Lars Vogel <Lars.Vogel@vogella.com>
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/DeleteVisitor.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/DeleteVisitor.java index c4bf28a..ff9ba18 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/DeleteVisitor.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/DeleteVisitor.java
@@ -118,7 +118,9 @@ IFileInfo info = node.fileInfo; if (info == null) info = new FileInfo(node.getLocalName()); - store.addState(target.getFullPath(), node.getStore(), info, true); + if (FileSystemResourceManager.storeHistory(node.getResource())) { + store.addState(target.getFullPath(), node.getStore(), info, true); + } } monitor.worked(1); ticks--;
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java index dbd60dd..9045f3a 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java
@@ -1149,7 +1149,8 @@ } } // add entry to History Store. - if (BitMask.isSet(updateFlags, IResource.KEEP_HISTORY) && fileInfo.exists()) + if (BitMask.isSet(updateFlags, IResource.KEEP_HISTORY) && fileInfo.exists() + && FileSystemResourceManager.storeHistory(target)) //never move to the history store, because then the file is missing if write fails getHistoryStore().addState(target.getFullPath(), store, fileInfo, false); if (!fileInfo.exists()) { @@ -1250,4 +1251,10 @@ //for backwards compatibility, ensure the old .prj file is deleted getWorkspace().getMetaArea().clearOldDescription(target); } + + public static boolean storeHistory(IResource file) { + WorkspaceDescription description = ((Workspace) file.getWorkspace()).internalGetDescription(); + return description.isKeepDerivedState() || !file.isDerived(); + } + }
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/IModelObjectConstants.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/IModelObjectConstants.java index ec9e5e7..d9a6efb 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/IModelObjectConstants.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/IModelObjectConstants.java
@@ -37,6 +37,8 @@ String FILE_STATE_LONGEVITY = "fileStateLongevity"; //$NON-NLS-1$ String MAX_FILE_STATE_SIZE = "maxFileStateSize"; //$NON-NLS-1$ String MAX_FILE_STATES = "maxFileStates"; //$NON-NLS-1$ + String KEEP_DERIVED_STATE = "keepDerivedState"; //$NON-NLS-1$ + /** * The project relative path is called the link name for backwards compatibility */
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ModelObjectWriter.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ModelObjectWriter.java index d3c2757..70c0f44 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ModelObjectWriter.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ModelObjectWriter.java
@@ -294,6 +294,7 @@ writer.printSimpleTag(FILE_STATE_LONGEVITY, description.getFileStateLongevity()); writer.printSimpleTag(MAX_FILE_STATE_SIZE, description.getMaxFileStateSize()); writer.printSimpleTag(MAX_FILE_STATES, description.getMaxFileStates()); + writer.printSimpleTag(KEEP_DERIVED_STATE, description.isKeepDerivedState() ? "1" : "0"); //$NON-NLS-1$ //$NON-NLS-2$ String[] order = description.getBuildOrder(false); if (order != null) write(BUILD_ORDER, PROJECT, order, writer);
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/PreferenceInitializer.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/PreferenceInitializer.java index 1e6599b..156f03f 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/PreferenceInitializer.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/PreferenceInitializer.java
@@ -41,6 +41,7 @@ public static final boolean PREF_APPLY_FILE_STATE_POLICY_DEFAULT = true; public static final long PREF_FILE_STATE_LONGEVITY_DEFAULT = 7 * 24 * 3600 * 1000l; // 7 days public static final long PREF_MAX_FILE_STATE_SIZE_DEFAULT = 1024 * 1024l; // 1 MB + public static final boolean PREF_KEEP_DERIVED_STATE_DEFAULT = false; public static final int PREF_MAX_FILE_STATES_DEFAULT = 50; public static final long PREF_DELTA_EXPIRATION_DEFAULT = 30 * 24 * 3600 * 1000l; // 30 days /** @@ -76,11 +77,13 @@ node.putBoolean(ResourcesPlugin.PREF_DEFAULT_BUILD_ORDER, PREF_DEFAULT_BUILD_ORDER_DEFAULT); node.putInt(ResourcesPlugin.PREF_MISSING_NATURE_MARKER_SEVERITY, PREF_MISSING_NATURE_MARKER_SEVERITY_DEFAULT); + // history store defaults node.putBoolean(ResourcesPlugin.PREF_APPLY_FILE_STATE_POLICY, PREF_APPLY_FILE_STATE_POLICY_DEFAULT); node.putLong(ResourcesPlugin.PREF_FILE_STATE_LONGEVITY, PREF_FILE_STATE_LONGEVITY_DEFAULT); node.putLong(ResourcesPlugin.PREF_MAX_FILE_STATE_SIZE, PREF_MAX_FILE_STATE_SIZE_DEFAULT); node.putInt(ResourcesPlugin.PREF_MAX_FILE_STATES, PREF_MAX_FILE_STATES_DEFAULT); + node.putBoolean(ResourcesPlugin.PREF_KEEP_DERIVED_STATE, PREF_KEEP_DERIVED_STATE_DEFAULT); // save manager defaults node.putLong(ResourcesPlugin.PREF_SNAPSHOT_INTERVAL, PREF_SNAPSHOT_INTERVAL_DEFAULT);
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java index b0b0418..909aaad 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ResourceTree.java
@@ -61,6 +61,9 @@ */ @Override public void addToLocalHistory(IFile file) { + if (!FileSystemResourceManager.storeHistory(file)) { + return; + } Assert.isLegal(isValid); try { lock.acquire();
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceDescription.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceDescription.java index 87687de..0859d78 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceDescription.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceDescription.java
@@ -28,6 +28,7 @@ protected int maxBuildIterations; protected int maxFileStates; protected long maxFileStateSize; + private boolean keepDerivedState; protected boolean applyFileStatePolicy; private long snapshotInterval; protected int operationsPerSnapshot; @@ -44,6 +45,8 @@ fileStateLongevity = node.getLong(ResourcesPlugin.PREF_FILE_STATE_LONGEVITY, PreferenceInitializer.PREF_FILE_STATE_LONGEVITY_DEFAULT); maxFileStates = node.getInt(ResourcesPlugin.PREF_MAX_FILE_STATES, PreferenceInitializer.PREF_MAX_FILE_STATES_DEFAULT); maxFileStateSize = node.getLong(ResourcesPlugin.PREF_MAX_FILE_STATE_SIZE, PreferenceInitializer.PREF_MAX_FILE_STATE_SIZE_DEFAULT); + keepDerivedState = node.getBoolean(ResourcesPlugin.PREF_KEEP_DERIVED_STATE, + PreferenceInitializer.PREF_KEEP_DERIVED_STATE_DEFAULT); snapshotInterval = node.getLong(ResourcesPlugin.PREF_SNAPSHOT_INTERVAL, PreferenceInitializer.PREF_SNAPSHOT_INTERVAL_DEFAULT); operationsPerSnapshot = node.getInt(PreferenceInitializer.PREF_OPERATIONS_PER_SNAPSHOT, PreferenceInitializer.PREF_OPERATIONS_PER_SNAPSHOT_DEFAULT); deltaExpiration = node.getLong(PreferenceInitializer.PREF_DELTA_EXPIRATION, PreferenceInitializer.PREF_DELTA_EXPIRATION_DEFAULT); @@ -213,4 +216,14 @@ public void setMaxConcurrentBuilds(int n) { this.parallelBuildsCount = n; } + + @Override + public boolean isKeepDerivedState() { + return keepDerivedState; + } + + @Override + public void setKeepDerivedState(boolean keepDerivedState) { + this.keepDerivedState = keepDerivedState; + } }
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceDescriptionReader.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceDescriptionReader.java index 9a2aa02..06fa124 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceDescriptionReader.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceDescriptionReader.java
@@ -116,6 +116,8 @@ String fileStateLongevity = getString(node, FILE_STATE_LONGEVITY); String maxFileStateSize = getString(node, MAX_FILE_STATE_SIZE); String maxFileStates = getString(node, MAX_FILE_STATES); + String keepDerivedState = getString(node, KEEP_DERIVED_STATE); + String[] buildOrder = getStrings(searchNode(node, BUILD_ORDER)); // build instance @@ -145,6 +147,9 @@ } catch (NumberFormatException e) { logNumberFormatException(maxFileStates, e); } + if (keepDerivedState != null) + // if in doubt keep derived off + description.setKeepDerivedState(keepDerivedState.equals(Integer.toString(1))); if (buildOrder != null) description.internalSetBuildOrder(buildOrder); try {
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspacePreferences.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspacePreferences.java index d5cb26b..65fc7d8 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspacePreferences.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspacePreferences.java
@@ -75,6 +75,7 @@ target.setFileStateLongevity(source.getFileStateLongevity()); target.setMaxFileStates(source.getMaxFileStates()); target.setMaxFileStateSize(source.getMaxFileStateSize()); + target.setKeepDerivedState(source.isKeepDerivedState()); target.setSnapshotInterval(source.getSnapshotInterval()); target.setOperationsPerSnapshot(source.getOperationsPerSnapshot()); target.setDeltaExpiration(source.getDeltaExpiration()); @@ -100,6 +101,7 @@ super.setOperationsPerSnapshot(preferences.getInt(PreferenceInitializer.PREF_OPERATIONS_PER_SNAPSHOT)); super.setDeltaExpiration(preferences.getLong(PreferenceInitializer.PREF_DELTA_EXPIRATION)); super.setMaxConcurrentBuilds(preferences.getInt(ResourcesPlugin.PREF_MAX_CONCURRENT_BUILDS)); + super.setKeepDerivedState(preferences.getBoolean(ResourcesPlugin.PREF_KEEP_DERIVED_STATE)); // This property listener ensures we are being updated properly when changes // are done directly to the preference store. @@ -215,6 +217,11 @@ preferences.setValue(ResourcesPlugin.PREF_MAX_CONCURRENT_BUILDS, n); } + @Override + public void setKeepDerivedState(boolean keepDerivedState) { + preferences.setValue(ResourcesPlugin.PREF_KEEP_DERIVED_STATE, keepDerivedState); + } + /** * @see org.eclipse.core.resources.IWorkspaceDescription#setSnapshotInterval(long) */ @@ -245,8 +252,10 @@ super.setOperationsPerSnapshot(preferences.getInt(PreferenceInitializer.PREF_OPERATIONS_PER_SNAPSHOT)); else if (property.equals(PreferenceInitializer.PREF_DELTA_EXPIRATION)) super.setDeltaExpiration(preferences.getLong(PreferenceInitializer.PREF_DELTA_EXPIRATION)); - else if (property.equals(ResourcesPlugin.PREF_MAX_CONCURRENT_BUILDS)) { + else if (property.equals(ResourcesPlugin.PREF_MAX_CONCURRENT_BUILDS)) super.setMaxConcurrentBuilds(preferences.getInt(ResourcesPlugin.PREF_MAX_CONCURRENT_BUILDS)); + else if (property.equals(ResourcesPlugin.PREF_KEEP_DERIVED_STATE)) { + super.setKeepDerivedState(preferences.getBoolean(ResourcesPlugin.PREF_KEEP_DERIVED_STATE)); } }
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IWorkspaceDescription.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IWorkspaceDescription.java index 339aec0..df1d6ec 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IWorkspaceDescription.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IWorkspaceDescription.java
@@ -89,6 +89,16 @@ long getMaxFileStateSize(); /** + * Returns whether derived files are tracked in the local history. + * + * @return <code>true</code> if local history for derived files is created + * @see #setKeepDerivedState(boolean) + * @see ResourcesPlugin#PREF_KEEP_DERIVED_STATE + * @since 3.15 + */ + boolean isKeepDerivedState(); + + /** * Returns whether file states are discarded according to the policy specified by * <code>setFileStateLongevity(long)</code>, <code>setMaxFileStates(int)</code> * and <code>setMaxFileStateSize(long)</code> methods. @@ -233,6 +243,22 @@ void setMaxFileStateSize(long size); /** + * Sets whether derived files are tracked in the local history. + * <p> + * Users must call <code>IWorkspace.setDescription</code> before changes made to + * this description take effect. + * </p> + * + * @param keepDerivedState <code>true</code> if a history of derived files is + * needed. + * @see IWorkspace#setDescription(IWorkspaceDescription) + * @see #isKeepDerivedState() + * @see ResourcesPlugin#PREF_KEEP_DERIVED_STATE + * @since 3.15 + */ + void setKeepDerivedState(boolean keepDerivedState); + + /** * Sets whether file states are discarded according to the policy specified by * <code>setFileStateLongevity(long)</code>, <code>setMaxFileStates(int)</code> * and <code>setMaxFileStateSize(long)</code> methods.
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/ResourcesPlugin.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/ResourcesPlugin.java index 0b06c2f..927093d 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/ResourcesPlugin.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/ResourcesPlugin.java
@@ -263,6 +263,16 @@ public static final String PREF_MAX_FILE_STATE_SIZE = PREF_DESCRIPTION_PREFIX + "maxfilestatesize"; //$NON-NLS-1$ /** + * Name of a preference for configuring whether derived files should be stored + * in the local history. + * + * @see IWorkspaceDescription#isKeepDerivedState() + * @see IWorkspaceDescription#setKeepDerivedState(boolean) + * @since 3.15 + */ + public static final String PREF_KEEP_DERIVED_STATE = PREF_DESCRIPTION_PREFIX + "keepDerivedState"; //$NON-NLS-1$ + + /** * Name of a preference for configuring the maximum number of states per * file that can be stored in the local history. *
diff --git a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/WorkspacePreferencesTest.java b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/WorkspacePreferencesTest.java index 47296c6..23b8945 100644 --- a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/WorkspacePreferencesTest.java +++ b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/WorkspacePreferencesTest.java
@@ -101,6 +101,11 @@ assertEquals("3.2", defaultSnapshotInterval, workspace.getDescription().getSnapshotInterval()); assertEquals("Description not synchronized", workspace.getDescription(), preferences); + preferences.setValue(ResourcesPlugin.PREF_KEEP_DERIVED_STATE, false); + assertFalse("4.0", workspace.getDescription().isKeepDerivedState()); + + preferences.setValue(ResourcesPlugin.PREF_KEEP_DERIVED_STATE, true); + assertTrue("4.1", workspace.getDescription().isKeepDerivedState()); } /** @@ -126,6 +131,8 @@ modified.setMaxFileStateSize((original.getMaxFileStateSize() + 1) * 2); // 8 - PREF_SNAPSHOT_INTERVAL modified.setSnapshotInterval((original.getSnapshotInterval() + 1) * 2); + // 9 - PREF_SNAPSHOT_INTERVAL + modified.setKeepDerivedState(!original.isKeepDerivedState()); final List<String> changedProperties = new LinkedList<>(); Preferences.IPropertyChangeListener listener = event -> changedProperties.add(event.getProperty()); @@ -144,7 +151,7 @@ fail("2.0", e); } // the right number of events should have been fired - assertEquals("2.1 - wrong number of properties changed ", 9, changedProperties.size()); + assertEquals("2.1 - wrong number of properties changed ", 10, changedProperties.size()); } finally { preferences.removePropertyChangeListener(listener); } @@ -181,6 +188,7 @@ modified.setMaxFileStates((original.getMaxFileStates() + 1) * 2); modified.setMaxFileStateSize((original.getMaxFileStateSize() + 1) * 2); modified.setSnapshotInterval((original.getSnapshotInterval() + 1) * 2); + modified.setKeepDerivedState(!original.isKeepDerivedState()); // sets modified description try { @@ -234,6 +242,7 @@ description.setMaxFileStates(16); description.setMaxFileStateSize(100050); description.setSnapshotInterval(1234567); + description.setKeepDerivedState(true); try { workspace.setDescription(description); } catch (CoreException ce) { @@ -270,6 +279,7 @@ description.setMaxFileStates(Math.abs((int) (Math.random() * 100000L))); description.setMaxFileStateSize(Math.abs((long) (Math.random() * 100000L))); description.setSnapshotInterval(Math.abs((long) (Math.random() * 100000L))); + description.setKeepDerivedState(true); LocalMetaArea localMetaArea = ((Workspace) workspace).getMetaArea(); try { localMetaArea.write(description); @@ -296,6 +306,8 @@ assertEquals(message + " - 7", description.getMaxFileStateSize(), preferences.getLong(ResourcesPlugin.PREF_MAX_FILE_STATE_SIZE)); assertEquals(message + " - 8", description.getSnapshotInterval(), preferences.getLong(ResourcesPlugin.PREF_SNAPSHOT_INTERVAL)); assertEquals(message + " - 9", description.getMaxBuildIterations(), preferences.getLong(ResourcesPlugin.PREF_MAX_BUILD_ITERATIONS)); + assertEquals(message + " -10", description.isKeepDerivedState(), + preferences.getBoolean(ResourcesPlugin.PREF_KEEP_DERIVED_STATE)); } /** @@ -311,5 +323,6 @@ assertEquals(message + " - 7", description1.getMaxFileStateSize(), description2.getMaxFileStateSize()); assertEquals(message + " - 8", description1.getSnapshotInterval(), description2.getSnapshotInterval()); assertEquals(message + " - 9", description1.getMaxBuildIterations(), description2.getMaxBuildIterations()); + assertEquals(message + " -10", description1.isKeepDerivedState(), description2.isKeepDerivedState()); } }