summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorChris Aniszczyk <caniszczyk@gmail.com>2011-05-25 09:46:49 -0400
committerCode Review <codereview-daemon@eclipse.org>2011-05-25 09:46:49 -0400
commitaa05559fd6a9099f90c8beeb80364e440e2614a2 (patch)
tree2958b0f2b78a2821951e9c5e74d508c2555d0de4 /org.eclipse.jgit
parent05fa1713da0ecc36829f321d798c2b08bf7936ff (diff)
parent2302a6d3ceea2926e785dba57abd58f609684e86 (diff)
downloadjgit-aa05559fd6a9099f90c8beeb80364e440e2614a2.tar.gz
jgit-aa05559fd6a9099f90c8beeb80364e440e2614a2.zip
Merge "Let RefDirectory use FileSnapShot to handle fast updates"
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileSnapshot.java16
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/storage/file/RefDirectory.java63
2 files changed, 55 insertions, 24 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileSnapshot.java
index bbec80c86c..ce556a7920 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileSnapshot.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileSnapshot.java
@@ -101,6 +101,22 @@ public class FileSnapshot {
return new FileSnapshot(read, modified);
}
+ /**
+ * Record a snapshot for a file for which the last modification time is
+ * already known.
+ * <p>
+ * This method should be invoked before the file is accessed.
+ *
+ * @param modified
+ * the last modification time of the file
+ *
+ * @return the snapshot.
+ */
+ public static FileSnapshot save(long modified) {
+ final long read = System.currentTimeMillis();
+ return new FileSnapshot(read, modified);
+ }
+
/** Last observed modification time of the path. */
private final long lastModified;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/RefDirectory.java
index cd199dcf92..90fd38bdeb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/RefDirectory.java
@@ -842,19 +842,22 @@ public class RefDirectory extends RefDatabase {
return n;
}
+ @SuppressWarnings("null")
private LooseRef scanRef(LooseRef ref, String name) throws IOException {
final File path = fileFor(name);
- final long modified = path.lastModified();
+ FileSnapshot currentSnapshot = null;
if (ref != null) {
- if (ref.getLastModified() == modified)
+ currentSnapshot = ref.getSnapShot();
+ if (!currentSnapshot.isModified(path))
return ref;
name = ref.getName();
- } else if (modified == 0)
+ } else if (!path.exists())
return null;
final int limit = 4096;
final byte[] buf;
+ FileSnapshot otherSnapshot = FileSnapshot.save(path);
try {
buf = IO.readSome(path, limit);
} catch (FileNotFoundException noFile) {
@@ -877,7 +880,12 @@ public class RefDirectory extends RefDatabase {
throw new IOException(MessageFormat.format(JGitText.get().notARef, name, content));
}
final String target = RawParseUtils.decode(buf, 5, n);
- return newSymbolicRef(modified, name, target);
+ if (ref != null && ref.isSymbolic()
+ && ref.getTarget().getName().equals(target)) {
+ currentSnapshot.setClean(otherSnapshot);
+ return ref;
+ }
+ return newSymbolicRef(path.lastModified(), name, target);
}
if (n < OBJECT_ID_STRING_LENGTH)
@@ -886,13 +894,19 @@ public class RefDirectory extends RefDatabase {
final ObjectId id;
try {
id = ObjectId.fromString(buf, 0);
+ if (ref != null && !ref.isSymbolic()
+ && ref.getTarget().getObjectId().equals(id)) {
+ currentSnapshot.setClean(otherSnapshot);
+ return ref;
+ }
+
} catch (IllegalArgumentException notRef) {
while (0 < n && Character.isWhitespace(buf[n - 1]))
n--;
String content = RawParseUtils.decode(buf, 0, n);
throw new IOException(MessageFormat.format(JGitText.get().notARef, name, content));
}
- return new LooseUnpeeled(modified, name, id);
+ return new LooseUnpeeled(path.lastModified(), name, id);
}
private static boolean isSymRef(final byte[] buf, int n) {
@@ -997,22 +1011,22 @@ public class RefDirectory extends RefDatabase {
}
private static interface LooseRef extends Ref {
- long getLastModified();
+ FileSnapshot getSnapShot();
LooseRef peel(ObjectIdRef newLeaf);
}
private final static class LoosePeeledTag extends ObjectIdRef.PeeledTag
implements LooseRef {
- private final long lastModified;
+ private final FileSnapshot snapShot;
LoosePeeledTag(long mtime, String refName, ObjectId id, ObjectId p) {
super(LOOSE, refName, id, p);
- this.lastModified = mtime;
+ snapShot = FileSnapshot.save(mtime);
}
- public long getLastModified() {
- return lastModified;
+ public FileSnapshot getSnapShot() {
+ return snapShot;
}
public LooseRef peel(ObjectIdRef newLeaf) {
@@ -1022,15 +1036,15 @@ public class RefDirectory extends RefDatabase {
private final static class LooseNonTag extends ObjectIdRef.PeeledNonTag
implements LooseRef {
- private final long lastModified;
+ private final FileSnapshot snapShot;
LooseNonTag(long mtime, String refName, ObjectId id) {
super(LOOSE, refName, id);
- this.lastModified = mtime;
+ snapShot = FileSnapshot.save(mtime);
}
- public long getLastModified() {
- return lastModified;
+ public FileSnapshot getSnapShot() {
+ return snapShot;
}
public LooseRef peel(ObjectIdRef newLeaf) {
@@ -1040,37 +1054,38 @@ public class RefDirectory extends RefDatabase {
private final static class LooseUnpeeled extends ObjectIdRef.Unpeeled
implements LooseRef {
- private final long lastModified;
+ private final FileSnapshot snapShot;
LooseUnpeeled(long mtime, String refName, ObjectId id) {
super(LOOSE, refName, id);
- this.lastModified = mtime;
+ snapShot = FileSnapshot.save(mtime);
}
- public long getLastModified() {
- return lastModified;
+ public FileSnapshot getSnapShot() {
+ return snapShot;
}
public LooseRef peel(ObjectIdRef newLeaf) {
if (newLeaf.getPeeledObjectId() != null)
- return new LoosePeeledTag(lastModified, getName(),
+ return new LoosePeeledTag(snapShot.lastModified(), getName(),
getObjectId(), newLeaf.getPeeledObjectId());
else
- return new LooseNonTag(lastModified, getName(), getObjectId());
+ return new LooseNonTag(snapShot.lastModified(), getName(),
+ getObjectId());
}
}
private final static class LooseSymbolicRef extends SymbolicRef implements
LooseRef {
- private final long lastModified;
+ private final FileSnapshot snapShot;
LooseSymbolicRef(long mtime, String refName, Ref target) {
super(refName, target);
- this.lastModified = mtime;
+ snapShot = FileSnapshot.save(mtime);
}
- public long getLastModified() {
- return lastModified;
+ public FileSnapshot getSnapShot() {
+ return snapShot;
}
public LooseRef peel(ObjectIdRef newLeaf) {