diff options
Diffstat (limited to 'org.eclipse.jgit')
11 files changed, 297 insertions, 169 deletions
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index 31c0bcba96..82e088c624 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF @@ -3,12 +3,12 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit Bundle-SymbolicName: org.eclipse.jgit -Bundle-Version: 5.0.0.qualifier +Bundle-Version: 5.1.0.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.jgit.annotations;version="5.0.0", - org.eclipse.jgit.api;version="5.0.0"; +Export-Package: org.eclipse.jgit.annotations;version="5.1.0", + org.eclipse.jgit.api;version="5.1.0"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff, @@ -22,52 +22,52 @@ Export-Package: org.eclipse.jgit.annotations;version="5.0.0", org.eclipse.jgit.submodule, org.eclipse.jgit.transport, org.eclipse.jgit.merge", - org.eclipse.jgit.api.errors;version="5.0.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", - org.eclipse.jgit.attributes;version="5.0.0", - org.eclipse.jgit.blame;version="5.0.0"; + org.eclipse.jgit.api.errors;version="5.1.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", + org.eclipse.jgit.attributes;version="5.1.0", + org.eclipse.jgit.blame;version="5.1.0"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff", - org.eclipse.jgit.diff;version="5.0.0"; + org.eclipse.jgit.diff;version="5.1.0"; uses:="org.eclipse.jgit.patch, org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util", - org.eclipse.jgit.dircache;version="5.0.0"; + org.eclipse.jgit.dircache;version="5.1.0"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.util, org.eclipse.jgit.events, org.eclipse.jgit.attributes", - org.eclipse.jgit.errors;version="5.0.0"; + org.eclipse.jgit.errors;version="5.1.0"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.internal.storage.pack, org.eclipse.jgit.transport, org.eclipse.jgit.dircache", - org.eclipse.jgit.events;version="5.0.0";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.fnmatch;version="5.0.0", - org.eclipse.jgit.gitrepo;version="5.0.0"; + org.eclipse.jgit.events;version="5.1.0";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.fnmatch;version="5.1.0", + org.eclipse.jgit.gitrepo;version="5.1.0"; uses:="org.eclipse.jgit.api, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.xml.sax.helpers, org.xml.sax", - org.eclipse.jgit.gitrepo.internal;version="5.0.0";x-internal:=true, - org.eclipse.jgit.hooks;version="5.0.0";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.ignore;version="5.0.0", - org.eclipse.jgit.ignore.internal;version="5.0.0";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal;version="5.0.0";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.fsck;version="5.0.0";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.ketch;version="5.0.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.dfs;version="5.0.0"; + org.eclipse.jgit.gitrepo.internal;version="5.1.0";x-internal:=true, + org.eclipse.jgit.hooks;version="5.1.0";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.ignore;version="5.1.0", + org.eclipse.jgit.ignore.internal;version="5.1.0";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal;version="5.1.0";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", + org.eclipse.jgit.internal.fsck;version="5.1.0";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal.ketch;version="5.1.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.dfs;version="5.1.0"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.http.server, org.eclipse.jgit.http.test, org.eclipse.jgit.lfs.test", - org.eclipse.jgit.internal.storage.file;version="5.0.0"; + org.eclipse.jgit.internal.storage.file;version="5.1.0"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.junit, org.eclipse.jgit.junit.http, @@ -75,12 +75,12 @@ Export-Package: org.eclipse.jgit.annotations;version="5.0.0", org.eclipse.jgit.lfs, org.eclipse.jgit.pgm, org.eclipse.jgit.pgm.test", - org.eclipse.jgit.internal.storage.io;version="5.0.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.pack;version="5.0.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftable;version="5.0.0"; + org.eclipse.jgit.internal.storage.io;version="5.1.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.pack;version="5.1.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.reftable;version="5.1.0"; x-friends:="org.eclipse.jgit.http.test,org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftree;version="5.0.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.lib;version="5.0.0"; + org.eclipse.jgit.internal.storage.reftree;version="5.1.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.lib;version="5.1.0"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util, @@ -90,33 +90,33 @@ Export-Package: org.eclipse.jgit.annotations;version="5.0.0", org.eclipse.jgit.treewalk, org.eclipse.jgit.transport, org.eclipse.jgit.submodule", - org.eclipse.jgit.lib.internal;version="5.0.0";x-internal:=true, - org.eclipse.jgit.merge;version="5.0.0"; + org.eclipse.jgit.lib.internal;version="5.1.0";x-internal:=true, + org.eclipse.jgit.merge;version="5.1.0"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.diff, org.eclipse.jgit.dircache, org.eclipse.jgit.api", - org.eclipse.jgit.nls;version="5.0.0", - org.eclipse.jgit.notes;version="5.0.0"; + org.eclipse.jgit.nls;version="5.1.0", + org.eclipse.jgit.notes;version="5.1.0"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.merge", - org.eclipse.jgit.patch;version="5.0.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", - org.eclipse.jgit.revplot;version="5.0.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", - org.eclipse.jgit.revwalk;version="5.0.0"; + org.eclipse.jgit.patch;version="5.1.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", + org.eclipse.jgit.revplot;version="5.1.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", + org.eclipse.jgit.revwalk;version="5.1.0"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff, org.eclipse.jgit.revwalk.filter", - org.eclipse.jgit.revwalk.filter;version="5.0.0";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.file;version="5.0.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.pack;version="5.0.0";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.submodule;version="5.0.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", - org.eclipse.jgit.transport;version="5.0.0"; + org.eclipse.jgit.revwalk.filter;version="5.1.0";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.file;version="5.1.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.pack;version="5.1.0";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.submodule;version="5.1.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", + org.eclipse.jgit.transport;version="5.1.0"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.revwalk, org.eclipse.jgit.internal.storage.pack, @@ -128,24 +128,24 @@ Export-Package: org.eclipse.jgit.annotations;version="5.0.0", org.eclipse.jgit.transport.http, org.eclipse.jgit.errors, org.eclipse.jgit.storage.pack", - org.eclipse.jgit.transport.http;version="5.0.0";uses:="javax.net.ssl", - org.eclipse.jgit.transport.resolver;version="5.0.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", - org.eclipse.jgit.treewalk;version="5.0.0"; + org.eclipse.jgit.transport.http;version="5.1.0";uses:="javax.net.ssl", + org.eclipse.jgit.transport.resolver;version="5.1.0";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", + org.eclipse.jgit.treewalk;version="5.1.0"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.attributes, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util, org.eclipse.jgit.dircache", - org.eclipse.jgit.treewalk.filter;version="5.0.0";uses:="org.eclipse.jgit.treewalk", - org.eclipse.jgit.util;version="5.0.0"; + org.eclipse.jgit.treewalk.filter;version="5.1.0";uses:="org.eclipse.jgit.treewalk", + org.eclipse.jgit.util;version="5.1.0"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.transport.http, org.eclipse.jgit.storage.file, org.ietf.jgss", - org.eclipse.jgit.util.io;version="5.0.0", - org.eclipse.jgit.util.sha1;version="5.0.0", - org.eclipse.jgit.util.time;version="5.0.0" + org.eclipse.jgit.util.io;version="5.1.0", + org.eclipse.jgit.util.sha1;version="5.1.0", + org.eclipse.jgit.util.time;version="5.1.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", com.jcraft.jsch;version="[0.1.37,0.2.0)", diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF index 89926f409a..99e4c0ca86 100644 --- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF @@ -3,5 +3,5 @@ Bundle-ManifestVersion: 2 Bundle-Name: org.eclipse.jgit - Sources Bundle-SymbolicName: org.eclipse.jgit.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 5.0.0.qualifier -Eclipse-SourceBundle: org.eclipse.jgit;version="5.0.0.qualifier";roots="." +Bundle-Version: 5.1.0.qualifier +Eclipse-SourceBundle: org.eclipse.jgit;version="5.1.0.qualifier";roots="." diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml index d94667f304..9dc588db24 100644 --- a/org.eclipse.jgit/pom.xml +++ b/org.eclipse.jgit/pom.xml @@ -53,7 +53,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.0.0-SNAPSHOT</version> + <version>5.1.0-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit</artifactId> diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsFsck.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsFsck.java index 985393c5e2..3f96d0919b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsFsck.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsFsck.java @@ -146,7 +146,7 @@ public class DfsFsck { throws IOException { pm.beginTask(JGitText.get().countingObjects, ProgressMonitor.UNKNOWN); try (ObjectWalk ow = new ObjectWalk(repo)) { - for (Ref r : repo.getAllRefs().values()) { + for (Ref r : repo.getRefDatabase().getRefs()) { ObjectId objectId = r.getObjectId(); if (objectId == null) { // skip unborn branch diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java index ca54ee22ea..09d59376a0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java @@ -43,13 +43,17 @@ package org.eclipse.jgit.internal.storage.dfs; +import static java.util.stream.Collectors.joining; + import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -86,10 +90,16 @@ public abstract class DfsObjDatabase extends ObjectDatabase { } }; - /** Sources for a pack file. */ + /** + * Sources for a pack file. + * <p> + * <strong>Note:</strong> When sorting packs by source, do not use the default + * comparator based on {@link Enum#compareTo}. Prefer {@link + * #DEFAULT_COMPARATOR} or your own {@link ComparatorBuilder}. + */ public static enum PackSource { /** The pack is created by ObjectInserter due to local activity. */ - INSERT(0), + INSERT, /** * The pack is created by PackParser due to a network event. @@ -100,7 +110,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * storage layout preferred by this version. Received packs are likely * to be either compacted or garbage collected in the future. */ - RECEIVE(0), + RECEIVE, /** * The pack was created by compacting multiple packs together. @@ -111,7 +121,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * * @see DfsPackCompactor */ - COMPACT(1), + COMPACT, /** * Pack was created by Git garbage collection by this implementation. @@ -122,17 +132,17 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * * @see DfsGarbageCollector */ - GC(2), + GC, /** Created from non-heads by {@link DfsGarbageCollector}. */ - GC_REST(3), + GC_REST, /** * RefTreeGraph pack was created by Git garbage collection. * * @see DfsGarbageCollector */ - GC_TXN(4), + GC_TXN, /** * Pack was created by Git garbage collection. @@ -141,12 +151,86 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * last GC pass. It is retained in a new pack until it is safe to prune * these objects from the repository. */ - UNREACHABLE_GARBAGE(5); + UNREACHABLE_GARBAGE; - final int category; + /** + * Default comparator for sources. + * <p> + * Sorts generally newer, smaller types such as {@code INSERT} and {@code + * RECEIVE} earlier; older, larger types such as {@code GC} later; and + * {@code UNREACHABLE_GARBAGE} at the end. + */ + public static final Comparator<PackSource> DEFAULT_COMPARATOR = + new ComparatorBuilder() + .add(INSERT, RECEIVE) + .add(COMPACT) + .add(GC) + .add(GC_REST) + .add(GC_TXN) + .add(UNREACHABLE_GARBAGE) + .build(); + + /** + * Builder for describing {@link PackSource} ordering where some values are + * explicitly considered equal to others. + */ + public static class ComparatorBuilder { + private final Map<PackSource, Integer> ranks = new HashMap<>(); + private int counter; + + /** + * Add a collection of sources that should sort as equal. + * <p> + * Sources in the input will sort after sources listed in previous calls + * to this method. + * + * @param sources + * sources in this equivalence class. + * @return this. + */ + public ComparatorBuilder add(PackSource... sources) { + for (PackSource s : sources) { + ranks.put(s, Integer.valueOf(counter)); + } + counter++; + return this; + } - PackSource(int category) { - this.category = category; + /** + * Build the comparator. + * + * @return new comparator instance. + * @throws IllegalArgumentException + * not all {@link PackSource} instances were explicitly assigned + * an equivalence class. + */ + public Comparator<PackSource> build() { + return new PackSourceComparator(ranks); + } + } + + private static class PackSourceComparator implements Comparator<PackSource> { + private final Map<PackSource, Integer> ranks; + + private PackSourceComparator(Map<PackSource, Integer> ranks) { + if (!ranks.keySet().equals( + new HashSet<>(Arrays.asList(PackSource.values())))) { + throw new IllegalArgumentException(); + } + this.ranks = new HashMap<>(ranks); + } + + @Override + public int compare(PackSource a, PackSource b) { + return ranks.get(a).compareTo(ranks.get(b)); + } + + @Override + public String toString() { + return Arrays.stream(PackSource.values()) + .map(s -> s + "=" + ranks.get(s)) //$NON-NLS-1$ + .collect(joining(", ", getClass().getSimpleName() + "{", "}")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } } } @@ -156,6 +240,8 @@ public abstract class DfsObjDatabase extends ObjectDatabase { private DfsReaderOptions readerOptions; + private Comparator<DfsPackDescription> packComparator; + /** * Initialize an object database for our repository. * @@ -169,6 +255,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { this.repository = repository; this.packList = new AtomicReference<>(NO_PACKS); this.readerOptions = options; + this.packComparator = DfsPackDescription.objectLookupComparator(); } /** @@ -180,6 +267,21 @@ public abstract class DfsObjDatabase extends ObjectDatabase { 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() { @@ -523,7 +625,7 @@ public abstract class DfsObjDatabase extends ObjectDatabase { Map<DfsPackDescription, DfsReftable> reftables = reftableMap(old); List<DfsPackDescription> scanned = listPacks(); - Collections.sort(scanned); + Collections.sort(scanned, packComparator); List<DfsPackFile> newPacks = new ArrayList<>(scanned.size()); List<DfsReftable> newReftables = new ArrayList<>(scanned.size()); @@ -584,30 +686,9 @@ public abstract class DfsObjDatabase extends ObjectDatabase { * @return comparator to sort {@link DfsReftable} by priority. */ protected Comparator<DfsReftable> reftableComparator() { - return (fa, fb) -> { - DfsPackDescription a = fa.getPackDescription(); - DfsPackDescription b = fb.getPackDescription(); - - // GC, COMPACT reftables first by higher category. - int c = category(b) - category(a); - if (c != 0) { - return c; - } - - // Lower maxUpdateIndex first. - c = Long.signum(a.getMaxUpdateIndex() - b.getMaxUpdateIndex()); - if (c != 0) { - return c; - } - - // Older reftable first. - return Long.signum(a.getLastModified() - b.getLastModified()); - }; - } - - static int category(DfsPackDescription d) { - PackSource s = d.getPackSource(); - return s != null ? s.category : 0; + return Comparator.comparing( + DfsReftable::getPackDescription, + DfsPackDescription.reftableComparator()); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java index b43b9b1780..127ee6bf11 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java @@ -404,12 +404,11 @@ public class DfsPackCompactor { // Sort packs by description ordering, this places newer packs before // older packs, allowing the PackWriter to be handed newer objects // first and older objects last. - Collections.sort(srcPacks, new Comparator<DfsPackFile>() { - @Override - public int compare(DfsPackFile a, DfsPackFile b) { - return a.getPackDescription().compareTo(b.getPackDescription()); - } - }); + Collections.sort( + srcPacks, + Comparator.comparing( + DfsPackFile::getPackDescription, + DfsPackDescription.objectLookupComparator())); rw = new RevWalk(ctx); added = rw.newFlag("ADDED"); //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java index 45eb7b0e1a..5a1ac02e25 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java @@ -47,7 +47,9 @@ import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE; import java.util.Arrays; +import java.util.Comparator; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.reftable.ReftableWriter; @@ -61,7 +63,107 @@ import org.eclipse.jgit.storage.pack.PackStatistics; * Instances of this class are cached with the DfsPackFile, and should not be * modified once initialized and presented to the JGit DFS library. */ -public class DfsPackDescription implements Comparable<DfsPackDescription> { +public class DfsPackDescription { + /** + * 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. + * <p> + * 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, packSourceComparator) + .thenComparing((a, b) -> { + PackSource as = a.getPackSource(); + PackSource bs = b.getPackSource(); + + // Tie break GC type packs by smallest first. There should be at most + // one of each source, but when multiple exist concurrent GCs may have + // run. Preferring the smaller file selects higher quality delta + // compression, placing less demand on the DfsBlockCache. + if (as == bs && isGC(as)) { + int cmp = Long.signum(a.getFileSize(PACK) - b.getFileSize(PACK)); + if (cmp != 0) { + return cmp; + } + } + + // Newer packs should sort first. + int cmp = Long.signum(b.getLastModified() - a.getLastModified()); + if (cmp != 0) { + return cmp; + } + + // Break ties on smaller index. Readers may get lucky and find + // the object they care about in the smaller index. This also pushes + // big historical packs to the end of the list, due to more objects. + return Long.signum(a.getObjectCount() - b.getObjectCount()); + }); + } + + static Comparator<DfsPackDescription> reftableComparator() { + return (a, b) -> { + // GC, COMPACT reftables first by reversing default order. + int c = PackSource.DEFAULT_COMPARATOR.reversed() + .compare(a.getPackSource(), b.getPackSource()); + if (c != 0) { + return c; + } + + // Lower maxUpdateIndex first. + c = Long.signum(a.getMaxUpdateIndex() - b.getMaxUpdateIndex()); + if (c != 0) { + return c; + } + + // Older reftable first. + return Long.signum(a.getLastModified() - b.getLastModified()); + }; + } + + static Comparator<DfsPackDescription> reuseComparator() { + return (a, b) -> { + PackSource as = a.getPackSource(); + PackSource bs = b.getPackSource(); + + if (as == bs && DfsPackDescription.isGC(as)) { + // Push smaller GC files last; these likely have higher quality + // delta compression and the contained representation should be + // favored over other files. + return Long.signum(b.getFileSize(PACK) - a.getFileSize(PACK)); + } + + // DfsPackDescription.compareTo already did a reasonable sort. + // Rely on Arrays.sort being stable, leaving equal elements. + return 0; + }; + } + private final DfsRepositoryDescription repoDesc; private final String packName; private PackSource packSource; @@ -93,11 +195,15 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { * name of the pack file. Must end with ".pack". * @param repoDesc * description of the repo containing the pack file. + * @param packSource + * the source of the pack. */ - public DfsPackDescription(DfsRepositoryDescription repoDesc, String name) { + public DfsPackDescription(DfsRepositoryDescription repoDesc, String name, + @NonNull PackSource packSource) { this.repoDesc = repoDesc; int dot = name.lastIndexOf('.'); this.packName = (dot < 0) ? name : name.substring(0, dot); + this.packSource = packSource; int extCnt = PackExt.values().length; sizeMap = new long[extCnt]; @@ -162,6 +268,7 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { * * @return the source of the pack. */ + @NonNull public PackSource getPackSource() { return packSource; } @@ -173,7 +280,7 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { * the source of the pack. * @return {@code this} */ - public DfsPackDescription setPackSource(PackSource source) { + public DfsPackDescription setPackSource(@NonNull PackSource source) { packSource = source; return this; } @@ -455,49 +562,6 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { return false; } - /** - * {@inheritDoc} - * <p> - * Sort packs according to the optimal lookup ordering. - * <p> - * This method 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. - */ - @Override - public int compareTo(DfsPackDescription b) { - // Cluster by PackSource, pushing UNREACHABLE_GARBAGE to the end. - PackSource as = getPackSource(); - PackSource bs = b.getPackSource(); - if (as != null && bs != null) { - int cmp = as.category - bs.category; - if (cmp != 0) - return cmp; - } - - // Tie break GC type packs by smallest first. There should be at most - // one of each source, but when multiple exist concurrent GCs may have - // run. Preferring the smaller file selects higher quality delta - // compression, placing less demand on the DfsBlockCache. - if (as != null && as == bs && isGC(as)) { - int cmp = Long.signum(getFileSize(PACK) - b.getFileSize(PACK)); - if (cmp != 0) { - return cmp; - } - } - - // Newer packs should sort first. - int cmp = Long.signum(b.getLastModified() - getLastModified()); - if (cmp != 0) - return cmp; - - // Break ties on smaller index. Readers may get lucky and find - // the object they care about in the smaller index. This also pushes - // big historical packs to the end of the list, due to more objects. - return Long.signum(getObjectCount() - b.getObjectCount()); - } - static boolean isGC(PackSource s) { switch (s) { case GC: diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java index 197114bd6b..d04709f6c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java @@ -45,7 +45,6 @@ package org.eclipse.jgit.internal.storage.dfs; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE; -import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; import java.io.IOException; @@ -66,7 +65,6 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackList; -import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl; import org.eclipse.jgit.internal.storage.file.PackBitmapIndex; import org.eclipse.jgit.internal.storage.file.PackIndex; @@ -611,26 +609,9 @@ public class DfsReader extends ObjectReader implements ObjectReuseAsIs { } } - private static final Comparator<DfsPackFile> PACK_SORT_FOR_REUSE = new Comparator<DfsPackFile>() { - @Override - public int compare(DfsPackFile af, DfsPackFile bf) { - DfsPackDescription ad = af.getPackDescription(); - DfsPackDescription bd = bf.getPackDescription(); - PackSource as = ad.getPackSource(); - PackSource bs = bd.getPackSource(); - - if (as != null && as == bs && DfsPackDescription.isGC(as)) { - // Push smaller GC files last; these likely have higher quality - // delta compression and the contained representation should be - // favored over other files. - return Long.signum(bd.getFileSize(PACK) - ad.getFileSize(PACK)); - } - - // DfsPackDescription.compareTo already did a reasonable sort. - // Rely on Arrays.sort being stable, leaving equal elements. - return 0; - } - }; + private static final Comparator<DfsPackFile> PACK_SORT_FOR_REUSE = + Comparator.comparing( + DfsPackFile::getPackDescription, DfsPackDescription.reuseComparator()); private List<DfsPackFile> sortPacksForSelectRepresentation() throws IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java index 662c3fef81..5b6894da9c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.reftable.ReftableConfig; import org.eclipse.jgit.lib.RefDatabase; @@ -118,10 +119,10 @@ public class InMemoryRepository extends DfsRepository { @Override protected DfsPackDescription newPack(PackSource source) { int id = packId.incrementAndGet(); - DfsPackDescription desc = new MemPack( + return new MemPack( "pack-" + id + "-" + source.name(), //$NON-NLS-1$ //$NON-NLS-2$ - getRepository().getDescription()); - return desc.setPackSource(source); + getRepository().getDescription(), + source); } @Override @@ -169,8 +170,8 @@ public class InMemoryRepository extends DfsRepository { private static class MemPack extends DfsPackDescription { final byte[][] fileMap = new byte[PackExt.values().length][]; - MemPack(String name, DfsRepositoryDescription repoDesc) { - super(repoDesc, name); + MemPack(String name, DfsRepositoryDescription repoDesc, PackSource source) { + super(repoDesc, name, source); } void put(PackExt ext, byte[] data) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java index ed5cf2c9e2..e280120a94 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java @@ -477,7 +477,7 @@ public class FileRepository extends Repository { /** * {@inheritDoc} * <p> - * Objects known to exist but not expressed by {@link #getAllRefs()}. + * Objects known to exist but not expressed by {@code #getAllRefs()}. * <p> * When a repository borrows objects from another repository, it can * advertise that it safely has that other repository's references, without @@ -490,12 +490,12 @@ public class FileRepository extends Repository { } /** - * Objects known to exist but not expressed by {@link #getAllRefs()}. + * Objects known to exist but not expressed by {@code #getAllRefs()}. * <p> * When a repository borrows objects from another repository, it can * advertise that it safely has that other repository's references, without - * exposing any other details about the other repository. This may help - * a client trying to push changes avoid pushing more than it needs to. + * exposing any other details about the other repository. This may help a + * client trying to push changes avoid pushing more than it needs to. * * @param skips * Set of AlternateHandle Ids already seen diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index fa283d0129..5fec5aadf0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -1092,7 +1092,9 @@ public abstract class Repository implements AutoCloseable { * not point to any object yet. * * @return mutable map of all known refs (heads, tags, remotes). + * @deprecated use {@code getRefDatabase().getRefs()} instead. */ + @Deprecated @NonNull public Map<String, Ref> getAllRefs() { try { |