diff options
author | Chris Aniszczyk <caniszczyk@gmail.com> | 2010-12-20 12:06:00 -0500 |
---|---|---|
committer | Code Review <codereview-daemon@eclipse.org> | 2010-12-20 12:06:00 -0500 |
commit | 8f419dc5e650047565cca34afc7524bcee3d32eb (patch) | |
tree | d731beaa87c2b30f28df46fe0d0aa3c01e3214dd | |
parent | f91ee9afcc56d93829e6e57efb6f9db5c9fa70be (diff) | |
parent | 3922e026e006ad738bf66b8b3b1afc59f9b004ae (diff) | |
download | jgit-8f419dc5e650047565cca34afc7524bcee3d32eb.tar.gz jgit-8f419dc5e650047565cca34afc7524bcee3d32eb.zip |
Merge "FileBasedConfig: Use FileSnapshot for isOutdated()"
3 files changed, 61 insertions, 12 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java index da1f3af603..212646b11d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java @@ -58,6 +58,7 @@ import org.eclipse.jgit.JGitText; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.IO; @@ -68,8 +69,9 @@ import org.eclipse.jgit.util.RawParseUtils; */ public class FileBasedConfig extends StoredConfig { private final File configFile; - private volatile long lastModified; private final FS fs; + private volatile FileSnapshot snapshot; + private volatile ObjectId hash; /** * Create a configuration with no default fallback. @@ -99,6 +101,8 @@ public class FileBasedConfig extends StoredConfig { super(base); configFile = cfgLocation; this.fs = fs; + this.snapshot = FileSnapshot.DIRTY; + this.hash = ObjectId.zeroId(); } @Override @@ -125,11 +129,24 @@ public class FileBasedConfig extends StoredConfig { */ @Override public void load() throws IOException, ConfigInvalidException { - lastModified = getFile().lastModified(); + final FileSnapshot oldSnapshot = snapshot; + final FileSnapshot newSnapshot = FileSnapshot.save(getFile()); try { - fromText(RawParseUtils.decode(IO.readFully(getFile()))); + final byte[] in = IO.readFully(getFile()); + final ObjectId newHash = hash(in); + if (hash.equals(newHash)) { + if (oldSnapshot.equals(newSnapshot)) + oldSnapshot.setClean(newSnapshot); + else + snapshot = newSnapshot; + } else { + fromText(RawParseUtils.decode(in)); + snapshot = newSnapshot; + hash = newHash; + } } catch (FileNotFoundException noFile) { clear(); + snapshot = newSnapshot; } catch (IOException e) { final IOException e2 = new IOException(MessageFormat.format(JGitText.get().cannotReadFile, getFile())); e2.initCause(e); @@ -157,19 +174,30 @@ public class FileBasedConfig extends StoredConfig { if (!lf.lock()) throw new IOException(MessageFormat.format(JGitText.get().cannotLockFile, getFile())); try { - lf.setNeedStatInformation(true); + lf.setNeedSnapshot(true); lf.write(out); if (!lf.commit()) throw new IOException(MessageFormat.format(JGitText.get().cannotCommitWriteTo, getFile())); } finally { lf.unlock(); } - lastModified = lf.getCommitLastModified(); + snapshot = lf.getCommitSnapshot(); + hash = hash(out); // notify the listeners fireConfigChangedEvent(); } @Override + public void clear() { + hash = hash(new byte[0]); + super.clear(); + } + + private static ObjectId hash(final byte[] rawText) { + return ObjectId.fromRaw(Constants.newMessageDigest().digest(rawText)); + } + + @Override public String toString() { return getClass().getSimpleName() + "[" + getFile().getPath() + "]"; } @@ -179,6 +207,6 @@ public class FileBasedConfig extends StoredConfig { * than the file on disk */ public boolean isOutdated() { - return getFile().lastModified() != lastModified; + return snapshot.isModified(getFile()); } } 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 c1ce449dce..87ae57b824 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 @@ -104,6 +104,10 @@ public class FileSnapshot { this.cannotBeRacilyClean = notRacyClean(read); } + long lastModified() { + return lastModified; + } + /** * Check if the path has been modified since the snapshot was saved. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LockFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LockFile.java index c1fb704a51..52aa7eeb9d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LockFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LockFile.java @@ -89,11 +89,11 @@ public class LockFile { private FileOutputStream os; - private boolean needStatInformation; + private boolean needSnapshot; private boolean fsync; - private long commitLastModified; + private FileSnapshot commitSnapshot; private final FS fs; @@ -334,12 +334,24 @@ public class LockFile { /** * Request that {@link #commit()} remember modification time. + * <p> + * This is an alias for {@code setNeedSnapshot(true)}. * * @param on * true if the commit method must remember the modification time. */ public void setNeedStatInformation(final boolean on) { - needStatInformation = on; + setNeedSnapshot(on); + } + + /** + * Request that {@link #commit()} remember the {@link FileSnapshot}. + * + * @param on + * true if the commit method must remember the FileSnapshot. + */ + public void setNeedSnapshot(final boolean on) { + needSnapshot = on; } /** @@ -442,8 +454,8 @@ public class LockFile { } private void saveStatInformation() { - if (needStatInformation) - commitLastModified = lck.lastModified(); + if (needSnapshot) + commitSnapshot = FileSnapshot.save(lck); } /** @@ -452,7 +464,12 @@ public class LockFile { * @return modification time of the lock file right before we committed it. */ public long getCommitLastModified() { - return commitLastModified; + return commitSnapshot.lastModified(); + } + + /** @return get the {@link FileSnapshot} just before commit. */ + public FileSnapshot getCommitSnapshot() { + return commitSnapshot; } /** |