diff options
author | Chris Aniszczyk <caniszczyk@gmail.com> | 2011-05-25 09:46:49 -0400 |
---|---|---|
committer | Code Review <codereview-daemon@eclipse.org> | 2011-05-25 09:46:49 -0400 |
commit | aa05559fd6a9099f90c8beeb80364e440e2614a2 (patch) | |
tree | 2958b0f2b78a2821951e9c5e74d508c2555d0de4 /org.eclipse.jgit | |
parent | 05fa1713da0ecc36829f321d798c2b08bf7936ff (diff) | |
parent | 2302a6d3ceea2926e785dba57abd58f609684e86 (diff) | |
download | jgit-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.java | 16 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/storage/file/RefDirectory.java | 63 |
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) { |