Preparing for merging
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/BucketIndex.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/BucketIndex.java
index 083a01f..301a36f 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/BucketIndex.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/BucketIndex.java
@@ -21,18 +21,29 @@
public class BucketIndex {
+ /**
+ * A entry in the bucket index. Each entry has one file path and a collection
+ * of states, which by their turn contain a (UUID, timestamp) pair.
+ */
public static final class Entry {
- public final static int LONG_LENGTH = 8;
- public final static int UUID_LENGTH = UniversalUniqueIdentifier.BYTES_SIZE;
- public final static int DATA_LENGTH = UUID_LENGTH + LONG_LENGTH;
+ // the length of a long in bytes
+ private final static int LONG_LENGTH = 8;
+ // the length of a UUID in bytes
+ private final static int UUID_LENGTH = UniversalUniqueIdentifier.BYTES_SIZE;
+ public final static int DATA_LENGTH = UUID_LENGTH + LONG_LENGTH;
byte[][] data;
IPath path;
+ /**
+ * Returns the byte array representation of a (UUID, timestamp) pair.
+ */
public static byte[] getDataAsByteArray(byte[] uuid, long timestamp) {
byte[] item = new byte[DATA_LENGTH];
System.arraycopy(uuid, 0, item, 0, uuid.length);
- for (int j = 0; j < LONG_LENGTH; j++)
- item[UUID_LENGTH + j] = (byte) (0xFF & (timestamp >>> (j * 8)));
+ for (int j = 0; j < LONG_LENGTH; j++) {
+ item[UUID_LENGTH + j] = (byte) (0xFF & timestamp);
+ timestamp >>>= 8;
+ }
return item;
}
@@ -47,7 +58,7 @@
return new UniversalUniqueIdentifier(item);
}
- Entry(IPath path, byte[][] data) {
+ public Entry(IPath path, byte[][] data) {
this.path = path;
this.data = data;
}
@@ -111,29 +122,46 @@
public boolean isEmpty() {
return data == null || data.length == 0;
}
+
+ public void sortStates() {
+ sortStates(this.data);
+ }
+ public static void sortStates(byte[][] data) {
+ Arrays.sort(data, new Comparator() {
+ // sort in inverse order
+ public int compare(Object o1, Object o2) {
+ byte[] state1 = (byte[]) o1;
+ byte[] state2 = (byte[]) o2;
+ long timestamp1 = getTimestamp(state1);
+ long timestamp2 = getTimestamp(state2);
+ if (timestamp1 == timestamp2)
+ return -UniversalUniqueIdentifier.compareTime(state1, state2);
+ return timestamp1 < timestamp2 ? +1 : -1;
+ }
+ });
+ }
}
public abstract static interface Visitor {
-
- // should stop the traversal
+ // should continue the traversal
public final static int CONTINUE = 0;
// should delete this entry (can be combined with the other constants except for UPDATE)
public final static int DELETE = 0x100;
// should stop looking at states for files in this container (or any of its children)
public final static int RETURN = 2;
- // keep visiting, still happy
+ // should stop the traversal
public final static int STOP = 1;
// should update this entry (can be combined with the other constants except for DELETE)
public final static int UPDATE = 0x200;
/**
- * @return either STOP, CONTINUE or RETURN and optionally DELETE
+ * @return either STOP, CONTINUE or RETURN and optionally DELETE or UPDATE
*/
public int visit(Entry entry);
}
- private static final String BUCKET = ".bucket"; //$NON-NLS-1$
+ private static final String BUCKET = "bucket.index"; //$NON-NLS-1$
public final static byte VERSION = 1;
@@ -175,7 +203,7 @@
* @return one of STOP, RETURN or CONTINUE constants
* @throws CoreException
*/
- public int accept(Visitor visitor, IPath filter, boolean exactMatch, boolean sorted) throws CoreException {
+ public int accept(Visitor visitor, IPath filter, boolean exactMatch) throws CoreException {
if (entries.isEmpty())
return Visitor.CONTINUE;
try {
@@ -187,6 +215,7 @@
continue;
// calls the visitor passing all uuids for the entry
final Entry fileEntry = new Entry(path, (byte[][]) entry.getValue());
+ fileEntry.sortStates();
int outcome = visitor.visit(fileEntry);
if ((outcome & Visitor.UPDATE) != 0) {
needSaving = true;
@@ -228,7 +257,6 @@
byte[][] newValue = new byte[existing.length + 1][];
System.arraycopy(existing, 0, newValue, 0, existing.length);
newValue[newValue.length - 1] = item;
- sortUUIDs(newValue);
entries.put(pathAsString, newValue);
needSaving = true;
}
@@ -279,7 +307,6 @@
byte[][] existing = (byte[][]) entries.get(pathAsString);
if (existing == null)
return new Entry(path, null);
- sortUUIDs(existing);
return new Entry(path, existing);
}
@@ -290,6 +317,7 @@
public void load(File baseLocation) throws CoreException {
load(baseLocation, false);
}
+
public void load(File baseLocation, boolean force) throws CoreException {
try {
// avoid reloading
@@ -362,15 +390,7 @@
}
}
- private void sortUUIDs(byte[][] uuids) {
- Arrays.sort(uuids, new Comparator() {
- public int compare(Object o1, Object o2) {
- return -UniversalUniqueIdentifier.compareTime((byte[]) o1, (byte[]) o2);
- }
- });
- }
-
public int getEntryCount() {
- return entries.size();
+ return entries.size();
}
}
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 8fed670..a11a301 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
@@ -150,18 +150,19 @@
/**
* Factory method for creating history stores.
*/
- private static IHistoryStore createHistoryStore(Workspace workspace, IPath location, int limit) {
- if (Boolean.getBoolean(ENABLE_NEW_HISTORY_STORE)) {
- HistoryStore2 newHistoryStore = new HistoryStore2(workspace, location, limit);
- if (Boolean.getBoolean(CONVERT_HISTORY_STORE)) {
- IStatus conversionOutcome = new HistoryStoreConverter().convertHistory(workspace, location, limit, newHistoryStore, true);
- if (conversionOutcome.getSeverity() != IStatus.OK)
- // if either we fail or succeed, a non-OK status is returned
- ResourcesPlugin.getPlugin().getLog().log(conversionOutcome);
- }
+ private static IHistoryStore createHistoryStore(Workspace workspace, IPath location, int limit) {
+ if (!Boolean.getBoolean(ENABLE_NEW_HISTORY_STORE))
+ // keep using the old history store
+ return new HistoryStore(workspace, location, limit);
+ HistoryStore2 newHistoryStore = new HistoryStore2(workspace, location, limit);
+ if (!Boolean.getBoolean(CONVERT_HISTORY_STORE))
+ // do not try to convert - return as it is
return newHistoryStore;
- }
- return new HistoryStore(workspace, location, limit);
+ IStatus result = new HistoryStoreConverter().convertHistory(workspace, location, limit, newHistoryStore, true);
+ if (result.getSeverity() != IStatus.OK)
+ // if we do anything (either we fail or succeed converting), a non-OK status is returned
+ ResourcesPlugin.getPlugin().getLog().log(result);
+ return newHistoryStore;
}
public void delete(IResource target, boolean force, boolean convertToPhantom, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java
index 15a294b..b44bbeb 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java
@@ -400,7 +400,7 @@
}
return blobStore.getBlob(((FileState) target).getUUID());
}
-
+
/**
* @see IHistoryStore#getStates(IPath, IProgressMonitor)
*/
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore2.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore2.java
index b1eef9f..d1b23e4 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore2.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore2.java
@@ -38,17 +38,13 @@
this.currentBucket = createBucketTable();
}
- public void accept(Visitor visitor, IPath root, int depth) throws CoreException {
- accept(visitor, root, depth, false);
- }
-
/**
* From a starting point in the tree, visit all nodes under it.
* @param visitor
* @param root
* @param depth
*/
- public void accept(Visitor visitor, IPath root, int depth, boolean sorted) throws CoreException {
+ public void accept(Visitor visitor, IPath root, int depth) throws CoreException {
// we only do anything for the root if depth == infinite
if (root.isRoot()) {
if (depth != IResource.DEPTH_INFINITE)
@@ -60,7 +56,7 @@
return;
for (int i = 0; i < projects.length; i++)
if (projects[i].isDirectory())
- if (!internalAccept(visitor, root.append(projects[i].getName()), projects[i], IResource.DEPTH_INFINITE, sorted))
+ if (!internalAccept(visitor, root.append(projects[i].getName()), projects[i], IResource.DEPTH_INFINITE))
break;
// done
return;
@@ -68,10 +64,10 @@
// handles the case the starting point is a file path
if (root.segmentCount() > 1) {
currentBucket.load(locationFor(root.removeLastSegments(1)));
- if (currentBucket.accept(visitor, root, true, sorted) != Visitor.CONTINUE || depth == IResource.DEPTH_ZERO)
+ if (currentBucket.accept(visitor, root, true) != Visitor.CONTINUE || depth == IResource.DEPTH_ZERO)
return;
}
- internalAccept(visitor, root, locationFor(root), depth, sorted);
+ internalAccept(visitor, root, locationFor(root), depth);
}
/**
@@ -135,7 +131,7 @@
}
return changed ? UPDATE : CONTINUE;
}
- }, root, IResource.DEPTH_INFINITE, true);
+ }, root, IResource.DEPTH_INFINITE);
// remove unreferenced blobs
blobStore.deleteBlobs(blobsToRemove);
blobsToRemove = new HashSet();
@@ -266,19 +262,8 @@
states.add(new FileState(HistoryStore2.this, fileEntry.getPath(), fileEntry.getTimestamp(i), fileEntry.getUUID(i)));
return CONTINUE;
}
- }, filePath, IResource.DEPTH_ZERO, true);
- IFileState[] result = (IFileState[]) states.toArray(new IFileState[states.size()]);
- // sort states based on modification time + uuid
- Arrays.sort(result, new Comparator() {
- public int compare(Object o1, Object o2) {
- FileState fs1 = (FileState) o1;
- FileState fs2 = (FileState) o2;
- if (fs1.getModificationTime() == fs1.getModificationTime())
- return -UniversalUniqueIdentifier.compareTime(fs1.getUUID(), fs2.getUUID());
- return (fs1.getModificationTime() < fs2.getModificationTime()) ? 1 : -1;
- }
- });
- return result;
+ }, filePath, IResource.DEPTH_ZERO);
+ return (IFileState[]) states.toArray(new IFileState[states.size()]);
} catch (CoreException ce) {
ResourcesPlugin.getPlugin().getLog().log(ce.getStatus());
return new IFileState[0];
@@ -289,9 +274,9 @@
*
* @return whether to continue visiting other branches
*/
- private boolean internalAccept(Visitor visitor, IPath root, File bucketDir, int depth, boolean sorted) throws CoreException {
+ private boolean internalAccept(Visitor visitor, IPath root, File bucketDir, int depth) throws CoreException {
currentBucket.load(bucketDir);
- int outcome = currentBucket.accept(visitor, root, depth == IResource.DEPTH_ZERO, sorted);
+ int outcome = currentBucket.accept(visitor, root, depth == IResource.DEPTH_ZERO);
if (outcome != Visitor.CONTINUE)
return outcome == Visitor.RETURN;
// nothing else to be done
@@ -302,7 +287,7 @@
return true;
for (int i = 0; i < subDirs.length; i++)
if (subDirs[i].isDirectory())
- if (!internalAccept(visitor, root, subDirs[i], IResource.DEPTH_INFINITE, sorted))
+ if (!internalAccept(visitor, root, subDirs[i], IResource.DEPTH_INFINITE))
return false;
return true;
}
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStoreConverter.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStoreConverter.java
index 4048e3e..56badac 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStoreConverter.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStoreConverter.java
@@ -18,8 +18,6 @@
import org.eclipse.core.runtime.*;
public class HistoryStoreConverter {
- private static final String BACKUP_FILE_EXTENSION = "bak"; //$NON-NLS-1$
-
/**
* Converts an existing history store lying on disk to the new history store.
* Returns Status.OK_STATUS if nothing is done, an IStatus.INFO status if
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java
index 26a02a5..f2b65bd 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java
@@ -53,7 +53,6 @@
public static boolean DEBUG_SAVE_SYNCINFO = false;
public static boolean DEBUG_SAVE_TREE = false;
public static boolean DEBUG_SAVE_METAINFO = false;
- public static boolean DEBUG_SAVE_SNAPSHOTS = false;
public static boolean DEBUG_SAVE_MASTERTABLE = false;
public static boolean DEBUG_AUTO_REFRESH = false;
@@ -85,7 +84,6 @@
DEBUG_SAVE_SYNCINFO = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/syncinfo")); //$NON-NLS-1$
DEBUG_SAVE_TREE = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/tree")); //$NON-NLS-1$
DEBUG_SAVE_METAINFO = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/metainfo")); //$NON-NLS-1$
- DEBUG_SAVE_SNAPSHOTS = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/snapshots")); //$NON-NLS-1$
DEBUG_SAVE_MASTERTABLE = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/mastertable")); //$NON-NLS-1$
DEBUG_SAVE = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save")); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/UniversalUniqueIdentifier.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/UniversalUniqueIdentifier.java
index a484496..7299722 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/UniversalUniqueIdentifier.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/UniversalUniqueIdentifier.java
@@ -100,15 +100,10 @@
@see #BYTES_SIZE
*/
public UniversalUniqueIdentifier(byte[] byteValue) {
- this(byteValue, 0);
- }
-
- public UniversalUniqueIdentifier(byte[] byteValue, int start) {
fBits = new byte[BYTES_SIZE];
- if (byteValue.length - start >= BYTES_SIZE)
- System.arraycopy(byteValue, start, fBits, 0, fBits.length);
+ if (byteValue.length >= BYTES_SIZE)
+ System.arraycopy(byteValue, 0, fBits, 0, BYTES_SIZE);
}
-
/**
Construct an instance whose internal representation is defined by the given string.
@@ -123,7 +118,7 @@
// Check to ensure it is a String of the right length.
// do not use Assert to avoid having to call Policy.bind ahead of time
if (string.length() != PrintStringSize)
- throw new IllegalArgumentException(Policy.bind("utils.wrongLength", string)); //$NON-NLS-1$
+ Assert.isTrue(false, Policy.bind("utils.wrongLength", string)); //$NON-NLS-1$
char[] newChars = string.toCharArray();
@@ -174,6 +169,22 @@
}
/**
+ * Compares the time component of two UUIDs.
+ *
+ * @see Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTime(UniversalUniqueIdentifier other) {
+ return compareTime(this.fBits, other.fBits);
+ }
+
+ public static int compareTime(byte[] fBits1, byte[] fBits2) {
+ for (int i = TIME_FIELD_STOP; i >= 0; i--)
+ if (fBits1[i] != fBits2[i])
+ return (0xFF & fBits1[i]) - (0xFF & fBits2[i]);
+ return 0;
+ }
+
+ /**
* Answers the node address attempting to mask the IP
* address of this machine.
*
@@ -460,64 +471,4 @@
}
return result + "}"; //$NON-NLS-1$
}
-
-// public static void main(String[] args) throws Exception {
-// StringWriter writer = new StringWriter(2000);
-// PrintWriter pw = new PrintWriter(writer);
-// int j = 0;
-// while (true) {
-// j++;
-// UniversalUniqueIdentifier uuid = new UniversalUniqueIdentifier();
-// byte[] bytes = uuid.toBytes();
-// for (int i = 0; i < 6; i++) {
-// pw.print(Integer.toHexString(bytes[i] & 0xFF));
-// pw.print(" ");
-// }
-// pw.print(Integer.toHexString(bytes[7] & HIGH_NIBBLE_MASK));
-// pw.print(" -- ");
-// pw.println(uuid);
-// if (j % 80 == 0) {
-// pw.flush();
-// System.out.println(writer.getBuffer());
-// writer.getBuffer().setLength(0);
-// }
-// }
-// }
-
- public static void main(String[] args) throws Exception {
- int i = 0;
- UniversalUniqueIdentifier last = new UniversalUniqueIdentifier();
- while (true) {
- i++;
- UniversalUniqueIdentifier current = new UniversalUniqueIdentifier();
- if (compareTime(last, current) >= 0) {
- System.out.println("Broke comparison at " + i);
- System.out.println(last);
- System.out.println(current);
- break;
- }
-//
-// if (current.toBytes()[0] == last.toBytes()[0]) {
-// System.out.println("Collision at " + i);
-// System.out.println(last);
-// System.out.println(current);
-// break;
-// }
- last = current;
- }
- }
-
- public static int compareTime(UniversalUniqueIdentifier uuid1, UniversalUniqueIdentifier uuid2) {
- return compareTime(uuid1.fBits, uuid2.fBits);
- }
- public static int compareTime(byte[] fBits1, byte[] fBits2) {
- for (int i = TIME_FIELD_STOP; i >= 0; i--)
- if (fBits1[i] != fBits2[i])
- return (0xFF & fBits1[i]) - (0xFF & fBits2[i]);
- return 0;
- }
- public static int compareTime(String uuid1, String uuid2) {
- // TODO this must be more efficient
- return compareTime(new UniversalUniqueIdentifier(uuid1), new UniversalUniqueIdentifier(uuid2));
- }
}
\ No newline at end of file