Browse Source

Allow overriding DfsPackDescription comparator for scanning packs

Provide a factory for comparators that use the default heuristics except
with a different ordering of PackSources.

Change-Id: I0809b64deb3d0486040076946fdbdad650d69240
stable-5.1
Dave Borowitz 7 years ago
parent
commit
5c02ce52d6
  1. 20
      org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackDescriptionTest.java
  2. 20
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
  3. 23
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java

20
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackDescriptionTest.java

@ -46,8 +46,10 @@ package org.eclipse.jgit.internal.storage.dfs;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT; 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;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST; 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.INSERT;
import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.RECEIVE; 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.INDEX;
import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -101,6 +103,24 @@ public final class DfsPackDescriptionTest {
assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b); 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 @Test
public void objectLookupComparatorGcFileSize() throws Exception { public void objectLookupComparatorGcFileSize() throws Exception {
// a is older and smaller. // a is older and smaller.

20
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java

@ -240,6 +240,8 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
private DfsReaderOptions readerOptions; private DfsReaderOptions readerOptions;
private Comparator<DfsPackDescription> packComparator;
/** /**
* Initialize an object database for our repository. * Initialize an object database for our repository.
* *
@ -253,6 +255,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
this.repository = repository; this.repository = repository;
this.packList = new AtomicReference<>(NO_PACKS); this.packList = new AtomicReference<>(NO_PACKS);
this.readerOptions = options; this.readerOptions = options;
this.packComparator = DfsPackDescription.objectLookupComparator();
} }
/** /**
@ -264,6 +267,21 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
return readerOptions; 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} */ /** {@inheritDoc} */
@Override @Override
public DfsReader newReader() { public DfsReader newReader() {
@ -607,7 +625,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase {
Map<DfsPackDescription, DfsReftable> reftables = reftableMap(old); Map<DfsPackDescription, DfsReftable> reftables = reftableMap(old);
List<DfsPackDescription> scanned = listPacks(); List<DfsPackDescription> scanned = listPacks();
Collections.sort(scanned, DfsPackDescription.objectLookupComparator()); Collections.sort(scanned, packComparator);
List<DfsPackFile> newPacks = new ArrayList<>(scanned.size()); List<DfsPackFile> newPacks = new ArrayList<>(scanned.size());
List<DfsReftable> newReftables = new ArrayList<>(scanned.size()); List<DfsReftable> newReftables = new ArrayList<>(scanned.size());

23
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java

@ -72,13 +72,32 @@ public class DfsPackDescription {
* with more recent modification dates before older packs, and packs with * with more recent modification dates before older packs, and packs with
* fewer objects before packs with more objects. * fewer objects before packs with more objects.
* <p> * <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. * @return comparator.
*/ */
public static Comparator<DfsPackDescription> objectLookupComparator() { 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( return Comparator.comparing(
DfsPackDescription::getPackSource, PackSource.DEFAULT_COMPARATOR) DfsPackDescription::getPackSource, packSourceComparator)
.thenComparing((a, b) -> { .thenComparing((a, b) -> {
PackSource as = a.getPackSource(); PackSource as = a.getPackSource();
PackSource bs = b.getPackSource(); PackSource bs = b.getPackSource();

Loading…
Cancel
Save