diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java new file mode 100644 index 000000000..b3d140a8e --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.storage.pack; + +import static java.util.zip.Deflater.DEFAULT_COMPRESSION; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.Config.SectionParser; + +class PackConfig { + /** Key for {@link Config#get(SectionParser)}. */ + static final Config.SectionParser KEY = new SectionParser() { + public PackConfig parse(final Config cfg) { + return new PackConfig(cfg); + } + }; + + final int deltaWindow; + + final long deltaWindowMemory; + + final int deltaDepth; + + final int compression; + + final int indexVersion; + + private PackConfig(Config rc) { + deltaWindow = rc.getInt("pack", "window", PackWriter.DEFAULT_DELTA_SEARCH_WINDOW_SIZE); + deltaWindowMemory = rc.getLong("pack", null, "windowmemory", 0); + deltaDepth = rc.getInt("pack", "depth", PackWriter.DEFAULT_MAX_DELTA_DEPTH); + compression = compression(rc); + indexVersion = rc.getInt("pack", "indexversion", 2); + } + + private static int compression(Config rc) { + if (rc.getString("pack", null, "compression") != null) + return rc.getInt("pack", "compression", DEFAULT_COMPRESSION); + return rc.getInt("core", "compression", DEFAULT_COMPRESSION); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java index 5ecef832a..05e863e55 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java @@ -66,7 +66,6 @@ import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.CoreConfig; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdSubclassMap; @@ -166,6 +165,13 @@ public class PackWriter { */ public static final int DEFAULT_MAX_DELTA_DEPTH = 50; + /** + * Default window size during packing. + * + * @see #setDeltaSearchWindowSize(int) + */ + public static final int DEFAULT_DELTA_SEARCH_WINDOW_SIZE = 10; + private static final int PACK_VERSION_GENERATED = 2; @SuppressWarnings("unchecked") @@ -202,9 +208,13 @@ public class PackWriter { private boolean deltaBaseAsOffset = DEFAULT_DELTA_BASE_AS_OFFSET; + private boolean deltaCompress = true; + private int maxDeltaDepth = DEFAULT_MAX_DELTA_DEPTH; - private int outputVersion; + private int deltaSearchWindowSize = DEFAULT_DELTA_SEARCH_WINDOW_SIZE; + + private int indexVersion; private boolean thin; @@ -254,9 +264,11 @@ public class PackWriter { else reuseSupport = null; - final CoreConfig coreConfig = configOf(repo).get(CoreConfig.KEY); - compressionLevel = coreConfig.getCompression(); - outputVersion = coreConfig.getPackIndexVersion(); + final PackConfig pc = configOf(repo).get(PackConfig.KEY); + deltaSearchWindowSize = pc.deltaWindow; + maxDeltaDepth = pc.deltaDepth; + compressionLevel = pc.compression; + indexVersion = pc.indexVersion; } private static Config configOf(final Repository repo) { @@ -364,6 +376,32 @@ public class PackWriter { this.deltaBaseAsOffset = deltaBaseAsOffset; } + /** + * Check whether the writer will create new deltas on the fly. + *

+ * Default setting: true + *

+ * + * @return true if the writer will create a new delta when either + * {@link #isReuseDeltas()} is false, or no suitable delta is + * available for reuse. + */ + public boolean isDeltaCompress() { + return deltaCompress; + } + + /** + * Set whether or not the writer will create new deltas on the fly. + * + * @param deltaCompress + * true to create deltas when {@link #isReuseDeltas()} is false, + * or when a suitable delta isn't available for reuse. Set to + * false to write whole objects instead. + */ + public void setDeltaCompress(boolean deltaCompress) { + this.deltaCompress = deltaCompress; + } + /** * Get maximum depth of delta chain set up for this writer. Generated chains * are not longer than this value. @@ -392,6 +430,31 @@ public class PackWriter { this.maxDeltaDepth = maxDeltaDepth; } + /** + * Get the number of objects to try when looking for a delta base. + * + * @return the object count to be searched. + */ + public int getDeltaSearchWindowSize() { + return deltaSearchWindowSize; + } + + /** + * Set the number of objects considered when searching for a delta base. + *

+ * Default setting: {@value #DEFAULT_DELTA_SEARCH_WINDOW_SIZE} + *

+ * + * @param objectCount + * number of objects to search at once. Must be at least 2. + */ + public void setDeltaSearchWindowSize(int objectCount) { + if (objectCount <= 2) + setDeltaCompress(false); + else + deltaSearchWindowSize = objectCount; + } + /** @return true if this writer is producing a thin pack. */ public boolean isThin() { return thin; @@ -440,7 +503,7 @@ public class PackWriter { * @see PackIndexWriter */ public void setIndexVersion(final int version) { - outputVersion = version; + indexVersion = version; } /** @@ -571,10 +634,10 @@ public class PackWriter { public void writeIndex(final OutputStream indexStream) throws IOException { final List list = sortByName(); final PackIndexWriter iw; - if (outputVersion <= 0) + if (indexVersion <= 0) iw = PackIndexWriter.createOldestPossible(indexStream, list); else - iw = PackIndexWriter.createVersion(indexStream, outputVersion); + iw = PackIndexWriter.createVersion(indexStream, indexVersion); iw.write(list, packcsum); }