]> source.dussan.org Git - jgit.git/commitdiff
Include supported extensions in PackFile constructor. 80/9980/7
authorColby Ranger <cranger@google.com>
Mon, 28 Jan 2013 19:49:01 +0000 (11:49 -0800)
committerColby Ranger <cranger@google.com>
Thu, 28 Feb 2013 19:35:07 +0000 (11:35 -0800)
Previously a PackFile class was assumed to only support a .pack and .idx
file. Update the constructor to enumerate the supported extensions for
the pack file. This will allow the bitmap code to only be executed if
the bitmap extension file is known to exist.

Change-Id: Ie59041dffec5f60d7ea2771026ffd945106bd4bf

org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/T0004_PackReaderTest.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackExt.java

index 67861f6779d1612b6382ce368ac9c00343ccddd5..d14cc212af3071cd117892173a30ada0ca0ff85b 100644 (file)
@@ -46,6 +46,8 @@
 
 package org.eclipse.jgit.storage.file;
 
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
@@ -70,7 +72,7 @@ public class T0004_PackReaderTest extends SampleDataRepositoryTestCase {
                final ObjectLoader or;
 
                id = ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327");
-               pr = new PackFile(TEST_PACK);
+               pr = new PackFile(TEST_PACK, PACK.getBit() | INDEX.getBit());
                or = pr.get(new WindowCursor(null), id);
                assertNotNull(or);
                assertEquals(Constants.OBJ_TREE, or.getType());
index 22ef45df6be4a1e4bdacd9667b982c6dccfd408c..7574f2aa882e8e6c3a2afb716b24ce1492e4cc18 100644 (file)
@@ -43,6 +43,9 @@
 
 package org.eclipse.jgit.storage.file;
 
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -74,6 +77,7 @@ import org.eclipse.jgit.lib.RepositoryCache;
 import org.eclipse.jgit.lib.RepositoryCache.FileKey;
 import org.eclipse.jgit.storage.pack.CachedPack;
 import org.eclipse.jgit.storage.pack.ObjectToPack;
+import org.eclipse.jgit.storage.pack.PackExt;
 import org.eclipse.jgit.storage.pack.PackWriter;
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.FileUtils;
@@ -335,10 +339,23 @@ public class ObjectDirectory extends FileObjectDatabase {
        public PackFile openPack(final File pack)
                        throws IOException {
                final String p = pack.getName();
-               if (p.length() != 50 || !p.startsWith("pack-") || !p.endsWith(".pack")) //$NON-NLS-1$
+               if (p.length() != 50 || !p.startsWith("pack-") || !p.endsWith(".pack")) //$NON-NLS-1$ //$NON-NLS-2$
                        throw new IOException(MessageFormat.format(JGitText.get().notAValidPack, pack));
 
-               PackFile res = new PackFile(pack);
+               // The pack and index are assumed to exist. The existence of other
+               // extensions needs to be explicitly checked.
+               //
+               int extensions = PACK.getBit() | INDEX.getBit();
+               final String base = p.substring(0, p.length() - 4);
+               for (PackExt ext : PackExt.values()) {
+                       if ((extensions & ext.getBit()) == 0) {
+                               final String name = base + ext.getExtension();
+                               if (new File(pack.getParentFile(), name).exists())
+                                       extensions |= ext.getBit();
+                       }
+               }
+
+               PackFile res = new PackFile(pack, extensions);
                insertPack(res);
                return res;
        }
@@ -720,9 +737,14 @@ public class ObjectDirectory extends FileObjectDatabase {
                        if (indexName.length() != 49 || !indexName.endsWith(".idx")) //$NON-NLS-1$
                                continue;
 
-                       final String base = indexName.substring(0, indexName.length() - 4);
-                       final String packName = base + ".pack"; //$NON-NLS-1$
-                       if (!names.contains(packName)) {
+                       final String base = indexName.substring(0, indexName.length() - 3);
+                       int extensions = 0;
+                       for (PackExt ext : PackExt.values()) {
+                               if (names.contains(base + ext.getExtension()))
+                                       extensions |= ext.getBit();
+                       }
+
+                       if ((extensions & PACK.getBit()) == 0) {
                                // Sometimes C Git's HTTP fetch transport leaves a
                                // .idx file behind and does not download the .pack.
                                // We have to skip over such useless indexes.
@@ -730,6 +752,7 @@ public class ObjectDirectory extends FileObjectDatabase {
                                continue;
                        }
 
+                       final String packName = base + PACK.getExtension();
                        final PackFile oldPack = forReuse.remove(packName);
                        if (oldPack != null) {
                                list.add(oldPack);
@@ -737,7 +760,7 @@ public class ObjectDirectory extends FileObjectDatabase {
                        }
 
                        final File packFile = new File(packDirectory, packName);
-                       list.add(new PackFile(packFile));
+                       list.add(new PackFile(packFile, extensions));
                        foundNew = true;
                }
 
index 666df58bec0d6466b1240e47bd0ae30af8d61e22..6c24a3fef1c941f0b490b71d307370e3a1c0182a 100644 (file)
@@ -97,6 +97,8 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
 
        private final File packFile;
 
+       private final int extensions;
+
        private File keepFile;
 
        private volatile String packName;
@@ -138,10 +140,13 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
         *
         * @param packFile
         *            path of the <code>.pack</code> file holding the data.
+        * @param extensions
+        *            additional pack file extensions with the same base as the pack
         */
-       public PackFile(final File packFile) {
+       public PackFile(final File packFile, int extensions) {
                this.packFile = packFile;
                this.packLastModified = (int) (packFile.lastModified() >> 10);
+               this.extensions = extensions;
 
                // Multiply by 31 here so we can more directly combine with another
                // value in WindowCache.hash(), without doing the multiply there.
@@ -1085,4 +1090,8 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
                String b = (dot < 0) ? p : p.substring(0, dot);
                return new File(packFile.getParentFile(), b + '.' + ext.getExtension());
        }
+
+       private boolean hasExt(PackExt ext) {
+               return (extensions & ext.getBit()) != 0;
+       }
 }
index cb33308c614b77b5940e5f5aa1edb4e9ba8f561e..61a6609300d5618f139be212b3e874129f9745a8 100644 (file)
@@ -45,21 +45,52 @@ package org.eclipse.jgit.storage.pack;
 
 /** A pack file extension. */
 public class PackExt {
+       private static volatile PackExt[] VALUES = new PackExt[] {};
 
        /** A pack file extension. */
-       public static final PackExt PACK = new PackExt("pack"); //$NON-NLS-1$
+       public static final PackExt PACK = newPackExt("pack"); //$NON-NLS-1$
 
        /** A pack index file extension. */
-       public static final PackExt INDEX = new PackExt("idx"); //$NON-NLS-1$
+       public static final PackExt INDEX = newPackExt("idx"); //$NON-NLS-1$
 
-       private final String ext;
+       /** @return all of the PackExt values. */
+       public static PackExt[] values() {
+               return VALUES;
+       }
 
        /**
+        * Returns a PackExt for the file extension and registers it in the values
+        * array.
+        *
         * @param ext
         *            the file extension.
+        * @return the PackExt for the ext
         */
-       public PackExt(String ext) {
+       public synchronized static PackExt newPackExt(String ext) {
+               PackExt[] dst = new PackExt[VALUES.length + 1];
+               for (int i = 0; i < VALUES.length; i++) {
+                       PackExt packExt = VALUES[i];
+                       if (packExt.getExtension().equals(ext))
+                               return packExt;
+                       dst[i] = packExt;
+               }
+               if (VALUES.length >= 32)
+                       throw new IllegalStateException(
+                                       "maximum number of pack extensions exceeded"); //$NON-NLS-1$
+
+               PackExt value = new PackExt(ext, VALUES.length);
+               dst[VALUES.length] = value;
+               VALUES = dst;
+               return value;
+       }
+
+       private final String ext;
+
+       private final int pos;
+
+       private PackExt(String ext, int pos) {
                this.ext = ext;
+               this.pos = pos;
        }
 
        /** @return the file extension. */
@@ -67,21 +98,19 @@ public class PackExt {
                return ext;
        }
 
-       @Override
-       public boolean equals(Object obj) {
-               if (obj instanceof PackExt) {
-                       return ((PackExt) obj).getExtension().equals(getExtension());
-               }
-               return false;
+       /** @return the position of the extension in the values array. */
+       public int getPosition() {
+               return pos;
        }
 
-       @Override
-       public int hashCode() {
-               return getExtension().hashCode();
+       /** @return the bit mask of the extension e.g {@code 1 << getPosition()}. */
+       public int getBit() {
+               return 1 << getPosition();
        }
 
        @Override
        public String toString() {
-               return String.format("PackExt[%s]", getExtension()); //$NON-NLS-1$
+               return String.format("PackExt[%s, bit=0x%s]", getExtension(), //$NON-NLS-1$
+                               Integer.toHexString(getBit()));
        }
 }