import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST;
+import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_TXN;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.RECEIVE;
+import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE;
import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
import static org.junit.Assert.assertEquals;
assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b);
}
+ @Test
+ public void objectLookupComparatorCustomPackSourceComparator()
+ throws Exception {
+ DfsPackDescription a = create(GC);
+
+ DfsPackDescription b = create(COMPACT);
+
+ assertComparesLessThan(DfsPackDescription.objectLookupComparator(), b, a);
+ assertComparesLessThan(
+ DfsPackDescription.objectLookupComparator(
+ new PackSource.ComparatorBuilder()
+ .add(GC)
+ .add(INSERT, RECEIVE, GC_REST, GC_TXN, UNREACHABLE_GARBAGE)
+ .add(COMPACT)
+ .build()),
+ a, b);
+ }
+
@Test
public void objectLookupComparatorGcFileSize() throws Exception {
// a is older and smaller.
private DfsReaderOptions readerOptions;
+ private Comparator<DfsPackDescription> packComparator;
+
/**
* Initialize an object database for our repository.
*
this.repository = repository;
this.packList = new AtomicReference<>(NO_PACKS);
this.readerOptions = options;
+ this.packComparator = DfsPackDescription.objectLookupComparator();
}
/**
return readerOptions;
}
+ /**
+ * Set the comparator used when searching for objects across packs.
+ * <p>
+ * An optimal comparator will find more objects without having to load large
+ * idx files from storage only to find that they don't contain the object.
+ * See {@link DfsPackDescription#objectLookupComparator()} for the default
+ * heuristics.
+ *
+ * @param packComparator
+ * comparator.
+ */
+ public void setPackComparator(Comparator<DfsPackDescription> packComparator) {
+ this.packComparator = packComparator;
+ }
+
/** {@inheritDoc} */
@Override
public DfsReader newReader() {
Map<DfsPackDescription, DfsReftable> reftables = reftableMap(old);
List<DfsPackDescription> scanned = listPacks();
- Collections.sort(scanned, DfsPackDescription.objectLookupComparator());
+ Collections.sort(scanned, packComparator);
List<DfsPackFile> newPacks = new ArrayList<>(scanned.size());
List<DfsReftable> newReftables = new ArrayList<>(scanned.size());
* with more recent modification dates before older packs, and packs with
* fewer objects before packs with more objects.
* <p>
- * Uses {@link PackSource#DEFAULT_COMPARATOR} for sorting sources.
+ * Uses {@link PackSource#DEFAULT_COMPARATOR} for the portion of comparison
+ * where packs are sorted by source.
*
* @return comparator.
*/
public static Comparator<DfsPackDescription> objectLookupComparator() {
+ return objectLookupComparator(PackSource.DEFAULT_COMPARATOR);
+ }
+
+ /**
+ * Comparator for packs when looking up objects in indexes.
+ * <p>
+ * This comparator tries to position packs in the order readers should examine
+ * them when looking for objects by SHA-1. The default tries to sort packs
+ * with more recent modification dates before older packs, and packs with
+ * fewer objects before packs with more objects.
+ *
+ * @param packSourceComparator
+ * comparator for the {@link PackSource}, used as the first step in
+ * comparison.
+ * @return comparator.
+ */
+ public static Comparator<DfsPackDescription> objectLookupComparator(
+ Comparator<PackSource> packSourceComparator) {
return Comparator.comparing(
- DfsPackDescription::getPackSource, PackSource.DEFAULT_COMPARATOR)
+ DfsPackDescription::getPackSource, packSourceComparator)
.thenComparing((a, b) -> {
PackSource as = a.getPackSource();
PackSource bs = b.getPackSource();