]> source.dussan.org Git - jgit.git/commitdiff
RefDirectory: Use FileSnapshot for packed-refs 18/2118/4
authorShawn O. Pearce <spearce@spearce.org>
Mon, 13 Dec 2010 21:41:19 +0000 (13:41 -0800)
committerChris Aniszczyk <caniszczyk@gmail.com>
Fri, 1 Apr 2011 22:49:09 +0000 (17:49 -0500)
Instead of tracking the length and modification time by hand, rely
on FileSnapshot to tell RefDirectory when the $GIT_DIR/packed-refs
file has been changed or should be re-read from disk.

Change-Id: I067d268dfdca1d39c72dfa536b34e6a239117cc3
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/RefDirectoryTest.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileSnapshot.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LockFile.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/RefDirectory.java

index 2a130223261582cb8d5ba8dc05cb146287a4dbf0..a61580dd1f1f57fd5d96c6cbd683a0680cce17e9 100644 (file)
@@ -1055,6 +1055,10 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase {
        private void writePackedRefs(String content) throws IOException {
                File pr = new File(diskRepo.getDirectory(), "packed-refs");
                write(pr, content);
+
+               final long now = System.currentTimeMillis();
+               final int oneHourAgo = 3600 * 1000;
+               pr.setLastModified(now - oneHourAgo);
        }
 
        private void deleteLooseRef(String name) {
index 0e5b3c00be7f637b5a3292b30c102d89da398b2a..bbec80c86c38acaef158b2bc21a9abc1e05c3902 100644 (file)
@@ -71,6 +71,20 @@ public class FileSnapshot {
         */
        public static final FileSnapshot DIRTY = new FileSnapshot(-1, -1);
 
+       /**
+        * A FileSnapshot that is clean if the file does not exist.
+        * <p>
+        * This instance is useful if the application wants to consider a missing
+        * file to be clean. {@link #isModified(File)} will return false if the file
+        * path does not exist.
+        */
+       public static final FileSnapshot MISSING_FILE = new FileSnapshot(0, 0) {
+               @Override
+               public boolean isModified(File path) {
+                       return path.exists();
+               }
+       };
+
        /**
         * Record a snapshot for a specific file path.
         * <p>
index 9e637ab4f1012f9a32b4009c38d6a2368bdde870..6acd7132ad9ce9fad3038747cb455842d917e462 100644 (file)
@@ -368,9 +368,9 @@ public class LockFile {
        /**
         * Wait until the lock file information differs from the old file.
         * <p>
-        * This method tests both the length and the last modification date. If both
-        * are the same, this method sleeps until it can force the new lock file's
-        * modification date to be later than the target file.
+        * This method tests the last modification date. If both are the same, this
+        * method sleeps until it can force the new lock file's modification date to
+        * be later than the target file.
         *
         * @throws InterruptedException
         *             the thread was interrupted before the last modified date of
@@ -378,14 +378,12 @@ public class LockFile {
         *             the target file.
         */
        public void waitForStatChange() throws InterruptedException {
-               if (ref.length() == lck.length()) {
-                       long otime = ref.lastModified();
-                       long ntime = lck.lastModified();
-                       while (otime == ntime) {
-                               Thread.sleep(25 /* milliseconds */);
-                               lck.setLastModified(System.currentTimeMillis());
-                               ntime = lck.lastModified();
-                       }
+               FileSnapshot o = FileSnapshot.save(ref);
+               FileSnapshot n = FileSnapshot.save(lck);
+               while (o.equals(n)) {
+                       Thread.sleep(25 /* milliseconds */);
+                       lck.setLastModified(System.currentTimeMillis());
+                       n = FileSnapshot.save(lck);
                }
        }
 
index c3402df672fe471625a0bb9cf03456f0fd11bb66..8ac08efb8373cfc5367878bea555f0491bb75ad0 100644 (file)
@@ -548,7 +548,7 @@ public class RefDirectory extends RefDatabase {
                                throw new IOException(MessageFormat.format(
                                        JGitText.get().cannotLockFile, packedRefsFile));
                        try {
-                               PackedRefList cur = readPackedRefs(0, 0);
+                               PackedRefList cur = readPackedRefs();
                                int idx = cur.find(name);
                                if (0 <= idx)
                                        commitPackedRefs(lck, cur.remove(idx), packed);
@@ -690,21 +690,19 @@ public class RefDirectory extends RefDatabase {
        }
 
        private PackedRefList getPackedRefs() throws IOException {
-               long size = packedRefsFile.length();
-               long mtime = size != 0 ? packedRefsFile.lastModified() : 0;
-
                final PackedRefList curList = packedRefs.get();
-               if (size == curList.lastSize && mtime == curList.lastModified)
+               if (!curList.snapshot.isModified(packedRefsFile))
                        return curList;
 
-               final PackedRefList newList = readPackedRefs(size, mtime);
+               final PackedRefList newList = readPackedRefs();
                if (packedRefs.compareAndSet(curList, newList))
                        modCnt.incrementAndGet();
                return newList;
        }
 
-       private PackedRefList readPackedRefs(long size, long mtime)
+       private PackedRefList readPackedRefs()
                        throws IOException {
+               final FileSnapshot snapshot = FileSnapshot.save(packedRefsFile);
                final BufferedReader br;
                try {
                        br = new BufferedReader(new InputStreamReader(new FileInputStream(
@@ -714,7 +712,7 @@ public class RefDirectory extends RefDatabase {
                        return PackedRefList.NO_PACKED_REFS;
                }
                try {
-                       return new PackedRefList(parsePackedRefs(br), size, mtime);
+                       return new PackedRefList(parsePackedRefs(br), snapshot);
                } finally {
                        br.close();
                }
@@ -780,7 +778,7 @@ public class RefDirectory extends RefDatabase {
                        protected void writeFile(String name, byte[] content)
                                        throws IOException {
                                lck.setFSync(true);
-                               lck.setNeedStatInformation(true);
+                               lck.setNeedSnapshot(true);
                                try {
                                        lck.write(content);
                                } catch (IOException ioe) {
@@ -795,8 +793,8 @@ public class RefDirectory extends RefDatabase {
                                if (!lck.commit())
                                        throw new ObjectWritingException(MessageFormat.format(JGitText.get().unableToWrite, name));
 
-                               packedRefs.compareAndSet(oldPackedList, new PackedRefList(refs,
-                                               content.length, lck.getCommitLastModified()));
+                               packedRefs.compareAndSet(oldPackedList, new PackedRefList(
+                                               refs, lck.getCommitSnapshot()));
                        }
                }.writePackedRefs();
        }
@@ -968,19 +966,14 @@ public class RefDirectory extends RefDatabase {
        }
 
        private static class PackedRefList extends RefList<Ref> {
-               static final PackedRefList NO_PACKED_REFS = new PackedRefList(RefList
-                               .emptyList(), 0, 0);
-
-               /** Last length of the packed-refs file when we read it. */
-               final long lastSize;
+               static final PackedRefList NO_PACKED_REFS = new PackedRefList(
+                               RefList.emptyList(), FileSnapshot.MISSING_FILE);
 
-               /** Last modified time of the packed-refs file when we read it. */
-               final long lastModified;
+               final FileSnapshot snapshot;
 
-               PackedRefList(RefList<Ref> src, long size, long mtime) {
+               PackedRefList(RefList<Ref> src, FileSnapshot s) {
                        super(src);
-                       lastSize = size;
-                       lastModified = mtime;
+                       snapshot = s;
                }
        }