Browse Source

Include supported extensions in PackFile constructor.

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
stable-3.0
Colby Ranger 12 years ago
parent
commit
4a317a1790
  1. 4
      org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/T0004_PackReaderTest.java
  2. 35
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
  3. 11
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
  4. 57
      org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackExt.java

4
org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/T0004_PackReaderTest.java

@ -46,6 +46,8 @@
package org.eclipse.jgit.storage.file; 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.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -70,7 +72,7 @@ public class T0004_PackReaderTest extends SampleDataRepositoryTestCase {
final ObjectLoader or; final ObjectLoader or;
id = ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327"); 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); or = pr.get(new WindowCursor(null), id);
assertNotNull(or); assertNotNull(or);
assertEquals(Constants.OBJ_TREE, or.getType()); assertEquals(Constants.OBJ_TREE, or.getType());

35
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java

@ -43,6 +43,9 @@
package org.eclipse.jgit.storage.file; 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.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; 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.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.storage.pack.CachedPack; import org.eclipse.jgit.storage.pack.CachedPack;
import org.eclipse.jgit.storage.pack.ObjectToPack; 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.storage.pack.PackWriter;
import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.FileUtils;
@ -335,10 +339,23 @@ public class ObjectDirectory extends FileObjectDatabase {
public PackFile openPack(final File pack) public PackFile openPack(final File pack)
throws IOException { throws IOException {
final String p = pack.getName(); 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)); 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); insertPack(res);
return res; return res;
} }
@ -720,9 +737,14 @@ public class ObjectDirectory extends FileObjectDatabase {
if (indexName.length() != 49 || !indexName.endsWith(".idx")) //$NON-NLS-1$ if (indexName.length() != 49 || !indexName.endsWith(".idx")) //$NON-NLS-1$
continue; continue;
final String base = indexName.substring(0, indexName.length() - 4); final String base = indexName.substring(0, indexName.length() - 3);
final String packName = base + ".pack"; //$NON-NLS-1$ int extensions = 0;
if (!names.contains(packName)) { 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 // Sometimes C Git's HTTP fetch transport leaves a
// .idx file behind and does not download the .pack. // .idx file behind and does not download the .pack.
// We have to skip over such useless indexes. // We have to skip over such useless indexes.
@ -730,6 +752,7 @@ public class ObjectDirectory extends FileObjectDatabase {
continue; continue;
} }
final String packName = base + PACK.getExtension();
final PackFile oldPack = forReuse.remove(packName); final PackFile oldPack = forReuse.remove(packName);
if (oldPack != null) { if (oldPack != null) {
list.add(oldPack); list.add(oldPack);
@ -737,7 +760,7 @@ public class ObjectDirectory extends FileObjectDatabase {
} }
final File packFile = new File(packDirectory, packName); final File packFile = new File(packDirectory, packName);
list.add(new PackFile(packFile)); list.add(new PackFile(packFile, extensions));
foundNew = true; foundNew = true;
} }

11
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java

@ -97,6 +97,8 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
private final File packFile; private final File packFile;
private final int extensions;
private File keepFile; private File keepFile;
private volatile String packName; private volatile String packName;
@ -138,10 +140,13 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
* *
* @param packFile * @param packFile
* path of the <code>.pack</code> file holding the data. * 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.packFile = packFile;
this.packLastModified = (int) (packFile.lastModified() >> 10); this.packLastModified = (int) (packFile.lastModified() >> 10);
this.extensions = extensions;
// Multiply by 31 here so we can more directly combine with another // Multiply by 31 here so we can more directly combine with another
// value in WindowCache.hash(), without doing the multiply there. // 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); String b = (dot < 0) ? p : p.substring(0, dot);
return new File(packFile.getParentFile(), b + '.' + ext.getExtension()); return new File(packFile.getParentFile(), b + '.' + ext.getExtension());
} }
private boolean hasExt(PackExt ext) {
return (extensions & ext.getBit()) != 0;
}
} }

57
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackExt.java

@ -45,21 +45,52 @@ package org.eclipse.jgit.storage.pack;
/** A pack file extension. */ /** A pack file extension. */
public class PackExt { public class PackExt {
private static volatile PackExt[] VALUES = new PackExt[] {};
/** A pack file extension. */ /** 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. */ /** 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 * @param ext
* the file extension. * 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.ext = ext;
this.pos = pos;
} }
/** @return the file extension. */ /** @return the file extension. */
@ -67,21 +98,19 @@ public class PackExt {
return ext; return ext;
} }
@Override /** @return the position of the extension in the values array. */
public boolean equals(Object obj) { public int getPosition() {
if (obj instanceof PackExt) { return pos;
return ((PackExt) obj).getExtension().equals(getExtension());
}
return false;
} }
@Override /** @return the bit mask of the extension e.g {@code 1 << getPosition()}. */
public int hashCode() { public int getBit() {
return getExtension().hashCode(); return 1 << getPosition();
} }
@Override @Override
public String toString() { 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()));
} }
} }

Loading…
Cancel
Save