Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 8369 Details for
Bug 36958
[plan item] Support workspace checkpoint and rollback
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
patch to org.eclipse.core.resources
org.eclipse.core.resources.checkpoints (text/plain), 34.87 KB, created by
Chris Tilt
on 2004-03-05 16:22:09 EST
(
hide
)
Description:
patch to org.eclipse.core.resources
Filename:
MIME Type:
Creator:
Chris Tilt
Created:
2004-03-05 16:22:09 EST
Size:
34.87 KB
patch
obsolete
>Index: src/org/eclipse/core/internal/localstore/HistoryStore.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java,v >retrieving revision 1.26 >diff -u -r1.26 HistoryStore.java >--- src/org/eclipse/core/internal/localstore/HistoryStore.java 5 Aug 2003 14:59:00 -0000 1.26 >+++ src/org/eclipse/core/internal/localstore/HistoryStore.java 5 Mar 2004 20:26:07 -0000 >@@ -12,21 +12,66 @@ > > import java.io.File; > import java.io.InputStream; >-import java.util.*; >-import org.eclipse.core.internal.indexing.*; >+import java.util.ArrayList; >+import java.util.Date; >+import java.util.HashSet; >+import java.util.Iterator; >+import java.util.LinkedList; >+import java.util.List; >+import java.util.Set; >+ >+import org.eclipse.core.internal.indexing.IndexCursor; >+import org.eclipse.core.internal.indexing.IndexedStoreException; >+import org.eclipse.core.internal.indexing.ObjectID; > import org.eclipse.core.internal.properties.IndexedStoreWrapper; >-import org.eclipse.core.internal.resources.*; >-import org.eclipse.core.internal.utils.*; >-import org.eclipse.core.resources.*; >-import org.eclipse.core.runtime.*; >+import org.eclipse.core.internal.resources.FileState; >+import org.eclipse.core.internal.resources.ICoreConstants; >+import org.eclipse.core.internal.resources.ResourceException; >+import org.eclipse.core.internal.resources.ResourceStatus; >+import org.eclipse.core.internal.resources.Workspace; >+import org.eclipse.core.internal.resources.WorkspaceDescription; >+import org.eclipse.core.internal.utils.Convert; >+import org.eclipse.core.internal.utils.Policy; >+import org.eclipse.core.internal.utils.UniversalUniqueIdentifier; >+import org.eclipse.core.resources.Checkpoint; >+import org.eclipse.core.resources.IContainer; >+import org.eclipse.core.resources.IFile; >+import org.eclipse.core.resources.IFileState; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.IResourceStatus; >+import org.eclipse.core.resources.IResourceVisitor; >+import org.eclipse.core.resources.IWorkspaceDescription; >+import org.eclipse.core.resources.ResourcesPlugin; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.Path; > >+/* >+ * HistoryStore >+ * >+ * Maintain Local History for the workspace. >+ * <p> >+ * Checkpoint notes: >+ * </p><p> >+ * Checkpoint garbage collection strategy is to remove all checkoints >+ * that would be invalidated by the removal of a local history entry, >+ * except in the case where a Project is deleted. Local History is >+ * deleted whenever a project is deleted, which could easily cause us >+ * to lose the entire set of checkpoints for other projects in the >+ * workspace. That would be too limiting. Normal garbage collection of >+ * local history entries due to expiration or limit counts will cause >+ * all affected checkpoints to be removed. >+ * </p> >+ */ > public class HistoryStore { > protected Workspace workspace; > protected IPath location; > protected BlobStore blobStore; > private IndexedStoreWrapper store; > private final static String INDEX_FILE = ".index"; //$NON-NLS-1$ >- >+ private final static String CHECKPOINT_FILE = ".checkpoints.txt"; //$NON-NLS-1$ >+ private CheckpointFileStore fCheckpointStore; > //flag used inside stateAlreadyExists to prevent creating an array > protected boolean stateAlreadyExists; > >@@ -34,6 +79,14 @@ > this.workspace = workspace; > blobStore = new BlobStore(location, limit); > store = new IndexedStoreWrapper(location.append(INDEX_FILE)); >+ fCheckpointStore = new CheckpointFileStore(location.append(CHECKPOINT_FILE)); >+ initCheckpointStore(); >+} >+ >+private void initCheckpointStore() { >+ long time = System.currentTimeMillis(); >+ Date date = new Date(time); >+ fCheckpointStore.addCheckpoint("session startup "+date.toString()); > } > /** > * Searches indexed store for key, and invokes visitor's defined behaviour on key matches. >@@ -181,7 +234,7 @@ > HistoryStoreEntry entry = HistoryStoreEntry.create(store, cursor); > // is it old? > if (entry.getLastModified() < minimumTimestamp) { >- remove(entry); >+ remove(entry, true); > continue; > } > if (!entry.getPath().equals(current)) { >@@ -197,6 +250,8 @@ > cursor.close(); > store.commit(); > removeGarbage(blobs); >+ // clean up the Checkpoint store as well. >+ fCheckpointStore.clean(minimumTimestamp); > } catch (Exception e) { > String message = Policy.bind("history.problemsCleaning"); //$NON-NLS-1$ > ResourceStatus status = new ResourceStatus(IResourceStatus.FAILED_DELETE_LOCAL, null, message, e); >@@ -378,15 +433,22 @@ > ", max: " + description.getMaxFileStateSize()); //$NON-NLS-1$ > return result; > } >-protected void remove(HistoryStoreEntry entry) throws IndexedStoreException { >+protected void remove(HistoryStoreEntry entry, boolean cleanCheckpoints) throws IndexedStoreException { > // Do not remove the blob yet. It may be referenced by another > // history store entry. > entry.remove(); >+ // collect any corresponding checkpoints that would be invalidated by >+ // the removal of this entry >+ if (cleanCheckpoints) { >+ fCheckpointStore.clean(entry.getLastModified()); >+ } > } > /** > * Removes all file states from this store. > */ > public void removeAll() { >+ // GC the checkpoints en mass so that calls to clean() are fast. >+ fCheckpointStore.cleanAll(); > // XXX: should implement a method with a better performance > removeAll(workspace.getRoot()); > } >@@ -397,7 +459,7 @@ > cursor.find(key); > while (cursor.keyMatches(key)) { > HistoryStoreEntry entry = HistoryStoreEntry.create(store, cursor); >- remove(entry); >+ remove(entry, false); > } > cursor.close(); > store.commit(); >@@ -439,8 +501,10 @@ > if (entries.size() <= maxEntries) > return; > int limit = entries.size() - maxEntries; >- for (int i = 0; i < limit; i++) >- remove((HistoryStoreEntry) entries.get(i)); >+ for (int i = 0; i < limit; i++) { >+ HistoryStoreEntry entry = (HistoryStoreEntry) entries.get(i); >+ remove(entry, true); >+ } > } > public void shutdown(IProgressMonitor monitor) { > if (store == null) >@@ -451,6 +515,7 @@ > } > protected void resetIndexedStore() { > store.reset(); >+ fCheckpointStore.reset(); > IPath location = workspace.getMetaArea().getHistoryStoreLocation(); > java.io.File target = location.toFile(); > Workspace.clear(target); >@@ -501,5 +566,155 @@ > accept(path, new PathCollector(), true); > return allFiles; > } >+ /** >+ * Add a new Checkpoint to the local history >+ */ >+ public void addCheckpoint(Checkpoint checkpoint) { >+ fCheckpointStore.addCheckpoint(checkpoint); >+ } >+ >+ /** >+ * Get the complete list of valid Checkpoints. >+ * Checkpoints for which there are no Local History States are not returned. >+ * The returned list is a deep copy, so any changes you make to the list or >+ * to the elements have no effect on the Local History or Checkpoint Store. >+ * @return List of <code>Checkpoint</code> objects >+ */ >+ public List getCheckpoints() { >+ return fCheckpointStore.getCheckpointsClone(); >+ } >+ /** >+ * Return the resources needed to rollback the workspace to the specified time. >+ * @param rollbackTime time to roll the workspace back to. >+ * @return Set[0] is a set of type <code>IFileState</code> that should be restored. >+ * Set[1] is a set of type <code>IFile</code> that should be deleted. >+ */ >+ public Set[] getRestoreAndDeleteFallbackStates (long rollbackTime) { >+ Set sets[] = {null, null}; >+ Set oldFileStates = getRollbackFileStates(rollbackTime); >+ Set modifiedSinceFiles = getFilesModifiedSince(rollbackTime); >+ Set restoreStates = new HashSet(); >+ Set deleteStates = new HashSet(); >+ >+ // restore files are those files modified just previous to and >+ // not after the rollback time. >+ Iterator states = oldFileStates.iterator(); >+ while (states.hasNext()) { >+ IFileState state = (IFileState) states.next(); >+ if (containsState(state, modifiedSinceFiles)) { >+ restoreStates.add(state); >+ } >+ } >+ // deleted files are those files modified since the rollback time, but >+ // not appearing in local history. They must have been created since >+ // the rollback time. >+ Iterator files = modifiedSinceFiles.iterator(); >+ while (files.hasNext()) { >+ IFile file = (IFile) files.next(); >+ if (!containsFile(file, oldFileStates)) { >+ deleteStates.add(file); >+ } >+ } >+ sets[0] = restoreStates; >+ sets[1] = deleteStates; >+ return sets; >+ } >+ >+ private boolean containsFile(IFile file, Set stateSet) { >+ String filePath = file.getFullPath().toString(); >+ >+ Iterator iter = stateSet.iterator(); >+ while (iter.hasNext()) { >+ IFileState state = (IFileState) iter.next(); >+ if (filePath.equals(state.getFullPath().toString())) { >+ return true; >+ } >+ } >+ return false; >+ } >+ >+ private boolean containsState(IFileState state, Set fileSet) { >+ String statePath = state.getFullPath().toString(); >+ >+ Iterator iter = fileSet.iterator(); >+ while (iter.hasNext()) { >+ IFile file = (IFile) iter.next(); >+ if (statePath.equals(file.getFullPath().toString())) { >+ return true; >+ } >+ } >+ return false; >+ } >+ >+ /** >+ * Return the files from the workspace that are new since the last >+ * modification time. >+ * >+ * @param lastModified return files newer than this date >+ * @return the set of newer files from the workspace. Element >+ * type is <code>IFile</code>. >+ */ >+ private Set getFilesModifiedSince(final long lastModified) { >+ final Set set = new HashSet(); >+ IResource root = workspace.getRoot(); >+ IResourceVisitor visitor = new IResourceVisitor() { >+ public boolean visit(IResource resource) { >+ // boolean isLinked = resource.isLinked(); >+ if (resource.getType() == IResource.FILE) { >+ IFile file = (IFile) resource; >+ if (file.getLocalTimeStamp() >= lastModified) { >+ set.add(file); >+ } >+ } >+ return true; >+ }}; >+ try { >+ root.accept(visitor, IResource.DEPTH_INFINITE, IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS); >+ } catch (CoreException e) { >+ // No exception should be thrown. >+ } >+ return set; >+ } > >+ /** >+ * Examine the last modification times of all file >+ * states stored in the local history and return the set of file states that are >+ * present which have modifications nearest and previous to the rollback time. >+ * >+ * @param rollbackTime >+ * @return Set the set of all file states that should be restored for this target rollback time. >+ * (element type is IFileState). >+ */ >+ private Set getRollbackFileStates(long rollbackTime) { >+ // collect all files in the space most proximal to, and younger than <code>lastModified</code> >+ Set rollbackStates = new HashSet(); >+ >+ Set set = allFiles(new Path("/"), IResource.DEPTH_INFINITE); //$NON-NLS-1$ >+ Iterator paths = set.iterator(); >+ >+ // for all file paths, add the one state needed for rollback >+ while (paths.hasNext()) { >+ IPath path = (IPath) paths.next(); >+ IFileState[] states = getStates(path); >+ boolean stateFound = false; >+ >+ // select the state that occurs just before the rollbackTime, maybe none, by >+ // looking through all stored states for this path and selecting the one that has >+ // a lastmodification time just before the rollback time. If there is none, then >+ // this file is not needed for rollback. >+ // >+ // states must be sorted from youngest to oldest for this implementation, >+ // which currently is true using getStates(). >+ >+ for (int i=0; i<states.length; i++) { >+ IFileState state = states[i]; >+ if (!stateFound && state.getModificationTime() < rollbackTime) { >+ stateFound = true; >+ rollbackStates.add(state); >+ continue; >+ } >+ } >+ } >+ return rollbackStates; >+ } > } >Index: src/org/eclipse/core/internal/localstore/CheckpointFileStore.java >=================================================================== >RCS file: src/org/eclipse/core/internal/localstore/CheckpointFileStore.java >diff -N src/org/eclipse/core/internal/localstore/CheckpointFileStore.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/localstore/CheckpointFileStore.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,213 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2004 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Common Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/cpl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.core.internal.localstore; >+ >+import java.io.BufferedReader; >+import java.io.File; >+import java.io.FileNotFoundException; >+import java.io.FileOutputStream; >+import java.io.FileReader; >+import java.io.IOException; >+import java.io.OutputStream; >+import java.util.ArrayList; >+import java.util.Iterator; >+import java.util.List; >+ >+import org.eclipse.core.internal.utils.Assert; >+import org.eclipse.core.resources.Checkpoint; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+ >+/** >+ * A file storage mechanism for Checkpoints. >+ * >+ * Checkpoints are stored sequentially in a store. New Checkpoints are written to >+ * the end of the store. Old Checkpoints are periodically cleaned up from the front >+ * of the store (presumably when the Local History Entries are cleaned up and thus >+ * invalidate the Checkpoint). >+ */ >+public class CheckpointFileStore extends CheckpointStore { >+ /* >+ * location of CheckpointStore >+ */ >+ protected IPath fLocation = null; >+ protected byte[] fNewline = {'\r','\n'}; >+ >+ /* >+ * Construct a file-based store for Checkpoints >+ */ >+ public CheckpointFileStore(IPath location) { >+ // ensure the location path is valid >+ Assert.isNotNull(location); >+ Assert.isTrue(!location.equals(Path.EMPTY)); >+ fLocation = location; >+ } >+ >+ /* >+ * Write the checkpoint to the checkoint store right now. (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#addCheckpoint(org.eclipse.core.internal.localstore.Checkpoint) >+ */ >+ public void addCheckpoint(Checkpoint cp) { >+ // write to the end of the file >+ try { >+ // open in append-mode >+ OutputStream output = new FileOutputStream(fLocation.toFile(), true); >+ try { >+ byte[] bytes = cp.getBytes(); >+ store(output, bytes); >+ } finally { >+ output.close(); >+ } >+ } catch (IOException e) { >+ String message = "CheckpointFileStore: failed to write checkpoint"; //$NON-NLS-1$ >+ // TODO: log an error >+ } >+ } >+ >+ /* >+ * add checkpoint for current time and specified label >+ */ >+ public void addCheckpoint (String label) { >+ addCheckpoint(label, System.currentTimeMillis()); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#getCheckpointsClone() >+ */ >+ public synchronized List getCheckpointsClone () { >+ // reading is faster with just one synchronize call at the top level >+ // rather than for each readLine(). It's unlikely anyone will be >+ // writing new checkpoints while we read the old ones, however, so >+ // the write-delay case is rare. >+ List list = new ArrayList(); >+ BufferedReader reader = null; >+ try { >+ reader = new BufferedReader(new FileReader(fLocation.toFile())); >+ while (reader.ready()) { >+ String line = reader.readLine(); >+ Checkpoint cp = Checkpoint.createCheckpoint(line); >+ if (cp != null) { >+ list.add(cp); >+ } >+ } >+ return list; >+ } catch (FileNotFoundException e) { >+ // TODO report badness via proper Logging >+ String message = "FileNotFoundException: "+fLocation.toFile(); //$NON-NLS-1$ >+ } catch (IOException e) { >+ // TODO report badness via proper Logging >+ String message = "IOException: reading checkpoints from "+fLocation.toFile(); //$NON-NLS-1$ >+ } finally { >+ try { >+ if (reader != null) >+ reader.close(); >+ } catch (IOException e) { >+ // nothing more we can do. >+ } >+ } >+ return list; >+ } >+ >+ /** >+ * @return Returns the fLocation. >+ */ >+ public IPath getFLocation() { >+ return fLocation; >+ } >+ /** >+ * @param location The fLocation to set. >+ */ >+ public void setFLocation(IPath location) { >+ fLocation = location; >+ } >+ >+ /** >+ * @return Returns the fNewline. >+ */ >+ public byte[] getFNewline() { >+ return fNewline; >+ } >+ /** >+ * @param newline The fNewline to set. >+ */ >+ public void setFNewline(byte[] newline) { >+ fNewline = newline; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#clean(long) >+ */ >+ public void clean(long cutoffDate) { >+ // get the list from file storage, collect it >+ // and write it back out. >+ List checkpoints = getCheckpointsClone(); >+ int oldSize = checkpoints.size(); >+ if (oldSize > 0) { >+ // only try to GC non-empy checkoint lists >+ checkpoints = CheckpointListStore.collectList(checkpoints, cutoffDate); >+ if (checkpoints.size() < oldSize) { >+ // only write file if the list shrunk >+ writeCheckPointFile(checkpoints); >+ } >+ } >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#cleanAll() >+ */ >+ public void cleanAll() { >+ List checkpoints = new ArrayList(); >+ writeCheckPointFile(checkpoints); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#reset() >+ */ >+ public void reset() { >+ // nothing to do >+ } >+ >+ /* >+ * write a list of checkpoints to the file store >+ */ >+ private synchronized void writeCheckPointFile(List checkpoints) { >+ try { >+ // open in overwrite-mode >+ OutputStream output = new FileOutputStream(fLocation.toFile()); >+ try { >+ Iterator iter = checkpoints.iterator(); >+ while (iter.hasNext()) { >+ Checkpoint cp = (Checkpoint)iter.next(); >+ byte[] bytes = cp.getBytes(); >+ store(output, bytes); >+ } >+ } finally { >+ if (output != null) { >+ output.close(); >+ } >+ } >+ } catch (IOException e) { >+ String message = "CheckpointFileStore: failed to write checkpoint"; //$NON-NLS-1$ >+ // TODO: log an error >+ } >+ } >+ >+ /* >+ * Write the checkpoint to the end of the file, synchronized. >+ */ >+ private synchronized void store(OutputStream out, byte[] bytes) throws IOException { >+ out.write(bytes); >+ out.write(fNewline); >+ out.flush(); >+ } >+ >+} >Index: src/org/eclipse/core/internal/localstore/CheckpointListStore.java >=================================================================== >RCS file: src/org/eclipse/core/internal/localstore/CheckpointListStore.java >diff -N src/org/eclipse/core/internal/localstore/CheckpointListStore.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/localstore/CheckpointListStore.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,119 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2004 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Common Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/cpl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.core.internal.localstore; >+ >+import java.util.ArrayList; >+import java.util.Iterator; >+import java.util.List; >+import java.util.ListIterator; >+ >+import org.eclipse.core.resources.Checkpoint; >+ >+/** >+ * An in-memory storage mechanism for CheckpointEntry(s). >+ * >+ * Checkpoints are stored sequentially in a store. New Checkpoints are written to >+ * the end of the store. Old Checkpoints are periodically cleaned up from the front >+ * of the store (presumably when the Local History Entries are cleaned up and thus >+ * invalidate the Checkpoint). >+ */ >+public class CheckpointListStore extends CheckpointStore { >+ >+ // Storage for memory-based store (does not need to be sorted) >+ protected List fCheckpoints = null; >+ >+ /* >+ * Construct a memory-based store for Checkpoints. >+ * This is not persisted over Eclipse startup/shutdown. >+ */ >+ public CheckpointListStore() { >+ fCheckpoints = new ArrayList(); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#addCheckpoint(java.lang.String, long) >+ */ >+ public void addCheckpoint (String label, long lastmodified) { >+ Checkpoint cp = new Checkpoint(label,lastmodified); >+ addCheckpoint(cp); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#addCheckpoint(java.lang.String) >+ */ >+ public void addCheckpoint (String label) { >+ addCheckpoint(label, System.currentTimeMillis()); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#getCheckpointsClone() >+ */ >+ public List getCheckpointsClone () { >+ List cloneList = new ArrayList(); >+ ListIterator iter = fCheckpoints.listIterator(); >+ while (iter.hasNext()) { >+ Checkpoint cp = (Checkpoint ) iter.next(); >+ cloneList.add(cp.clone()); >+ } >+ return cloneList; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#addCheckpoint(org.eclipse.core.internal.localstore.Checkpoint) >+ */ >+ public void addCheckpoint(Checkpoint checkpoint) { >+ fCheckpoints.add(checkpoint); // ignore possible failure >+ } >+ /* (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#clean(long) >+ */ >+ public void clean(long cutoffDate) { >+ fCheckpoints = collectList(fCheckpoints, cutoffDate); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#cleanAll() >+ */ >+ public void cleanAll() { >+ fCheckpoints = new ArrayList(); >+ } >+ >+ /** >+ * Garbage collect the List, removing old checkpoints. >+ * Resulting list is unsorted. >+ * @param list list of Checkpoint(s) to garbage collect >+ * @param cutoffDate oldest date to collect >+ * @return list of surviving checkpoints >+ */ >+ static public synchronized List collectList(List list, long cutoffDate) { >+ // search entire list. the list is not assumed to be sorted >+ Iterator iter = list.iterator(); >+ List collectedList = new ArrayList(); >+ while (iter.hasNext()) { >+ Checkpoint cp = (Checkpoint)iter.next(); >+ if (cp.getLastModified() > cutoffDate) { >+ collectedList.add(cp); >+ } >+ } >+ return collectedList; >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.core.internal.localstore.CheckpointStore#reset() >+ */ >+ public void reset() { >+ // Nothing to do on a reset since we are in memory! >+ } >+ >+} >Index: src/org/eclipse/core/internal/localstore/CheckpointStore.java >=================================================================== >RCS file: src/org/eclipse/core/internal/localstore/CheckpointStore.java >diff -N src/org/eclipse/core/internal/localstore/CheckpointStore.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/internal/localstore/CheckpointStore.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,87 @@ >+/******************************************************************************* >+ * Copyright (c) 2004 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Common Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/cpl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.core.internal.localstore; >+ >+import java.util.List; >+ >+import org.eclipse.core.resources.*; >+ >+/** >+ * A storage mechanism for CheckpointEntry(s). >+ * >+ * Checkpoints are stored sequentially in a store. New Checkpoints are written to >+ * the end of the store. Old Checkpoints are periodically cleaned up from the front >+ * of the store (presumably when the Local History Entries are cleaned up and thus >+ * invalidate the Checkpoint). >+ * <p> >+ * The life cycle of checkpoints are simple. Call one of the <code>addCheckpoint</code> >+ * methods to add a new checkpoint label/time to the checkpoint store whenever you >+ * want. Later, you can get the list of checkpoints via <code>getCheckpointsClone</code>. >+ * <p> >+ * To garbage collect checkpoints, call <code>clean</code> with the oldest timestamp >+ * you want to remove. Checkpoints with timestamps younger than the one specified are >+ * kept. >+ */ >+public abstract class CheckpointStore { >+ >+ /** >+ * Construct a memory-based store for Checkpoints. >+ * This is not persisted over Eclipse startup/shutdown. >+ */ >+ public CheckpointStore() { >+ } >+ >+ /** >+ * add checkpoint for current time and specified label >+ * @param label readable name of the checkpoint >+ */ >+ public void addCheckpoint (String label) { >+ addCheckpoint(label, System.currentTimeMillis()); >+ } >+ >+ /** >+ * add checkpoint for specified label and time. >+ * @param label readable name of the checkpoint >+ * @param lastmodified datestamp of the checkpoint >+ */ >+ public void addCheckpoint (String label, long lastmodified) { >+ Checkpoint cp = new Checkpoint(label,lastmodified); >+ addCheckpoint(cp); >+ } >+ >+ public abstract void addCheckpoint(Checkpoint checkpoint); >+ >+ /** >+ * Return a deep copy of the List of checkpoints. Changes >+ * to the list or checkpoint elements have no effect on the store. >+ * @returns current list of <code>Checkpoint</code>s. >+ */ >+ public abstract List getCheckpointsClone (); >+ >+ /** >+ * Clean up old checkpoints. >+ * Any points having a last modified date equal to, or older than >+ * the specified date will be removed from the checkpoint store. >+ * @param cutoffDate remove points as old as this, and all older. >+ */ >+ public abstract void clean(long cutoffDate); >+ >+ /** >+ * Remove all checkpoints. >+ */ >+ public abstract void cleanAll(); >+ >+ /** >+ * Reset from a failure. >+ * Do a best effort to clean up and save what we can. >+ */ >+ public abstract void reset(); >+} >Index: src/org/eclipse/core/resources/Checkpoint.java >=================================================================== >RCS file: src/org/eclipse/core/resources/Checkpoint.java >diff -N src/org/eclipse/core/resources/Checkpoint.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/resources/Checkpoint.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,135 @@ >+/******************************************************************************* >+ * Copyright (c) 2004 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Common Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/cpl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.core.resources; >+ >+import org.eclipse.core.internal.utils.Convert; >+ >+ >+/** >+ * Represent one point in time that can be used as a rollback point for workspace >+ * resources. >+ * >+ * A checkpoint is defined by a user-settable label and a timestamp. It denotes >+ * a point in time that corresponds with resources in the local history store. >+ * A human or programmatic user can roll back to this point, assuming that the >+ * needed files are located in the local history. Checkpoints are managed by the >+ * CheckpointStore class. >+ */ >+public class Checkpoint { >+ // user-readable label for this checkpoint >+ protected String fLabel = null; >+ >+ // system-meaningful timestamp of this checkpoint >+ protected long fLastModified = 0; >+ >+ /** >+ * Construct a checkpoint with the given label. The timestamp is set at the >+ * current value of system time. >+ * >+ * @param label >+ */ >+ public Checkpoint(String label) { >+ this(label, System.currentTimeMillis()); >+ } >+ >+ /** >+ * Construct a checkpoint with given label and timestamp. >+ * * >+ * @param label >+ * @param timestamp >+ */ >+ public Checkpoint(String label, long lastmodified) { >+ fLabel = label; >+ fLastModified = lastmodified; >+ } >+ >+ /** >+ * Create a checkpoint from an array of UTF8-encoded bytes. Expected >+ * format is <code>(lastmodified-value)(space)(label-value)</code> >+ * @param bytes >+ */ >+ static public Checkpoint createCheckpoint(byte[] bytes) { >+ String s = Convert.fromUTF8(bytes); >+ return createCheckpoint(s); >+ } >+ >+ /** >+ * Create a checkpoint from a string. Expected format >+ * is <code>(lastmodified-value)(space)(label-value)</code> >+ * @param string >+ */ >+ static public Checkpoint createCheckpoint(String string) { >+ // parse string into fields >+ String[] tokens = string.split(" ",2); //$NON-NLS-1$ >+ if (tokens.length != 2) { >+ return null; >+ } >+ String label = tokens[1]; >+ String lastModString = tokens[0]; >+ return new Checkpoint(label,Long.parseLong(lastModString)); >+ } >+ >+ /** >+ * Return (printable) string representation of Checkpoint. >+ */ >+ public String toString() { >+ StringBuffer s = new StringBuffer(); >+ s.append("("+Long.toString(fLastModified)+" "); //$NON-NLS-1$ //$NON-NLS-2$ >+ s.append(fLabel+")"); //$NON-NLS-1$ >+ return s.toString(); >+ } >+ >+ /** >+ * Return the UTF8-encoded bytes that represent this checkpoint. >+ */ >+ public byte[] getBytes() { >+ // convert fields to bytes >+ byte[] lastModifiedBytes = Convert.toUTF8(Long.toString(fLastModified)); >+ byte[] labelBytes = Convert.toUTF8(" "+fLabel); //$NON-NLS-1$ >+ byte[] reply = new byte[lastModifiedBytes.length+labelBytes.length]; >+ // Copy values into reply >+ System.arraycopy(lastModifiedBytes, 0, reply, 0, lastModifiedBytes.length); >+ System.arraycopy(labelBytes, 0, reply, lastModifiedBytes.length, labelBytes.length); >+ return reply; >+ } >+ /** >+ * @return Returns the Label. >+ */ >+ public String getLabel() { >+ return fLabel; >+ } >+ /** >+ * @param label The Label to set. >+ */ >+ public void setLabel(String label) { >+ fLabel = label; >+ } >+ /** >+ * @return Returns the LastModified. >+ */ >+ public long getLastModified() { >+ return fLastModified; >+ } >+ /** >+ * @param lastModified The LastModified to set. >+ */ >+ public void setLastModified(long lastModified) { >+ fLastModified = lastModified; >+ } >+ >+ /* >+ * Make a shallow copy of this object >+ * @return new shallow copy of this checkpoint >+ */ >+ public Object clone() { >+ return new Checkpoint(fLabel, fLastModified); >+ } >+} >Index: src/org/eclipse/core/resources/CheckpointBridge.java >=================================================================== >RCS file: src/org/eclipse/core/resources/CheckpointBridge.java >diff -N src/org/eclipse/core/resources/CheckpointBridge.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/core/resources/CheckpointBridge.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,90 @@ >+/******************************************************************************* >+ * Copyright (c) 2004 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Common Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/cpl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.core.resources; >+ >+import java.util.List; >+import java.util.Set; >+ >+import org.eclipse.core.internal.localstore.FileSystemResourceManager; >+import org.eclipse.core.internal.localstore.HistoryStore; >+import org.eclipse.core.internal.resources.Workspace; >+ >+/** >+ * CheckpointBridge exposes the minimum needed >+*/ >+public class CheckpointBridge { >+ /** >+ * Add a checkpoint to the local history manager. >+ * <p> >+ * The label is user definable. The lastModified timestamp is usually >+ * going to be the current time, which you can obtain with a call to >+ * System.currentTimeMillis(). A simple default for the label is the string >+ * representation of the current date and time. >+ * >+ * @param checkpoint new <code>Checkpoint</code> to add to local history >+ */ >+ static public void addCheckpoint(Checkpoint checkpoint) { >+ HistoryStore historyStore = getHistoryStore(); >+ historyStore.addCheckpoint(checkpoint); >+ } >+ /** >+ * Get the list of valid checkpoints >+ * @return a List of <code>Checkpoint</code> objects. >+ */ >+ static public List getCheckpoints() { >+ HistoryStore historyStore = getHistoryStore(); >+ return historyStore.getCheckpoints(); >+ } >+ >+ /** >+ * Return the <code>IFileState</code>(s) needed to restore (as best as >+ * possible) the workspace to its state of the <code>lastModified</code> >+ * time. Two sets are returned. The first holds the set of resources that >+ * should be restored from the local history. The second holds the set of >+ * resources that should be deleted from the workspace. >+ * >+ * @param lastModified time of the checkpoint to rollback to. >+ * @return an array of <code>Set</code>(s) of size two. Each >+ * element type of each Set is an IFileState. Set[0] holds >+ * the "restore" set and Set[1] holds the "delete" set. >+ */ >+ public static Set[] getRestoreAndDeleteFallbackStates(long lastModified) { >+ HistoryStore historyStore = getHistoryStore(); >+ Set[] stateSets = historyStore.getRestoreAndDeleteFallbackStates(lastModified); >+ /* begin debugging >+ Set restoreStates = stateSets[0]; // IFileState >+ Set deleteStates = stateSets[1]; // IFile >+ >+ Iterator states = restoreStates.iterator(); >+ while (states.hasNext()) { >+ IFileState state = (IFileState) states.next(); >+ Date date = new Date(state.getModificationTime()); >+ System.out.println("restore: " + date.toString() + "\t" + state.getFullPath()); >+ } >+ states = deleteStates.iterator(); >+ while (states.hasNext()) { >+ IFile state = (IFile) states.next(); >+ Date date = new Date(state.getLocalTimeStamp()); >+ System.out.println("delete: " + date.toString() + "\t" + state.getFullPath()); >+ } >+ end debugging */ >+ return stateSets; >+ } >+ >+ /* >+ * Get the current HistoryStore from the workspace. >+ */ >+ static private HistoryStore getHistoryStore() { >+ Workspace workspace = (Workspace) ResourcesPlugin.getWorkspace(); >+ FileSystemResourceManager fmgr = workspace.getFileSystemManager(); >+ return (fmgr == null) ? null : fmgr.getHistoryStore(); >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 36958
:
8368
| 8369