PackConfig.java

  1. /*
  2.  * Copyright (C) 2008-2010, Google Inc.
  3.  * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com> and others
  4.  *
  5.  * This program and the accompanying materials are made available under the
  6.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  7.  * https://www.eclipse.org/org/documents/edl-v10.php.
  8.  *
  9.  * SPDX-License-Identifier: BSD-3-Clause
  10.  */

  11. package org.eclipse.jgit.storage.pack;

  12. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
  13. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BIGFILE_THRESHOLD;
  14. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT;
  15. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN;
  16. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT;
  17. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS;
  18. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT;
  19. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BUILD_BITMAPS;
  20. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_COMPRESSION;
  21. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_CUT_DELTACHAINS;
  22. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_CACHE_LIMIT;
  23. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_CACHE_SIZE;
  24. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_COMPRESSION;
  25. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DEPTH;
  26. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_INDEXVERSION;
  27. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK;
  28. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REUSE_DELTAS;
  29. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REUSE_OBJECTS;
  30. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_SEARCH_FOR_REUSE_TIMEOUT;
  31. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_SINGLE_PACK;
  32. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_THREADS;
  33. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WAIT_PREVENT_RACYPACK;
  34. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW;
  35. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW_MEMORY;
  36. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;

  37. import java.time.Duration;
  38. import java.util.concurrent.Executor;
  39. import java.util.concurrent.TimeUnit;
  40. import java.util.zip.Deflater;

  41. import org.eclipse.jgit.internal.storage.file.PackIndexWriter;
  42. import org.eclipse.jgit.lib.Config;
  43. import org.eclipse.jgit.lib.Repository;

  44. /**
  45.  * Configuration used by a pack writer when constructing the stream.
  46.  *
  47.  * A configuration may be modified once created, but should not be modified
  48.  * while it is being used by a PackWriter. If a configuration is not modified it
  49.  * is safe to share the same configuration instance between multiple concurrent
  50.  * threads executing different PackWriters.
  51.  */
  52. public class PackConfig {
  53.     /**
  54.      * Default value of deltas reuse option: {@value}
  55.      *
  56.      * @see #setReuseDeltas(boolean)
  57.      */
  58.     public static final boolean DEFAULT_REUSE_DELTAS = true;

  59.     /**
  60.      * Default value of objects reuse option: {@value}
  61.      *
  62.      * @see #setReuseObjects(boolean)
  63.      */
  64.     public static final boolean DEFAULT_REUSE_OBJECTS = true;

  65.     /**
  66.      * Default value of keep old packs option: {@value}
  67.      * @see #setPreserveOldPacks(boolean)
  68.      * @since 4.7
  69.      */
  70.     public static final boolean DEFAULT_PRESERVE_OLD_PACKS = false;

  71.     /**
  72.      * Default value of prune old packs option: {@value}
  73.      * @see #setPrunePreserved(boolean)
  74.      * @since 4.7
  75.      */
  76.     public static final boolean DEFAULT_PRUNE_PRESERVED = false;

  77.     /**
  78.      * Default value of delta compress option: {@value}
  79.      *
  80.      * @see #setDeltaCompress(boolean)
  81.      */
  82.     public static final boolean DEFAULT_DELTA_COMPRESS = true;

  83.     /**
  84.      * Default value of delta base as offset option: {@value}
  85.      *
  86.      * @see #setDeltaBaseAsOffset(boolean)
  87.      */
  88.     public static final boolean DEFAULT_DELTA_BASE_AS_OFFSET = false;

  89.     /**
  90.      * Default value of maximum delta chain depth: {@value}
  91.      *
  92.      * @see #setMaxDeltaDepth(int)
  93.      */
  94.     public static final int DEFAULT_MAX_DELTA_DEPTH = 50;

  95.     /**
  96.      * Default window size during packing: {@value}
  97.      *
  98.      * @see #setDeltaSearchWindowSize(int)
  99.      */
  100.     public static final int DEFAULT_DELTA_SEARCH_WINDOW_SIZE = 10;

  101.     private static final int MB = 1 << 20;

  102.     /**
  103.      * Default big file threshold: {@value}
  104.      *
  105.      * @see #setBigFileThreshold(int)
  106.      */
  107.     public static final int DEFAULT_BIG_FILE_THRESHOLD = 50 * MB;

  108.     /**
  109.      * Default if we wait before opening a newly written pack to prevent its
  110.      * lastModified timestamp could be racy
  111.      *
  112.      * @since 5.1.8
  113.      */
  114.     public static final boolean DEFAULT_WAIT_PREVENT_RACY_PACK = false;

  115.     /**
  116.      * Default if we wait before opening a newly written pack to prevent its
  117.      * lastModified timestamp could be racy
  118.      *
  119.      * @since 5.1.8
  120.      */
  121.     public static final long DEFAULT_MINSIZE_PREVENT_RACY_PACK = 100 * MB;

  122.     /**
  123.      * Default delta cache size: {@value}
  124.      *
  125.      * @see #setDeltaCacheSize(long)
  126.      */
  127.     public static final long DEFAULT_DELTA_CACHE_SIZE = 50 * 1024 * 1024;

  128.     /**
  129.      * Default delta cache limit: {@value}
  130.      *
  131.      * @see #setDeltaCacheLimit(int)
  132.      */
  133.     public static final int DEFAULT_DELTA_CACHE_LIMIT = 100;

  134.     /**
  135.      * Default index version: {@value}
  136.      *
  137.      * @see #setIndexVersion(int)
  138.      */
  139.     public static final int DEFAULT_INDEX_VERSION = 2;

  140.     /**
  141.      * Default value of the build bitmaps option: {@value}
  142.      *
  143.      * @see #setBuildBitmaps(boolean)
  144.      * @since 3.0
  145.      */
  146.     public static final boolean DEFAULT_BUILD_BITMAPS = true;

  147.     /**
  148.      * Default count of most recent commits to select for bitmaps. Only applies
  149.      * when bitmaps are enabled: {@value}
  150.      *
  151.      * @see #setBitmapContiguousCommitCount(int)
  152.      * @since 4.2
  153.      */
  154.     public static final int DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT = 100;

  155.     /**
  156.      * Count at which the span between selected commits changes from
  157.      * "bitmapRecentCommitSpan" to "bitmapDistantCommitSpan". Only applies when
  158.      * bitmaps are enabled: {@value}
  159.      *
  160.      * @see #setBitmapRecentCommitCount(int)
  161.      * @since 4.2
  162.      */
  163.     public static final int DEFAULT_BITMAP_RECENT_COMMIT_COUNT = 20000;

  164.     /**
  165.      * Default spacing between commits in recent history when selecting commits
  166.      * for bitmaps. Only applies when bitmaps are enabled: {@value}
  167.      *
  168.      * @see #setBitmapRecentCommitSpan(int)
  169.      * @since 4.2
  170.      */
  171.     public static final int DEFAULT_BITMAP_RECENT_COMMIT_SPAN = 100;

  172.     /**
  173.      * Default spacing between commits in distant history when selecting commits
  174.      * for bitmaps. Only applies when bitmaps are enabled: {@value}
  175.      *
  176.      * @see #setBitmapDistantCommitSpan(int)
  177.      * @since 4.2
  178.      */
  179.     public static final int DEFAULT_BITMAP_DISTANT_COMMIT_SPAN = 5000;

  180.     /**
  181.      * Default count of branches required to activate inactive branch commit
  182.      * selection. If the number of branches is less than this then bitmaps for
  183.      * the entire commit history of all branches will be created, otherwise
  184.      * branches marked as "inactive" will have coverage for only partial
  185.      * history: {@value}
  186.      *
  187.      * @see #setBitmapExcessiveBranchCount(int)
  188.      * @since 4.2
  189.      */
  190.     public static final int DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT = 100;

  191.     /**
  192.      * Default age at which a branch is considered inactive. Age is taken as the
  193.      * number of days ago that the most recent commit was made to a branch. Only
  194.      * affects bitmap processing if bitmaps are enabled and the
  195.      * "excessive branch count" has been exceeded: {@value}
  196.      *
  197.      * @see #setBitmapInactiveBranchAgeInDays(int)
  198.      * @since 4.2
  199.      */
  200.     public static final int DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS = 90;

  201.     /**
  202.      * Default max time to spend during the search for reuse phase. This
  203.      * optimization is disabled by default: {@value}
  204.      *
  205.      * @see #setSearchForReuseTimeout(Duration)
  206.      * @since 5.13
  207.      */
  208.     public static final Duration DEFAULT_SEARCH_FOR_REUSE_TIMEOUT = Duration
  209.             .ofSeconds(Integer.MAX_VALUE);

  210.     private int compressionLevel = Deflater.DEFAULT_COMPRESSION;

  211.     private boolean reuseDeltas = DEFAULT_REUSE_DELTAS;

  212.     private boolean reuseObjects = DEFAULT_REUSE_OBJECTS;

  213.     private boolean preserveOldPacks = DEFAULT_PRESERVE_OLD_PACKS;

  214.     private boolean prunePreserved = DEFAULT_PRUNE_PRESERVED;

  215.     private boolean deltaBaseAsOffset = DEFAULT_DELTA_BASE_AS_OFFSET;

  216.     private boolean deltaCompress = DEFAULT_DELTA_COMPRESS;

  217.     private int maxDeltaDepth = DEFAULT_MAX_DELTA_DEPTH;

  218.     private int deltaSearchWindowSize = DEFAULT_DELTA_SEARCH_WINDOW_SIZE;

  219.     private long deltaSearchMemoryLimit;

  220.     private long deltaCacheSize = DEFAULT_DELTA_CACHE_SIZE;

  221.     private int deltaCacheLimit = DEFAULT_DELTA_CACHE_LIMIT;

  222.     private int bigFileThreshold = DEFAULT_BIG_FILE_THRESHOLD;

  223.     private boolean waitPreventRacyPack = DEFAULT_WAIT_PREVENT_RACY_PACK;

  224.     private long minSizePreventRacyPack = DEFAULT_MINSIZE_PREVENT_RACY_PACK;

  225.     private int threads;

  226.     private Executor executor;

  227.     private int indexVersion = DEFAULT_INDEX_VERSION;

  228.     private boolean buildBitmaps = DEFAULT_BUILD_BITMAPS;

  229.     private int bitmapContiguousCommitCount = DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT;

  230.     private int bitmapRecentCommitCount = DEFAULT_BITMAP_RECENT_COMMIT_COUNT;

  231.     private int bitmapRecentCommitSpan = DEFAULT_BITMAP_RECENT_COMMIT_SPAN;

  232.     private int bitmapDistantCommitSpan = DEFAULT_BITMAP_DISTANT_COMMIT_SPAN;

  233.     private int bitmapExcessiveBranchCount = DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT;

  234.     private int bitmapInactiveBranchAgeInDays = DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS;

  235.     private Duration searchForReuseTimeout = DEFAULT_SEARCH_FOR_REUSE_TIMEOUT;

  236.     private boolean cutDeltaChains;

  237.     private boolean singlePack;

  238.     /**
  239.      * Create a default configuration.
  240.      */
  241.     public PackConfig() {
  242.         // Fields are initialized to defaults.
  243.     }

  244.     /**
  245.      * Create a configuration honoring the repository's settings.
  246.      *
  247.      * @param db
  248.      *            the repository to read settings from. The repository is not
  249.      *            retained by the new configuration, instead its settings are
  250.      *            copied during the constructor.
  251.      */
  252.     public PackConfig(Repository db) {
  253.         fromConfig(db.getConfig());
  254.     }

  255.     /**
  256.      * Create a configuration honoring settings in a
  257.      * {@link org.eclipse.jgit.lib.Config}.
  258.      *
  259.      * @param cfg
  260.      *            the source to read settings from. The source is not retained
  261.      *            by the new configuration, instead its settings are copied
  262.      *            during the constructor.
  263.      */
  264.     public PackConfig(Config cfg) {
  265.         fromConfig(cfg);
  266.     }

  267.     /**
  268.      * Copy an existing configuration to a new instance.
  269.      *
  270.      * @param cfg
  271.      *            the source configuration to copy from.
  272.      */
  273.     public PackConfig(PackConfig cfg) {
  274.         this.compressionLevel = cfg.compressionLevel;
  275.         this.reuseDeltas = cfg.reuseDeltas;
  276.         this.reuseObjects = cfg.reuseObjects;
  277.         this.preserveOldPacks = cfg.preserveOldPacks;
  278.         this.prunePreserved = cfg.prunePreserved;
  279.         this.deltaBaseAsOffset = cfg.deltaBaseAsOffset;
  280.         this.deltaCompress = cfg.deltaCompress;
  281.         this.maxDeltaDepth = cfg.maxDeltaDepth;
  282.         this.deltaSearchWindowSize = cfg.deltaSearchWindowSize;
  283.         this.deltaSearchMemoryLimit = cfg.deltaSearchMemoryLimit;
  284.         this.deltaCacheSize = cfg.deltaCacheSize;
  285.         this.deltaCacheLimit = cfg.deltaCacheLimit;
  286.         this.bigFileThreshold = cfg.bigFileThreshold;
  287.         this.waitPreventRacyPack = cfg.waitPreventRacyPack;
  288.         this.minSizePreventRacyPack = cfg.minSizePreventRacyPack;
  289.         this.threads = cfg.threads;
  290.         this.executor = cfg.executor;
  291.         this.indexVersion = cfg.indexVersion;
  292.         this.buildBitmaps = cfg.buildBitmaps;
  293.         this.bitmapContiguousCommitCount = cfg.bitmapContiguousCommitCount;
  294.         this.bitmapRecentCommitCount = cfg.bitmapRecentCommitCount;
  295.         this.bitmapRecentCommitSpan = cfg.bitmapRecentCommitSpan;
  296.         this.bitmapDistantCommitSpan = cfg.bitmapDistantCommitSpan;
  297.         this.bitmapExcessiveBranchCount = cfg.bitmapExcessiveBranchCount;
  298.         this.bitmapInactiveBranchAgeInDays = cfg.bitmapInactiveBranchAgeInDays;
  299.         this.cutDeltaChains = cfg.cutDeltaChains;
  300.         this.singlePack = cfg.singlePack;
  301.         this.searchForReuseTimeout = cfg.searchForReuseTimeout;
  302.     }

  303.     /**
  304.      * Check whether to reuse deltas existing in repository.
  305.      *
  306.      * Default setting: {@value #DEFAULT_REUSE_DELTAS}
  307.      *
  308.      * @return true if object is configured to reuse deltas; false otherwise.
  309.      */
  310.     public boolean isReuseDeltas() {
  311.         return reuseDeltas;
  312.     }

  313.     /**
  314.      * Set reuse deltas configuration option for the writer.
  315.      *
  316.      * When enabled, writer will search for delta representation of object in
  317.      * repository and use it if possible. Normally, only deltas with base to
  318.      * another object existing in set of objects to pack will be used. The
  319.      * exception however is thin-packs where the base object may exist on the
  320.      * other side.
  321.      *
  322.      * When raw delta data is directly copied from a pack file, its checksum is
  323.      * computed to verify the data is not corrupt.
  324.      *
  325.      * Default setting: {@value #DEFAULT_REUSE_DELTAS}
  326.      *
  327.      * @param reuseDeltas
  328.      *            boolean indicating whether or not try to reuse deltas.
  329.      */
  330.     public void setReuseDeltas(boolean reuseDeltas) {
  331.         this.reuseDeltas = reuseDeltas;
  332.     }

  333.     /**
  334.      * Checks whether to reuse existing objects representation in repository.
  335.      *
  336.      * Default setting: {@value #DEFAULT_REUSE_OBJECTS}
  337.      *
  338.      * @return true if writer is configured to reuse objects representation from
  339.      *         pack; false otherwise.
  340.      */
  341.     public boolean isReuseObjects() {
  342.         return reuseObjects;
  343.     }

  344.     /**
  345.      * Set reuse objects configuration option for the writer.
  346.      *
  347.      * If enabled, writer searches for compressed representation in a pack file.
  348.      * If possible, compressed data is directly copied from such a pack file.
  349.      * Data checksum is verified.
  350.      *
  351.      * Default setting: {@value #DEFAULT_REUSE_OBJECTS}
  352.      *
  353.      * @param reuseObjects
  354.      *            boolean indicating whether or not writer should reuse existing
  355.      *            objects representation.
  356.      */
  357.     public void setReuseObjects(boolean reuseObjects) {
  358.         this.reuseObjects = reuseObjects;
  359.     }

  360.     /**
  361.      * Checks whether to preserve old packs in a preserved directory
  362.      *
  363.      * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
  364.      *
  365.      * @return true if repacking will preserve old pack files.
  366.      * @since 4.7
  367.      */
  368.     public boolean isPreserveOldPacks() {
  369.         return preserveOldPacks;
  370.     }

  371.     /**
  372.      * Set preserve old packs configuration option for repacking.
  373.      *
  374.      * If enabled, old pack files are moved into a preserved subdirectory instead
  375.      * of being deleted
  376.      *
  377.      * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
  378.      *
  379.      * @param preserveOldPacks
  380.      *            boolean indicating whether or not preserve old pack files
  381.      * @since 4.7
  382.      */
  383.     public void setPreserveOldPacks(boolean preserveOldPacks) {
  384.         this.preserveOldPacks = preserveOldPacks;
  385.     }

  386.     /**
  387.      * Checks whether to remove preserved pack files in a preserved directory
  388.      *
  389.      * Default setting: {@value #DEFAULT_PRUNE_PRESERVED}
  390.      *
  391.      * @return true if repacking will remove preserved pack files.
  392.      * @since 4.7
  393.      */
  394.     public boolean isPrunePreserved() {
  395.         return prunePreserved;
  396.     }

  397.     /**
  398.      * Set prune preserved configuration option for repacking.
  399.      *
  400.      * If enabled, preserved pack files are removed from a preserved subdirectory
  401.      *
  402.      * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
  403.      *
  404.      * @param prunePreserved
  405.      *            boolean indicating whether or not preserve old pack files
  406.      * @since 4.7
  407.      */
  408.     public void setPrunePreserved(boolean prunePreserved) {
  409.         this.prunePreserved = prunePreserved;
  410.     }

  411.     /**
  412.      * True if writer can use offsets to point to a delta base.
  413.      *
  414.      * If true the writer may choose to use an offset to point to a delta base
  415.      * in the same pack, this is a newer style of reference that saves space.
  416.      * False if the writer has to use the older (and more compatible style) of
  417.      * storing the full ObjectId of the delta base.
  418.      *
  419.      * Default setting: {@value #DEFAULT_DELTA_BASE_AS_OFFSET}
  420.      *
  421.      * @return true if delta base is stored as an offset; false if it is stored
  422.      *         as an ObjectId.
  423.      */
  424.     public boolean isDeltaBaseAsOffset() {
  425.         return deltaBaseAsOffset;
  426.     }

  427.     /**
  428.      * Set writer delta base format.
  429.      *
  430.      * Delta base can be written as an offset in a pack file (new approach
  431.      * reducing file size) or as an object id (legacy approach, compatible with
  432.      * old readers).
  433.      *
  434.      * Default setting: {@value #DEFAULT_DELTA_BASE_AS_OFFSET}
  435.      *
  436.      * @param deltaBaseAsOffset
  437.      *            boolean indicating whether delta base can be stored as an
  438.      *            offset.
  439.      */
  440.     public void setDeltaBaseAsOffset(boolean deltaBaseAsOffset) {
  441.         this.deltaBaseAsOffset = deltaBaseAsOffset;
  442.     }

  443.     /**
  444.      * Check whether the writer will create new deltas on the fly.
  445.      *
  446.      * Default setting: {@value #DEFAULT_DELTA_COMPRESS}
  447.      *
  448.      * @return true if the writer will create a new delta when either
  449.      *         {@link #isReuseDeltas()} is false, or no suitable delta is
  450.      *         available for reuse.
  451.      */
  452.     public boolean isDeltaCompress() {
  453.         return deltaCompress;
  454.     }

  455.     /**
  456.      * Set whether or not the writer will create new deltas on the fly.
  457.      *
  458.      * Default setting: {@value #DEFAULT_DELTA_COMPRESS}
  459.      *
  460.      * @param deltaCompress
  461.      *            true to create deltas when {@link #isReuseDeltas()} is false,
  462.      *            or when a suitable delta isn't available for reuse. Set to
  463.      *            false to write whole objects instead.
  464.      */
  465.     public void setDeltaCompress(boolean deltaCompress) {
  466.         this.deltaCompress = deltaCompress;
  467.     }

  468.     /**
  469.      * Get maximum depth of delta chain set up for the writer.
  470.      *
  471.      * Generated chains are not longer than this value.
  472.      *
  473.      * Default setting: {@value #DEFAULT_MAX_DELTA_DEPTH}
  474.      *
  475.      * @return maximum delta chain depth.
  476.      */
  477.     public int getMaxDeltaDepth() {
  478.         return maxDeltaDepth;
  479.     }

  480.     /**
  481.      * Set up maximum depth of delta chain for the writer.
  482.      *
  483.      * Generated chains are not longer than this value. Too low value causes low
  484.      * compression level, while too big makes unpacking (reading) longer.
  485.      *
  486.      * Default setting: {@value #DEFAULT_MAX_DELTA_DEPTH}
  487.      *
  488.      * @param maxDeltaDepth
  489.      *            maximum delta chain depth.
  490.      */
  491.     public void setMaxDeltaDepth(int maxDeltaDepth) {
  492.         this.maxDeltaDepth = maxDeltaDepth;
  493.     }

  494.     /**
  495.      * Whether existing delta chains should be cut at
  496.      * {@link #getMaxDeltaDepth()}.
  497.      *
  498.      * @return true if existing delta chains should be cut at
  499.      *         {@link #getMaxDeltaDepth()}. Default is false, allowing existing
  500.      *         chains to be of any length.
  501.      * @since 3.0
  502.      */
  503.     public boolean getCutDeltaChains() {
  504.         return cutDeltaChains;
  505.     }

  506.     /**
  507.      * Enable cutting existing delta chains at {@link #getMaxDeltaDepth()}.
  508.      *
  509.      * By default this is disabled and existing chains are kept at whatever
  510.      * length a prior packer was configured to create. This allows objects to be
  511.      * packed one with a large depth (for example 250), and later to quickly
  512.      * repack the repository with a shorter depth (such as 50), but reusing the
  513.      * complete delta chains created by the earlier 250 depth.
  514.      *
  515.      * @param cut
  516.      *            true to cut existing chains.
  517.      * @since 3.0
  518.      */
  519.     public void setCutDeltaChains(boolean cut) {
  520.         cutDeltaChains = cut;
  521.     }

  522.     /**
  523.      * Whether all of refs/* should be packed in a single pack.
  524.      *
  525.      * @return true if all of refs/* should be packed in a single pack. Default
  526.      *         is false, packing a separate GC_REST pack for references outside
  527.      *         of refs/heads/* and refs/tags/*.
  528.      * @since 4.9
  529.      */
  530.     public boolean getSinglePack() {
  531.         return singlePack;
  532.     }

  533.     /**
  534.      * If {@code true}, packs a single GC pack for all objects reachable from
  535.      * refs/*. Otherwise packs the GC pack with objects reachable from
  536.      * refs/heads/* and refs/tags/*, and a GC_REST pack with the remaining
  537.      * reachable objects. Disabled by default, packing GC and GC_REST.
  538.      *
  539.      * @param single
  540.      *            true to pack a single GC pack rather than GC and GC_REST packs
  541.      * @since 4.9
  542.      */
  543.     public void setSinglePack(boolean single) {
  544.         singlePack = single;
  545.     }

  546.     /**
  547.      * Get the number of objects to try when looking for a delta base.
  548.      *
  549.      * This limit is per thread, if 4 threads are used the actual memory used
  550.      * will be 4 times this value.
  551.      *
  552.      * Default setting: {@value #DEFAULT_DELTA_SEARCH_WINDOW_SIZE}
  553.      *
  554.      * @return the object count to be searched.
  555.      */
  556.     public int getDeltaSearchWindowSize() {
  557.         return deltaSearchWindowSize;
  558.     }

  559.     /**
  560.      * Set the number of objects considered when searching for a delta base.
  561.      *
  562.      * Default setting: {@value #DEFAULT_DELTA_SEARCH_WINDOW_SIZE}
  563.      *
  564.      * @param objectCount
  565.      *            number of objects to search at once. Must be at least 2.
  566.      */
  567.     public void setDeltaSearchWindowSize(int objectCount) {
  568.         if (objectCount <= 2)
  569.             setDeltaCompress(false);
  570.         else
  571.             deltaSearchWindowSize = objectCount;
  572.     }

  573.     /**
  574.      * Get maximum number of bytes to put into the delta search window.
  575.      *
  576.      * Default setting is 0, for an unlimited amount of memory usage. Actual
  577.      * memory used is the lower limit of either this setting, or the sum of
  578.      * space used by at most {@link #getDeltaSearchWindowSize()} objects.
  579.      *
  580.      * This limit is per thread, if 4 threads are used the actual memory limit
  581.      * will be 4 times this value.
  582.      *
  583.      * @return the memory limit.
  584.      */
  585.     public long getDeltaSearchMemoryLimit() {
  586.         return deltaSearchMemoryLimit;
  587.     }

  588.     /**
  589.      * Set the maximum number of bytes to put into the delta search window.
  590.      *
  591.      * Default setting is 0, for an unlimited amount of memory usage. If the
  592.      * memory limit is reached before {@link #getDeltaSearchWindowSize()} the
  593.      * window size is temporarily lowered.
  594.      *
  595.      * @param memoryLimit
  596.      *            Maximum number of bytes to load at once, 0 for unlimited.
  597.      */
  598.     public void setDeltaSearchMemoryLimit(long memoryLimit) {
  599.         deltaSearchMemoryLimit = memoryLimit;
  600.     }

  601.     /**
  602.      * Get the size of the in-memory delta cache.
  603.      *
  604.      * This limit is for the entire writer, even if multiple threads are used.
  605.      *
  606.      * Default setting: {@value #DEFAULT_DELTA_CACHE_SIZE}
  607.      *
  608.      * @return maximum number of bytes worth of delta data to cache in memory.
  609.      *         If 0 the cache is infinite in size (up to the JVM heap limit
  610.      *         anyway). A very tiny size such as 1 indicates the cache is
  611.      *         effectively disabled.
  612.      */
  613.     public long getDeltaCacheSize() {
  614.         return deltaCacheSize;
  615.     }

  616.     /**
  617.      * Set the maximum number of bytes of delta data to cache.
  618.      *
  619.      * During delta search, up to this many bytes worth of small or hard to
  620.      * compute deltas will be stored in memory. This cache speeds up writing by
  621.      * allowing the cached entry to simply be dumped to the output stream.
  622.      *
  623.      * Default setting: {@value #DEFAULT_DELTA_CACHE_SIZE}
  624.      *
  625.      * @param size
  626.      *            number of bytes to cache. Set to 0 to enable an infinite
  627.      *            cache, set to 1 (an impossible size for any delta) to disable
  628.      *            the cache.
  629.      */
  630.     public void setDeltaCacheSize(long size) {
  631.         deltaCacheSize = size;
  632.     }

  633.     /**
  634.      * Maximum size in bytes of a delta to cache.
  635.      *
  636.      * Default setting: {@value #DEFAULT_DELTA_CACHE_LIMIT}
  637.      *
  638.      * @return maximum size (in bytes) of a delta that should be cached.
  639.      */
  640.     public int getDeltaCacheLimit() {
  641.         return deltaCacheLimit;
  642.     }

  643.     /**
  644.      * Set the maximum size of a delta that should be cached.
  645.      *
  646.      * During delta search, any delta smaller than this size will be cached, up
  647.      * to the {@link #getDeltaCacheSize()} maximum limit. This speeds up writing
  648.      * by allowing these cached deltas to be output as-is.
  649.      *
  650.      * Default setting: {@value #DEFAULT_DELTA_CACHE_LIMIT}
  651.      *
  652.      * @param size
  653.      *            maximum size (in bytes) of a delta to be cached.
  654.      */
  655.     public void setDeltaCacheLimit(int size) {
  656.         deltaCacheLimit = size;
  657.     }

  658.     /**
  659.      * Get the maximum file size that will be delta compressed.
  660.      *
  661.      * Files bigger than this setting will not be delta compressed, as they are
  662.      * more than likely already highly compressed binary data files that do not
  663.      * delta compress well, such as MPEG videos.
  664.      *
  665.      * Default setting: {@value #DEFAULT_BIG_FILE_THRESHOLD}
  666.      *
  667.      * @return the configured big file threshold.
  668.      */
  669.     public int getBigFileThreshold() {
  670.         return bigFileThreshold;
  671.     }

  672.     /**
  673.      * Set the maximum file size that should be considered for deltas.
  674.      *
  675.      * Default setting: {@value #DEFAULT_BIG_FILE_THRESHOLD}
  676.      *
  677.      * @param bigFileThreshold
  678.      *            the limit, in bytes.
  679.      */
  680.     public void setBigFileThreshold(int bigFileThreshold) {
  681.         this.bigFileThreshold = bigFileThreshold;
  682.     }

  683.     /**
  684.      * Get whether we wait before opening a newly written pack to prevent its
  685.      * lastModified timestamp could be racy
  686.      *
  687.      * @return whether we wait before opening a newly written pack to prevent
  688.      *         its lastModified timestamp could be racy
  689.      * @since 5.1.8
  690.      */
  691.     public boolean isWaitPreventRacyPack() {
  692.         return waitPreventRacyPack;
  693.     }

  694.     /**
  695.      * Get whether we wait before opening a newly written pack to prevent its
  696.      * lastModified timestamp could be racy. Returns {@code true} if
  697.      * {@code waitToPreventRacyPack = true} and
  698.      * {@code packSize > minSizePreventRacyPack}, {@code false} otherwise.
  699.      *
  700.      * @param packSize
  701.      *            size of the pack file
  702.      *
  703.      * @return whether we wait before opening a newly written pack to prevent
  704.      *         its lastModified timestamp could be racy
  705.      * @since 5.1.8
  706.      */
  707.     public boolean doWaitPreventRacyPack(long packSize) {
  708.         return isWaitPreventRacyPack()
  709.                 && packSize > getMinSizePreventRacyPack();
  710.     }

  711.     /**
  712.      * Set whether we wait before opening a newly written pack to prevent its
  713.      * lastModified timestamp could be racy
  714.      *
  715.      * @param waitPreventRacyPack
  716.      *            whether we wait before opening a newly written pack to prevent
  717.      *            its lastModified timestamp could be racy
  718.      * @since 5.1.8
  719.      */
  720.     public void setWaitPreventRacyPack(boolean waitPreventRacyPack) {
  721.         this.waitPreventRacyPack = waitPreventRacyPack;
  722.     }

  723.     /**
  724.      * Get minimum packfile size for which we wait before opening a newly
  725.      * written pack to prevent its lastModified timestamp could be racy if
  726.      * {@code isWaitToPreventRacyPack} is {@code true}.
  727.      *
  728.      * @return minimum packfile size, default is 100 MiB
  729.      *
  730.      * @since 5.1.8
  731.      */
  732.     public long getMinSizePreventRacyPack() {
  733.         return minSizePreventRacyPack;
  734.     }

  735.     /**
  736.      * Set minimum packfile size for which we wait before opening a newly
  737.      * written pack to prevent its lastModified timestamp could be racy if
  738.      * {@code isWaitToPreventRacyPack} is {@code true}.
  739.      *
  740.      * @param minSizePreventRacyPack
  741.      *            minimum packfile size, default is 100 MiB
  742.      *
  743.      * @since 5.1.8
  744.      */
  745.     public void setMinSizePreventRacyPack(long minSizePreventRacyPack) {
  746.         this.minSizePreventRacyPack = minSizePreventRacyPack;
  747.     }

  748.     /**
  749.      * Get the compression level applied to objects in the pack.
  750.      *
  751.      * Default setting: {@value java.util.zip.Deflater#DEFAULT_COMPRESSION}
  752.      *
  753.      * @return current compression level, see {@link java.util.zip.Deflater}.
  754.      */
  755.     public int getCompressionLevel() {
  756.         return compressionLevel;
  757.     }

  758.     /**
  759.      * Set the compression level applied to objects in the pack.
  760.      *
  761.      * Default setting: {@value java.util.zip.Deflater#DEFAULT_COMPRESSION}
  762.      *
  763.      * @param level
  764.      *            compression level, must be a valid level recognized by the
  765.      *            {@link java.util.zip.Deflater} class.
  766.      */
  767.     public void setCompressionLevel(int level) {
  768.         compressionLevel = level;
  769.     }

  770.     /**
  771.      * Get the number of threads used during delta compression.
  772.      *
  773.      * Default setting: 0 (auto-detect processors)
  774.      *
  775.      * @return number of threads used for delta compression. 0 will auto-detect
  776.      *         the threads to the number of available processors.
  777.      */
  778.     public int getThreads() {
  779.         return threads;
  780.     }

  781.     /**
  782.      * Set the number of threads to use for delta compression.
  783.      *
  784.      * During delta compression, if there are enough objects to be considered
  785.      * the writer will start up concurrent threads and allow them to compress
  786.      * different sections of the repository concurrently.
  787.      *
  788.      * An application thread pool can be set by {@link #setExecutor(Executor)}.
  789.      * If not set a temporary pool will be created by the writer, and torn down
  790.      * automatically when compression is over.
  791.      *
  792.      * Default setting: 0 (auto-detect processors)
  793.      *
  794.      * @param threads
  795.      *            number of threads to use. If &lt;= 0 the number of available
  796.      *            processors for this JVM is used.
  797.      */
  798.     public void setThreads(int threads) {
  799.         this.threads = threads;
  800.     }

  801.     /**
  802.      * Get the preferred thread pool to execute delta search on.
  803.      *
  804.      * @return the preferred thread pool to execute delta search on.
  805.      */
  806.     public Executor getExecutor() {
  807.         return executor;
  808.     }

  809.     /**
  810.      * Set the executor to use when using threads.
  811.      *
  812.      * During delta compression if the executor is non-null jobs will be queued
  813.      * up on it to perform delta compression in parallel. Aside from setting the
  814.      * executor, the caller must set {@link #setThreads(int)} to enable threaded
  815.      * delta search.
  816.      *
  817.      * @param executor
  818.      *            executor to use for threads. Set to null to create a temporary
  819.      *            executor just for the writer.
  820.      */
  821.     public void setExecutor(Executor executor) {
  822.         this.executor = executor;
  823.     }

  824.     /**
  825.      * Get the pack index file format version this instance creates.
  826.      *
  827.      * Default setting: {@value #DEFAULT_INDEX_VERSION}
  828.      *
  829.      * @return the index version, the special version 0 designates the oldest
  830.      *         (most compatible) format available for the objects.
  831.      * @see PackIndexWriter
  832.      */
  833.     public int getIndexVersion() {
  834.         return indexVersion;
  835.     }

  836.     /**
  837.      * Set the pack index file format version this instance will create.
  838.      *
  839.      * Default setting: {@value #DEFAULT_INDEX_VERSION}
  840.      *
  841.      * @param version
  842.      *            the version to write. The special version 0 designates the
  843.      *            oldest (most compatible) format available for the objects.
  844.      * @see PackIndexWriter
  845.      */
  846.     public void setIndexVersion(int version) {
  847.         indexVersion = version;
  848.     }

  849.     /**
  850.      * True if writer is allowed to build bitmaps for indexes.
  851.      *
  852.      * Default setting: {@value #DEFAULT_BUILD_BITMAPS}
  853.      *
  854.      * @return true if delta base is the writer can choose to output an index
  855.      *         with bitmaps.
  856.      * @since 3.0
  857.      */
  858.     public boolean isBuildBitmaps() {
  859.         return buildBitmaps;
  860.     }

  861.     /**
  862.      * Set writer to allow building bitmaps for supported pack files.
  863.      *
  864.      * Index files can include bitmaps to speed up future ObjectWalks.
  865.      *
  866.      * Default setting: {@value #DEFAULT_BUILD_BITMAPS}
  867.      *
  868.      * @param buildBitmaps
  869.      *            boolean indicating whether bitmaps may be included in the
  870.      *            index.
  871.      * @since 3.0
  872.      */
  873.     public void setBuildBitmaps(boolean buildBitmaps) {
  874.         this.buildBitmaps = buildBitmaps;
  875.     }

  876.     /**
  877.      * Get the count of most recent commits for which to build bitmaps.
  878.      *
  879.      * Default setting: {@value #DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT}
  880.      *
  881.      * @return the count of most recent commits for which to build bitmaps
  882.      * @since 4.2
  883.      */
  884.     public int getBitmapContiguousCommitCount() {
  885.         return bitmapContiguousCommitCount;
  886.     }

  887.     /**
  888.      * Set the count of most recent commits for which to build bitmaps.
  889.      *
  890.      * Default setting: {@value #DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT}
  891.      *
  892.      * @param count
  893.      *            the count of most recent commits for which to build bitmaps
  894.      * @since 4.2
  895.      */
  896.     public void setBitmapContiguousCommitCount(int count) {
  897.         bitmapContiguousCommitCount = count;
  898.     }

  899.     /**
  900.      * Get the count at which to switch from "bitmapRecentCommitSpan" to
  901.      * "bitmapDistantCommitSpan".
  902.      *
  903.      * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_COUNT}
  904.      *
  905.      * @return the count for switching between recent and distant spans
  906.      * @since 4.2
  907.      */
  908.     public int getBitmapRecentCommitCount() {
  909.         return bitmapRecentCommitCount;
  910.     }

  911.     /**
  912.      * Set the count at which to switch from "bitmapRecentCommitSpan" to
  913.      * "bitmapDistantCommitSpan".
  914.      *
  915.      * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_COUNT}
  916.      *
  917.      * @param count
  918.      *            the count for switching between recent and distant spans
  919.      * @since 4.2
  920.      */
  921.     public void setBitmapRecentCommitCount(int count) {
  922.         bitmapRecentCommitCount = count;
  923.     }

  924.     /**
  925.      * Get the span of commits when building bitmaps for recent history.
  926.      *
  927.      * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_SPAN}
  928.      *
  929.      * @return the span of commits when building bitmaps for recent history
  930.      * @since 4.2
  931.      */
  932.     public int getBitmapRecentCommitSpan() {
  933.         return bitmapRecentCommitSpan;
  934.     }

  935.     /**
  936.      * Set the span of commits when building bitmaps for recent history.
  937.      *
  938.      * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_SPAN}
  939.      *
  940.      * @param span
  941.      *            the span of commits when building bitmaps for recent history
  942.      * @since 4.2
  943.      */
  944.     public void setBitmapRecentCommitSpan(int span) {
  945.         bitmapRecentCommitSpan = span;
  946.     }

  947.     /**
  948.      * Get the span of commits when building bitmaps for distant history.
  949.      *
  950.      * Default setting: {@value #DEFAULT_BITMAP_DISTANT_COMMIT_SPAN}
  951.      *
  952.      * @return the span of commits when building bitmaps for distant history
  953.      * @since 4.2
  954.      */
  955.     public int getBitmapDistantCommitSpan() {
  956.         return bitmapDistantCommitSpan;
  957.     }

  958.     /**
  959.      * Set the span of commits when building bitmaps for distant history.
  960.      *
  961.      * Default setting: {@value #DEFAULT_BITMAP_DISTANT_COMMIT_SPAN}
  962.      *
  963.      * @param span
  964.      *            the span of commits when building bitmaps for distant history
  965.      * @since 4.2
  966.      */
  967.     public void setBitmapDistantCommitSpan(int span) {
  968.         bitmapDistantCommitSpan = span;
  969.     }

  970.     /**
  971.      * Get the count of branches deemed "excessive". If the count of branches in
  972.      * a repository exceeds this number and bitmaps are enabled, "inactive"
  973.      * branches will have fewer bitmaps than "active" branches.
  974.      *
  975.      * Default setting: {@value #DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT}
  976.      *
  977.      * @return the count of branches deemed "excessive"
  978.      * @since 4.2
  979.      */
  980.     public int getBitmapExcessiveBranchCount() {
  981.         return bitmapExcessiveBranchCount;
  982.     }

  983.     /**
  984.      * Set the count of branches deemed "excessive". If the count of branches in
  985.      * a repository exceeds this number and bitmaps are enabled, "inactive"
  986.      * branches will have fewer bitmaps than "active" branches.
  987.      *
  988.      * Default setting: {@value #DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT}
  989.      *
  990.      * @param count
  991.      *            the count of branches deemed "excessive"
  992.      * @since 4.2
  993.      */
  994.     public void setBitmapExcessiveBranchCount(int count) {
  995.         bitmapExcessiveBranchCount = count;
  996.     }

  997.     /**
  998.      * Get the age in days that marks a branch as "inactive".
  999.      *
  1000.      * Default setting: {@value #DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS}
  1001.      *
  1002.      * @return the age in days that marks a branch as "inactive"
  1003.      * @since 4.2
  1004.      */
  1005.     public int getBitmapInactiveBranchAgeInDays() {
  1006.         return bitmapInactiveBranchAgeInDays;
  1007.     }

  1008.     /**
  1009.      * Get the max time to spend during the search for reuse phase.
  1010.      *
  1011.      * Default setting: {@value #DEFAULT_SEARCH_FOR_REUSE_TIMEOUT}
  1012.      *
  1013.      * @return the maximum time to spend during the search for reuse phase.
  1014.      * @since 5.13
  1015.      */
  1016.     public Duration getSearchForReuseTimeout() {
  1017.         return searchForReuseTimeout;
  1018.     }

  1019.     /**
  1020.      * Set the age in days that marks a branch as "inactive".
  1021.      *
  1022.      * Default setting: {@value #DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS}
  1023.      *
  1024.      * @param ageInDays
  1025.      *            the age in days that marks a branch as "inactive"
  1026.      * @since 4.2
  1027.      */
  1028.     public void setBitmapInactiveBranchAgeInDays(int ageInDays) {
  1029.         bitmapInactiveBranchAgeInDays = ageInDays;
  1030.     }

  1031.     /**
  1032.      * Set the max time to spend during the search for reuse phase.
  1033.      *
  1034.      * @param timeout
  1035.      *            max time allowed during the search for reuse phase
  1036.      *
  1037.      *            Default setting: {@value #DEFAULT_SEARCH_FOR_REUSE_TIMEOUT}
  1038.      * @since 5.13
  1039.      */
  1040.     public void setSearchForReuseTimeout(Duration timeout) {
  1041.         searchForReuseTimeout = timeout;
  1042.     }

  1043.     /**
  1044.      * Update properties by setting fields from the configuration.
  1045.      *
  1046.      * If a property's corresponding variable is not defined in the supplied
  1047.      * configuration, then it is left unmodified.
  1048.      *
  1049.      * @param rc
  1050.      *            configuration to read properties from.
  1051.      */
  1052.     public void fromConfig(Config rc) {
  1053.         setMaxDeltaDepth(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_DEPTH,
  1054.                 getMaxDeltaDepth()));
  1055.         setDeltaSearchWindowSize(rc.getInt(CONFIG_PACK_SECTION,
  1056.                 CONFIG_KEY_WINDOW, getDeltaSearchWindowSize()));
  1057.         setDeltaSearchMemoryLimit(rc.getLong(CONFIG_PACK_SECTION,
  1058.                 CONFIG_KEY_WINDOW_MEMORY, getDeltaSearchMemoryLimit()));
  1059.         setDeltaCacheSize(rc.getLong(CONFIG_PACK_SECTION,
  1060.                 CONFIG_KEY_DELTA_CACHE_SIZE, getDeltaCacheSize()));
  1061.         setDeltaCacheLimit(rc.getInt(CONFIG_PACK_SECTION,
  1062.                 CONFIG_KEY_DELTA_CACHE_LIMIT, getDeltaCacheLimit()));
  1063.         setCompressionLevel(rc.getInt(CONFIG_PACK_SECTION,
  1064.                 CONFIG_KEY_COMPRESSION, rc.getInt(CONFIG_CORE_SECTION,
  1065.                         CONFIG_KEY_COMPRESSION, getCompressionLevel())));
  1066.         setIndexVersion(rc.getInt(CONFIG_PACK_SECTION,
  1067.                 CONFIG_KEY_INDEXVERSION,
  1068.                 getIndexVersion()));
  1069.         setBigFileThreshold(rc.getInt(CONFIG_CORE_SECTION,
  1070.                 CONFIG_KEY_BIGFILE_THRESHOLD, getBigFileThreshold()));
  1071.         setThreads(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_THREADS,
  1072.                 getThreads()));

  1073.         // These variables aren't standardized
  1074.         setReuseDeltas(rc.getBoolean(CONFIG_PACK_SECTION,
  1075.                 CONFIG_KEY_REUSE_DELTAS, isReuseDeltas()));
  1076.         setReuseObjects(rc.getBoolean(CONFIG_PACK_SECTION,
  1077.                 CONFIG_KEY_REUSE_OBJECTS, isReuseObjects()));
  1078.         setDeltaCompress(rc.getBoolean(CONFIG_PACK_SECTION,
  1079.                 CONFIG_KEY_DELTA_COMPRESSION, isDeltaCompress()));
  1080.         setCutDeltaChains(rc.getBoolean(CONFIG_PACK_SECTION,
  1081.                 CONFIG_KEY_CUT_DELTACHAINS, getCutDeltaChains()));
  1082.         setSinglePack(rc.getBoolean(CONFIG_PACK_SECTION,
  1083.                 CONFIG_KEY_SINGLE_PACK,
  1084.                 getSinglePack()));
  1085.         setBuildBitmaps(rc.getBoolean(CONFIG_PACK_SECTION,
  1086.                 CONFIG_KEY_BUILD_BITMAPS, isBuildBitmaps()));
  1087.         setBitmapContiguousCommitCount(rc.getInt(CONFIG_PACK_SECTION,
  1088.                 CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT,
  1089.                 getBitmapContiguousCommitCount()));
  1090.         setBitmapRecentCommitCount(rc.getInt(CONFIG_PACK_SECTION,
  1091.                 CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT,
  1092.                 getBitmapRecentCommitCount()));
  1093.         setBitmapRecentCommitSpan(rc.getInt(CONFIG_PACK_SECTION,
  1094.                 CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT,
  1095.                 getBitmapRecentCommitSpan()));
  1096.         setBitmapDistantCommitSpan(rc.getInt(CONFIG_PACK_SECTION,
  1097.                 CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN,
  1098.                 getBitmapDistantCommitSpan()));
  1099.         setBitmapExcessiveBranchCount(rc.getInt(CONFIG_PACK_SECTION,
  1100.                 CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT,
  1101.                 getBitmapExcessiveBranchCount()));
  1102.         setBitmapInactiveBranchAgeInDays(rc.getInt(CONFIG_PACK_SECTION,
  1103.                 CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS,
  1104.                 getBitmapInactiveBranchAgeInDays()));
  1105.         setSearchForReuseTimeout(Duration.ofSeconds(rc.getTimeUnit(
  1106.                 CONFIG_PACK_SECTION, null,
  1107.                 CONFIG_KEY_SEARCH_FOR_REUSE_TIMEOUT,
  1108.                 getSearchForReuseTimeout().getSeconds(), TimeUnit.SECONDS)));
  1109.         setWaitPreventRacyPack(rc.getBoolean(CONFIG_PACK_SECTION,
  1110.                 CONFIG_KEY_WAIT_PREVENT_RACYPACK, isWaitPreventRacyPack()));
  1111.         setMinSizePreventRacyPack(rc.getLong(CONFIG_PACK_SECTION,
  1112.                 CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK,
  1113.                 getMinSizePreventRacyPack()));
  1114.     }

  1115.     /** {@inheritDoc} */
  1116.     @Override
  1117.     public String toString() {
  1118.         final StringBuilder b = new StringBuilder();
  1119.         b.append("maxDeltaDepth=").append(getMaxDeltaDepth()); //$NON-NLS-1$
  1120.         b.append(", deltaSearchWindowSize=").append(getDeltaSearchWindowSize()); //$NON-NLS-1$
  1121.         b.append(", deltaSearchMemoryLimit=") //$NON-NLS-1$
  1122.                 .append(getDeltaSearchMemoryLimit());
  1123.         b.append(", deltaCacheSize=").append(getDeltaCacheSize()); //$NON-NLS-1$
  1124.         b.append(", deltaCacheLimit=").append(getDeltaCacheLimit()); //$NON-NLS-1$
  1125.         b.append(", compressionLevel=").append(getCompressionLevel()); //$NON-NLS-1$
  1126.         b.append(", indexVersion=").append(getIndexVersion()); //$NON-NLS-1$
  1127.         b.append(", bigFileThreshold=").append(getBigFileThreshold()); //$NON-NLS-1$
  1128.         b.append(", threads=").append(getThreads()); //$NON-NLS-1$
  1129.         b.append(", reuseDeltas=").append(isReuseDeltas()); //$NON-NLS-1$
  1130.         b.append(", reuseObjects=").append(isReuseObjects()); //$NON-NLS-1$
  1131.         b.append(", deltaCompress=").append(isDeltaCompress()); //$NON-NLS-1$
  1132.         b.append(", buildBitmaps=").append(isBuildBitmaps()); //$NON-NLS-1$
  1133.         b.append(", bitmapContiguousCommitCount=") //$NON-NLS-1$
  1134.                 .append(getBitmapContiguousCommitCount());
  1135.         b.append(", bitmapRecentCommitCount=") //$NON-NLS-1$
  1136.                 .append(getBitmapRecentCommitCount());
  1137.         b.append(", bitmapRecentCommitSpan=") //$NON-NLS-1$
  1138.                 .append(getBitmapRecentCommitSpan());
  1139.         b.append(", bitmapDistantCommitSpan=") //$NON-NLS-1$
  1140.                 .append(getBitmapDistantCommitSpan());
  1141.         b.append(", bitmapExcessiveBranchCount=") //$NON-NLS-1$
  1142.                 .append(getBitmapExcessiveBranchCount());
  1143.         b.append(", bitmapInactiveBranchAge=") //$NON-NLS-1$
  1144.                 .append(getBitmapInactiveBranchAgeInDays());
  1145.         b.append(", searchForReuseTimeout") //$NON-NLS-1$
  1146.                 .append(getSearchForReuseTimeout());
  1147.         b.append(", singlePack=").append(getSinglePack()); //$NON-NLS-1$
  1148.         return b.toString();
  1149.     }
  1150. }