View Javadoc
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  
12  package org.eclipse.jgit.storage.pack;
13  
14  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
15  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BIGFILE_THRESHOLD;
16  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT;
17  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN;
18  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT;
19  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS;
20  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT;
21  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BUILD_BITMAPS;
22  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_COMPRESSION;
23  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_CUT_DELTACHAINS;
24  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_CACHE_LIMIT;
25  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_CACHE_SIZE;
26  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_COMPRESSION;
27  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DEPTH;
28  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_INDEXVERSION;
29  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK;
30  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REUSE_DELTAS;
31  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REUSE_OBJECTS;
32  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_SEARCH_FOR_REUSE_TIMEOUT;
33  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_SINGLE_PACK;
34  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_THREADS;
35  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WAIT_PREVENT_RACYPACK;
36  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW;
37  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_WINDOW_MEMORY;
38  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
39  
40  import java.time.Duration;
41  import java.util.concurrent.Executor;
42  import java.util.concurrent.TimeUnit;
43  import java.util.zip.Deflater;
44  
45  import org.eclipse.jgit.internal.storage.file.PackIndexWriter;
46  import org.eclipse.jgit.lib.Config;
47  import org.eclipse.jgit.lib.Repository;
48  
49  /**
50   * Configuration used by a pack writer when constructing the stream.
51   *
52   * A configuration may be modified once created, but should not be modified
53   * while it is being used by a PackWriter. If a configuration is not modified it
54   * is safe to share the same configuration instance between multiple concurrent
55   * threads executing different PackWriters.
56   */
57  public class PackConfig {
58  	/**
59  	 * Default value of deltas reuse option: {@value}
60  	 *
61  	 * @see #setReuseDeltas(boolean)
62  	 */
63  	public static final boolean DEFAULT_REUSE_DELTAS = true;
64  
65  	/**
66  	 * Default value of objects reuse option: {@value}
67  	 *
68  	 * @see #setReuseObjects(boolean)
69  	 */
70  	public static final boolean DEFAULT_REUSE_OBJECTS = true;
71  
72  	/**
73  	 * Default value of keep old packs option: {@value}
74  	 * @see #setPreserveOldPacks(boolean)
75  	 * @since 4.7
76  	 */
77  	public static final boolean DEFAULT_PRESERVE_OLD_PACKS = false;
78  
79  	/**
80  	 * Default value of prune old packs option: {@value}
81  	 * @see #setPrunePreserved(boolean)
82  	 * @since 4.7
83  	 */
84  	public static final boolean DEFAULT_PRUNE_PRESERVED = false;
85  
86  	/**
87  	 * Default value of delta compress option: {@value}
88  	 *
89  	 * @see #setDeltaCompress(boolean)
90  	 */
91  	public static final boolean DEFAULT_DELTA_COMPRESS = true;
92  
93  	/**
94  	 * Default value of delta base as offset option: {@value}
95  	 *
96  	 * @see #setDeltaBaseAsOffset(boolean)
97  	 */
98  	public static final boolean DEFAULT_DELTA_BASE_AS_OFFSET = false;
99  
100 	/**
101 	 * Default value of maximum delta chain depth: {@value}
102 	 *
103 	 * @see #setMaxDeltaDepth(int)
104 	 */
105 	public static final int DEFAULT_MAX_DELTA_DEPTH = 50;
106 
107 	/**
108 	 * Default window size during packing: {@value}
109 	 *
110 	 * @see #setDeltaSearchWindowSize(int)
111 	 */
112 	public static final int DEFAULT_DELTA_SEARCH_WINDOW_SIZE = 10;
113 
114 	private static final int MB = 1 << 20;
115 
116 	/**
117 	 * Default big file threshold: {@value}
118 	 *
119 	 * @see #setBigFileThreshold(int)
120 	 */
121 	public static final int DEFAULT_BIG_FILE_THRESHOLD = 50 * MB;
122 
123 	/**
124 	 * Default if we wait before opening a newly written pack to prevent its
125 	 * lastModified timestamp could be racy
126 	 *
127 	 * @since 5.1.8
128 	 */
129 	public static final boolean DEFAULT_WAIT_PREVENT_RACY_PACK = false;
130 
131 	/**
132 	 * Default if we wait before opening a newly written pack to prevent its
133 	 * lastModified timestamp could be racy
134 	 *
135 	 * @since 5.1.8
136 	 */
137 	public static final long DEFAULT_MINSIZE_PREVENT_RACY_PACK = 100 * MB;
138 
139 	/**
140 	 * Default delta cache size: {@value}
141 	 *
142 	 * @see #setDeltaCacheSize(long)
143 	 */
144 	public static final long DEFAULT_DELTA_CACHE_SIZE = 50 * 1024 * 1024;
145 
146 	/**
147 	 * Default delta cache limit: {@value}
148 	 *
149 	 * @see #setDeltaCacheLimit(int)
150 	 */
151 	public static final int DEFAULT_DELTA_CACHE_LIMIT = 100;
152 
153 	/**
154 	 * Default index version: {@value}
155 	 *
156 	 * @see #setIndexVersion(int)
157 	 */
158 	public static final int DEFAULT_INDEX_VERSION = 2;
159 
160 	/**
161 	 * Default value of the build bitmaps option: {@value}
162 	 *
163 	 * @see #setBuildBitmaps(boolean)
164 	 * @since 3.0
165 	 */
166 	public static final boolean DEFAULT_BUILD_BITMAPS = true;
167 
168 	/**
169 	 * Default count of most recent commits to select for bitmaps. Only applies
170 	 * when bitmaps are enabled: {@value}
171 	 *
172 	 * @see #setBitmapContiguousCommitCount(int)
173 	 * @since 4.2
174 	 */
175 	public static final int DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT = 100;
176 
177 	/**
178 	 * Count at which the span between selected commits changes from
179 	 * "bitmapRecentCommitSpan" to "bitmapDistantCommitSpan". Only applies when
180 	 * bitmaps are enabled: {@value}
181 	 *
182 	 * @see #setBitmapRecentCommitCount(int)
183 	 * @since 4.2
184 	 */
185 	public static final int DEFAULT_BITMAP_RECENT_COMMIT_COUNT = 20000;
186 
187 	/**
188 	 * Default spacing between commits in recent history when selecting commits
189 	 * for bitmaps. Only applies when bitmaps are enabled: {@value}
190 	 *
191 	 * @see #setBitmapRecentCommitSpan(int)
192 	 * @since 4.2
193 	 */
194 	public static final int DEFAULT_BITMAP_RECENT_COMMIT_SPAN = 100;
195 
196 	/**
197 	 * Default spacing between commits in distant history when selecting commits
198 	 * for bitmaps. Only applies when bitmaps are enabled: {@value}
199 	 *
200 	 * @see #setBitmapDistantCommitSpan(int)
201 	 * @since 4.2
202 	 */
203 	public static final int DEFAULT_BITMAP_DISTANT_COMMIT_SPAN = 5000;
204 
205 	/**
206 	 * Default count of branches required to activate inactive branch commit
207 	 * selection. If the number of branches is less than this then bitmaps for
208 	 * the entire commit history of all branches will be created, otherwise
209 	 * branches marked as "inactive" will have coverage for only partial
210 	 * history: {@value}
211 	 *
212 	 * @see #setBitmapExcessiveBranchCount(int)
213 	 * @since 4.2
214 	 */
215 	public static final int DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT = 100;
216 
217 	/**
218 	 * Default age at which a branch is considered inactive. Age is taken as the
219 	 * number of days ago that the most recent commit was made to a branch. Only
220 	 * affects bitmap processing if bitmaps are enabled and the
221 	 * "excessive branch count" has been exceeded: {@value}
222 	 *
223 	 * @see #setBitmapInactiveBranchAgeInDays(int)
224 	 * @since 4.2
225 	 */
226 	public static final int DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS = 90;
227 
228 	/**
229 	 * Default max time to spend during the search for reuse phase. This
230 	 * optimization is disabled by default: {@value}
231 	 *
232 	 * @see #setSearchForReuseTimeout(Duration)
233 	 * @since 5.13
234 	 */
235 	public static final Duration DEFAULT_SEARCH_FOR_REUSE_TIMEOUT = Duration
236 			.ofSeconds(Integer.MAX_VALUE);
237 
238 	private int compressionLevel = Deflater.DEFAULT_COMPRESSION;
239 
240 	private boolean reuseDeltas = DEFAULT_REUSE_DELTAS;
241 
242 	private boolean reuseObjects = DEFAULT_REUSE_OBJECTS;
243 
244 	private boolean preserveOldPacks = DEFAULT_PRESERVE_OLD_PACKS;
245 
246 	private boolean prunePreserved = DEFAULT_PRUNE_PRESERVED;
247 
248 	private boolean deltaBaseAsOffset = DEFAULT_DELTA_BASE_AS_OFFSET;
249 
250 	private boolean deltaCompress = DEFAULT_DELTA_COMPRESS;
251 
252 	private int maxDeltaDepth = DEFAULT_MAX_DELTA_DEPTH;
253 
254 	private int deltaSearchWindowSize = DEFAULT_DELTA_SEARCH_WINDOW_SIZE;
255 
256 	private long deltaSearchMemoryLimit;
257 
258 	private long deltaCacheSize = DEFAULT_DELTA_CACHE_SIZE;
259 
260 	private int deltaCacheLimit = DEFAULT_DELTA_CACHE_LIMIT;
261 
262 	private int bigFileThreshold = DEFAULT_BIG_FILE_THRESHOLD;
263 
264 	private boolean waitPreventRacyPack = DEFAULT_WAIT_PREVENT_RACY_PACK;
265 
266 	private long minSizePreventRacyPack = DEFAULT_MINSIZE_PREVENT_RACY_PACK;
267 
268 	private int threads;
269 
270 	private Executor executor;
271 
272 	private int indexVersion = DEFAULT_INDEX_VERSION;
273 
274 	private boolean buildBitmaps = DEFAULT_BUILD_BITMAPS;
275 
276 	private int bitmapContiguousCommitCount = DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT;
277 
278 	private int bitmapRecentCommitCount = DEFAULT_BITMAP_RECENT_COMMIT_COUNT;
279 
280 	private int bitmapRecentCommitSpan = DEFAULT_BITMAP_RECENT_COMMIT_SPAN;
281 
282 	private int bitmapDistantCommitSpan = DEFAULT_BITMAP_DISTANT_COMMIT_SPAN;
283 
284 	private int bitmapExcessiveBranchCount = DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT;
285 
286 	private int bitmapInactiveBranchAgeInDays = DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS;
287 
288 	private Duration searchForReuseTimeout = DEFAULT_SEARCH_FOR_REUSE_TIMEOUT;
289 
290 	private boolean cutDeltaChains;
291 
292 	private boolean singlePack;
293 
294 	/**
295 	 * Create a default configuration.
296 	 */
297 	public PackConfig() {
298 		// Fields are initialized to defaults.
299 	}
300 
301 	/**
302 	 * Create a configuration honoring the repository's settings.
303 	 *
304 	 * @param db
305 	 *            the repository to read settings from. The repository is not
306 	 *            retained by the new configuration, instead its settings are
307 	 *            copied during the constructor.
308 	 */
309 	public PackConfig(Repository db) {
310 		fromConfig(db.getConfig());
311 	}
312 
313 	/**
314 	 * Create a configuration honoring settings in a
315 	 * {@link org.eclipse.jgit.lib.Config}.
316 	 *
317 	 * @param cfg
318 	 *            the source to read settings from. The source is not retained
319 	 *            by the new configuration, instead its settings are copied
320 	 *            during the constructor.
321 	 */
322 	public PackConfig(Config cfg) {
323 		fromConfig(cfg);
324 	}
325 
326 	/**
327 	 * Copy an existing configuration to a new instance.
328 	 *
329 	 * @param cfg
330 	 *            the source configuration to copy from.
331 	 */
332 	public PackConfig(PackConfig cfg) {
333 		this.compressionLevel = cfg.compressionLevel;
334 		this.reuseDeltas = cfg.reuseDeltas;
335 		this.reuseObjects = cfg.reuseObjects;
336 		this.preserveOldPacks = cfg.preserveOldPacks;
337 		this.prunePreserved = cfg.prunePreserved;
338 		this.deltaBaseAsOffset = cfg.deltaBaseAsOffset;
339 		this.deltaCompress = cfg.deltaCompress;
340 		this.maxDeltaDepth = cfg.maxDeltaDepth;
341 		this.deltaSearchWindowSize = cfg.deltaSearchWindowSize;
342 		this.deltaSearchMemoryLimit = cfg.deltaSearchMemoryLimit;
343 		this.deltaCacheSize = cfg.deltaCacheSize;
344 		this.deltaCacheLimit = cfg.deltaCacheLimit;
345 		this.bigFileThreshold = cfg.bigFileThreshold;
346 		this.waitPreventRacyPack = cfg.waitPreventRacyPack;
347 		this.minSizePreventRacyPack = cfg.minSizePreventRacyPack;
348 		this.threads = cfg.threads;
349 		this.executor = cfg.executor;
350 		this.indexVersion = cfg.indexVersion;
351 		this.buildBitmaps = cfg.buildBitmaps;
352 		this.bitmapContiguousCommitCount = cfg.bitmapContiguousCommitCount;
353 		this.bitmapRecentCommitCount = cfg.bitmapRecentCommitCount;
354 		this.bitmapRecentCommitSpan = cfg.bitmapRecentCommitSpan;
355 		this.bitmapDistantCommitSpan = cfg.bitmapDistantCommitSpan;
356 		this.bitmapExcessiveBranchCount = cfg.bitmapExcessiveBranchCount;
357 		this.bitmapInactiveBranchAgeInDays = cfg.bitmapInactiveBranchAgeInDays;
358 		this.cutDeltaChains = cfg.cutDeltaChains;
359 		this.singlePack = cfg.singlePack;
360 		this.searchForReuseTimeout = cfg.searchForReuseTimeout;
361 	}
362 
363 	/**
364 	 * Check whether to reuse deltas existing in repository.
365 	 *
366 	 * Default setting: {@value #DEFAULT_REUSE_DELTAS}
367 	 *
368 	 * @return true if object is configured to reuse deltas; false otherwise.
369 	 */
370 	public boolean isReuseDeltas() {
371 		return reuseDeltas;
372 	}
373 
374 	/**
375 	 * Set reuse deltas configuration option for the writer.
376 	 *
377 	 * When enabled, writer will search for delta representation of object in
378 	 * repository and use it if possible. Normally, only deltas with base to
379 	 * another object existing in set of objects to pack will be used. The
380 	 * exception however is thin-packs where the base object may exist on the
381 	 * other side.
382 	 *
383 	 * When raw delta data is directly copied from a pack file, its checksum is
384 	 * computed to verify the data is not corrupt.
385 	 *
386 	 * Default setting: {@value #DEFAULT_REUSE_DELTAS}
387 	 *
388 	 * @param reuseDeltas
389 	 *            boolean indicating whether or not try to reuse deltas.
390 	 */
391 	public void setReuseDeltas(boolean reuseDeltas) {
392 		this.reuseDeltas = reuseDeltas;
393 	}
394 
395 	/**
396 	 * Checks whether to reuse existing objects representation in repository.
397 	 *
398 	 * Default setting: {@value #DEFAULT_REUSE_OBJECTS}
399 	 *
400 	 * @return true if writer is configured to reuse objects representation from
401 	 *         pack; false otherwise.
402 	 */
403 	public boolean isReuseObjects() {
404 		return reuseObjects;
405 	}
406 
407 	/**
408 	 * Set reuse objects configuration option for the writer.
409 	 *
410 	 * If enabled, writer searches for compressed representation in a pack file.
411 	 * If possible, compressed data is directly copied from such a pack file.
412 	 * Data checksum is verified.
413 	 *
414 	 * Default setting: {@value #DEFAULT_REUSE_OBJECTS}
415 	 *
416 	 * @param reuseObjects
417 	 *            boolean indicating whether or not writer should reuse existing
418 	 *            objects representation.
419 	 */
420 	public void setReuseObjects(boolean reuseObjects) {
421 		this.reuseObjects = reuseObjects;
422 	}
423 
424 	/**
425 	 * Checks whether to preserve old packs in a preserved directory
426 	 *
427 	 * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
428 	 *
429 	 * @return true if repacking will preserve old pack files.
430 	 * @since 4.7
431 	 */
432 	public boolean isPreserveOldPacks() {
433 		return preserveOldPacks;
434 	}
435 
436 	/**
437 	 * Set preserve old packs configuration option for repacking.
438 	 *
439 	 * If enabled, old pack files are moved into a preserved subdirectory instead
440 	 * of being deleted
441 	 *
442 	 * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
443 	 *
444 	 * @param preserveOldPacks
445 	 *            boolean indicating whether or not preserve old pack files
446 	 * @since 4.7
447 	 */
448 	public void setPreserveOldPacks(boolean preserveOldPacks) {
449 		this.preserveOldPacks = preserveOldPacks;
450 	}
451 
452 	/**
453 	 * Checks whether to remove preserved pack files in a preserved directory
454 	 *
455 	 * Default setting: {@value #DEFAULT_PRUNE_PRESERVED}
456 	 *
457 	 * @return true if repacking will remove preserved pack files.
458 	 * @since 4.7
459 	 */
460 	public boolean isPrunePreserved() {
461 		return prunePreserved;
462 	}
463 
464 	/**
465 	 * Set prune preserved configuration option for repacking.
466 	 *
467 	 * If enabled, preserved pack files are removed from a preserved subdirectory
468 	 *
469 	 * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS}
470 	 *
471 	 * @param prunePreserved
472 	 *            boolean indicating whether or not preserve old pack files
473 	 * @since 4.7
474 	 */
475 	public void setPrunePreserved(boolean prunePreserved) {
476 		this.prunePreserved = prunePreserved;
477 	}
478 
479 	/**
480 	 * True if writer can use offsets to point to a delta base.
481 	 *
482 	 * If true the writer may choose to use an offset to point to a delta base
483 	 * in the same pack, this is a newer style of reference that saves space.
484 	 * False if the writer has to use the older (and more compatible style) of
485 	 * storing the full ObjectId of the delta base.
486 	 *
487 	 * Default setting: {@value #DEFAULT_DELTA_BASE_AS_OFFSET}
488 	 *
489 	 * @return true if delta base is stored as an offset; false if it is stored
490 	 *         as an ObjectId.
491 	 */
492 	public boolean isDeltaBaseAsOffset() {
493 		return deltaBaseAsOffset;
494 	}
495 
496 	/**
497 	 * Set writer delta base format.
498 	 *
499 	 * Delta base can be written as an offset in a pack file (new approach
500 	 * reducing file size) or as an object id (legacy approach, compatible with
501 	 * old readers).
502 	 *
503 	 * Default setting: {@value #DEFAULT_DELTA_BASE_AS_OFFSET}
504 	 *
505 	 * @param deltaBaseAsOffset
506 	 *            boolean indicating whether delta base can be stored as an
507 	 *            offset.
508 	 */
509 	public void setDeltaBaseAsOffset(boolean deltaBaseAsOffset) {
510 		this.deltaBaseAsOffset = deltaBaseAsOffset;
511 	}
512 
513 	/**
514 	 * Check whether the writer will create new deltas on the fly.
515 	 *
516 	 * Default setting: {@value #DEFAULT_DELTA_COMPRESS}
517 	 *
518 	 * @return true if the writer will create a new delta when either
519 	 *         {@link #isReuseDeltas()} is false, or no suitable delta is
520 	 *         available for reuse.
521 	 */
522 	public boolean isDeltaCompress() {
523 		return deltaCompress;
524 	}
525 
526 	/**
527 	 * Set whether or not the writer will create new deltas on the fly.
528 	 *
529 	 * Default setting: {@value #DEFAULT_DELTA_COMPRESS}
530 	 *
531 	 * @param deltaCompress
532 	 *            true to create deltas when {@link #isReuseDeltas()} is false,
533 	 *            or when a suitable delta isn't available for reuse. Set to
534 	 *            false to write whole objects instead.
535 	 */
536 	public void setDeltaCompress(boolean deltaCompress) {
537 		this.deltaCompress = deltaCompress;
538 	}
539 
540 	/**
541 	 * Get maximum depth of delta chain set up for the writer.
542 	 *
543 	 * Generated chains are not longer than this value.
544 	 *
545 	 * Default setting: {@value #DEFAULT_MAX_DELTA_DEPTH}
546 	 *
547 	 * @return maximum delta chain depth.
548 	 */
549 	public int getMaxDeltaDepth() {
550 		return maxDeltaDepth;
551 	}
552 
553 	/**
554 	 * Set up maximum depth of delta chain for the writer.
555 	 *
556 	 * Generated chains are not longer than this value. Too low value causes low
557 	 * compression level, while too big makes unpacking (reading) longer.
558 	 *
559 	 * Default setting: {@value #DEFAULT_MAX_DELTA_DEPTH}
560 	 *
561 	 * @param maxDeltaDepth
562 	 *            maximum delta chain depth.
563 	 */
564 	public void setMaxDeltaDepth(int maxDeltaDepth) {
565 		this.maxDeltaDepth = maxDeltaDepth;
566 	}
567 
568 	/**
569 	 * Whether existing delta chains should be cut at
570 	 * {@link #getMaxDeltaDepth()}.
571 	 *
572 	 * @return true if existing delta chains should be cut at
573 	 *         {@link #getMaxDeltaDepth()}. Default is false, allowing existing
574 	 *         chains to be of any length.
575 	 * @since 3.0
576 	 */
577 	public boolean getCutDeltaChains() {
578 		return cutDeltaChains;
579 	}
580 
581 	/**
582 	 * Enable cutting existing delta chains at {@link #getMaxDeltaDepth()}.
583 	 *
584 	 * By default this is disabled and existing chains are kept at whatever
585 	 * length a prior packer was configured to create. This allows objects to be
586 	 * packed one with a large depth (for example 250), and later to quickly
587 	 * repack the repository with a shorter depth (such as 50), but reusing the
588 	 * complete delta chains created by the earlier 250 depth.
589 	 *
590 	 * @param cut
591 	 *            true to cut existing chains.
592 	 * @since 3.0
593 	 */
594 	public void setCutDeltaChains(boolean cut) {
595 		cutDeltaChains = cut;
596 	}
597 
598 	/**
599 	 * Whether all of refs/* should be packed in a single pack.
600 	 *
601 	 * @return true if all of refs/* should be packed in a single pack. Default
602 	 *         is false, packing a separate GC_REST pack for references outside
603 	 *         of refs/heads/* and refs/tags/*.
604 	 * @since 4.9
605 	 */
606 	public boolean getSinglePack() {
607 		return singlePack;
608 	}
609 
610 	/**
611 	 * If {@code true}, packs a single GC pack for all objects reachable from
612 	 * refs/*. Otherwise packs the GC pack with objects reachable from
613 	 * refs/heads/* and refs/tags/*, and a GC_REST pack with the remaining
614 	 * reachable objects. Disabled by default, packing GC and GC_REST.
615 	 *
616 	 * @param single
617 	 *            true to pack a single GC pack rather than GC and GC_REST packs
618 	 * @since 4.9
619 	 */
620 	public void setSinglePack(boolean single) {
621 		singlePack = single;
622 	}
623 
624 	/**
625 	 * Get the number of objects to try when looking for a delta base.
626 	 *
627 	 * This limit is per thread, if 4 threads are used the actual memory used
628 	 * will be 4 times this value.
629 	 *
630 	 * Default setting: {@value #DEFAULT_DELTA_SEARCH_WINDOW_SIZE}
631 	 *
632 	 * @return the object count to be searched.
633 	 */
634 	public int getDeltaSearchWindowSize() {
635 		return deltaSearchWindowSize;
636 	}
637 
638 	/**
639 	 * Set the number of objects considered when searching for a delta base.
640 	 *
641 	 * Default setting: {@value #DEFAULT_DELTA_SEARCH_WINDOW_SIZE}
642 	 *
643 	 * @param objectCount
644 	 *            number of objects to search at once. Must be at least 2.
645 	 */
646 	public void setDeltaSearchWindowSize(int objectCount) {
647 		if (objectCount <= 2)
648 			setDeltaCompress(false);
649 		else
650 			deltaSearchWindowSize = objectCount;
651 	}
652 
653 	/**
654 	 * Get maximum number of bytes to put into the delta search window.
655 	 *
656 	 * Default setting is 0, for an unlimited amount of memory usage. Actual
657 	 * memory used is the lower limit of either this setting, or the sum of
658 	 * space used by at most {@link #getDeltaSearchWindowSize()} objects.
659 	 *
660 	 * This limit is per thread, if 4 threads are used the actual memory limit
661 	 * will be 4 times this value.
662 	 *
663 	 * @return the memory limit.
664 	 */
665 	public long getDeltaSearchMemoryLimit() {
666 		return deltaSearchMemoryLimit;
667 	}
668 
669 	/**
670 	 * Set the maximum number of bytes to put into the delta search window.
671 	 *
672 	 * Default setting is 0, for an unlimited amount of memory usage. If the
673 	 * memory limit is reached before {@link #getDeltaSearchWindowSize()} the
674 	 * window size is temporarily lowered.
675 	 *
676 	 * @param memoryLimit
677 	 *            Maximum number of bytes to load at once, 0 for unlimited.
678 	 */
679 	public void setDeltaSearchMemoryLimit(long memoryLimit) {
680 		deltaSearchMemoryLimit = memoryLimit;
681 	}
682 
683 	/**
684 	 * Get the size of the in-memory delta cache.
685 	 *
686 	 * This limit is for the entire writer, even if multiple threads are used.
687 	 *
688 	 * Default setting: {@value #DEFAULT_DELTA_CACHE_SIZE}
689 	 *
690 	 * @return maximum number of bytes worth of delta data to cache in memory.
691 	 *         If 0 the cache is infinite in size (up to the JVM heap limit
692 	 *         anyway). A very tiny size such as 1 indicates the cache is
693 	 *         effectively disabled.
694 	 */
695 	public long getDeltaCacheSize() {
696 		return deltaCacheSize;
697 	}
698 
699 	/**
700 	 * Set the maximum number of bytes of delta data to cache.
701 	 *
702 	 * During delta search, up to this many bytes worth of small or hard to
703 	 * compute deltas will be stored in memory. This cache speeds up writing by
704 	 * allowing the cached entry to simply be dumped to the output stream.
705 	 *
706 	 * Default setting: {@value #DEFAULT_DELTA_CACHE_SIZE}
707 	 *
708 	 * @param size
709 	 *            number of bytes to cache. Set to 0 to enable an infinite
710 	 *            cache, set to 1 (an impossible size for any delta) to disable
711 	 *            the cache.
712 	 */
713 	public void setDeltaCacheSize(long size) {
714 		deltaCacheSize = size;
715 	}
716 
717 	/**
718 	 * Maximum size in bytes of a delta to cache.
719 	 *
720 	 * Default setting: {@value #DEFAULT_DELTA_CACHE_LIMIT}
721 	 *
722 	 * @return maximum size (in bytes) of a delta that should be cached.
723 	 */
724 	public int getDeltaCacheLimit() {
725 		return deltaCacheLimit;
726 	}
727 
728 	/**
729 	 * Set the maximum size of a delta that should be cached.
730 	 *
731 	 * During delta search, any delta smaller than this size will be cached, up
732 	 * to the {@link #getDeltaCacheSize()} maximum limit. This speeds up writing
733 	 * by allowing these cached deltas to be output as-is.
734 	 *
735 	 * Default setting: {@value #DEFAULT_DELTA_CACHE_LIMIT}
736 	 *
737 	 * @param size
738 	 *            maximum size (in bytes) of a delta to be cached.
739 	 */
740 	public void setDeltaCacheLimit(int size) {
741 		deltaCacheLimit = size;
742 	}
743 
744 	/**
745 	 * Get the maximum file size that will be delta compressed.
746 	 *
747 	 * Files bigger than this setting will not be delta compressed, as they are
748 	 * more than likely already highly compressed binary data files that do not
749 	 * delta compress well, such as MPEG videos.
750 	 *
751 	 * Default setting: {@value #DEFAULT_BIG_FILE_THRESHOLD}
752 	 *
753 	 * @return the configured big file threshold.
754 	 */
755 	public int getBigFileThreshold() {
756 		return bigFileThreshold;
757 	}
758 
759 	/**
760 	 * Set the maximum file size that should be considered for deltas.
761 	 *
762 	 * Default setting: {@value #DEFAULT_BIG_FILE_THRESHOLD}
763 	 *
764 	 * @param bigFileThreshold
765 	 *            the limit, in bytes.
766 	 */
767 	public void setBigFileThreshold(int bigFileThreshold) {
768 		this.bigFileThreshold = bigFileThreshold;
769 	}
770 
771 	/**
772 	 * Get whether we wait before opening a newly written pack to prevent its
773 	 * lastModified timestamp could be racy
774 	 *
775 	 * @return whether we wait before opening a newly written pack to prevent
776 	 *         its lastModified timestamp could be racy
777 	 * @since 5.1.8
778 	 */
779 	public boolean isWaitPreventRacyPack() {
780 		return waitPreventRacyPack;
781 	}
782 
783 	/**
784 	 * Get whether we wait before opening a newly written pack to prevent its
785 	 * lastModified timestamp could be racy. Returns {@code true} if
786 	 * {@code waitToPreventRacyPack = true} and
787 	 * {@code packSize > minSizePreventRacyPack}, {@code false} otherwise.
788 	 *
789 	 * @param packSize
790 	 *            size of the pack file
791 	 *
792 	 * @return whether we wait before opening a newly written pack to prevent
793 	 *         its lastModified timestamp could be racy
794 	 * @since 5.1.8
795 	 */
796 	public boolean doWaitPreventRacyPack(long packSize) {
797 		return isWaitPreventRacyPack()
798 				&& packSize > getMinSizePreventRacyPack();
799 	}
800 
801 	/**
802 	 * Set whether we wait before opening a newly written pack to prevent its
803 	 * lastModified timestamp could be racy
804 	 *
805 	 * @param waitPreventRacyPack
806 	 *            whether we wait before opening a newly written pack to prevent
807 	 *            its lastModified timestamp could be racy
808 	 * @since 5.1.8
809 	 */
810 	public void setWaitPreventRacyPack(boolean waitPreventRacyPack) {
811 		this.waitPreventRacyPack = waitPreventRacyPack;
812 	}
813 
814 	/**
815 	 * Get minimum packfile size for which we wait before opening a newly
816 	 * written pack to prevent its lastModified timestamp could be racy if
817 	 * {@code isWaitToPreventRacyPack} is {@code true}.
818 	 *
819 	 * @return minimum packfile size, default is 100 MiB
820 	 *
821 	 * @since 5.1.8
822 	 */
823 	public long getMinSizePreventRacyPack() {
824 		return minSizePreventRacyPack;
825 	}
826 
827 	/**
828 	 * Set minimum packfile size for which we wait before opening a newly
829 	 * written pack to prevent its lastModified timestamp could be racy if
830 	 * {@code isWaitToPreventRacyPack} is {@code true}.
831 	 *
832 	 * @param minSizePreventRacyPack
833 	 *            minimum packfile size, default is 100 MiB
834 	 *
835 	 * @since 5.1.8
836 	 */
837 	public void setMinSizePreventRacyPack(long minSizePreventRacyPack) {
838 		this.minSizePreventRacyPack = minSizePreventRacyPack;
839 	}
840 
841 	/**
842 	 * Get the compression level applied to objects in the pack.
843 	 *
844 	 * Default setting: {@value java.util.zip.Deflater#DEFAULT_COMPRESSION}
845 	 *
846 	 * @return current compression level, see {@link java.util.zip.Deflater}.
847 	 */
848 	public int getCompressionLevel() {
849 		return compressionLevel;
850 	}
851 
852 	/**
853 	 * Set the compression level applied to objects in the pack.
854 	 *
855 	 * Default setting: {@value java.util.zip.Deflater#DEFAULT_COMPRESSION}
856 	 *
857 	 * @param level
858 	 *            compression level, must be a valid level recognized by the
859 	 *            {@link java.util.zip.Deflater} class.
860 	 */
861 	public void setCompressionLevel(int level) {
862 		compressionLevel = level;
863 	}
864 
865 	/**
866 	 * Get the number of threads used during delta compression.
867 	 *
868 	 * Default setting: 0 (auto-detect processors)
869 	 *
870 	 * @return number of threads used for delta compression. 0 will auto-detect
871 	 *         the threads to the number of available processors.
872 	 */
873 	public int getThreads() {
874 		return threads;
875 	}
876 
877 	/**
878 	 * Set the number of threads to use for delta compression.
879 	 *
880 	 * During delta compression, if there are enough objects to be considered
881 	 * the writer will start up concurrent threads and allow them to compress
882 	 * different sections of the repository concurrently.
883 	 *
884 	 * An application thread pool can be set by {@link #setExecutor(Executor)}.
885 	 * If not set a temporary pool will be created by the writer, and torn down
886 	 * automatically when compression is over.
887 	 *
888 	 * Default setting: 0 (auto-detect processors)
889 	 *
890 	 * @param threads
891 	 *            number of threads to use. If &lt;= 0 the number of available
892 	 *            processors for this JVM is used.
893 	 */
894 	public void setThreads(int threads) {
895 		this.threads = threads;
896 	}
897 
898 	/**
899 	 * Get the preferred thread pool to execute delta search on.
900 	 *
901 	 * @return the preferred thread pool to execute delta search on.
902 	 */
903 	public Executor getExecutor() {
904 		return executor;
905 	}
906 
907 	/**
908 	 * Set the executor to use when using threads.
909 	 *
910 	 * During delta compression if the executor is non-null jobs will be queued
911 	 * up on it to perform delta compression in parallel. Aside from setting the
912 	 * executor, the caller must set {@link #setThreads(int)} to enable threaded
913 	 * delta search.
914 	 *
915 	 * @param executor
916 	 *            executor to use for threads. Set to null to create a temporary
917 	 *            executor just for the writer.
918 	 */
919 	public void setExecutor(Executor executor) {
920 		this.executor = executor;
921 	}
922 
923 	/**
924 	 * Get the pack index file format version this instance creates.
925 	 *
926 	 * Default setting: {@value #DEFAULT_INDEX_VERSION}
927 	 *
928 	 * @return the index version, the special version 0 designates the oldest
929 	 *         (most compatible) format available for the objects.
930 	 * @see PackIndexWriter
931 	 */
932 	public int getIndexVersion() {
933 		return indexVersion;
934 	}
935 
936 	/**
937 	 * Set the pack index file format version this instance will create.
938 	 *
939 	 * Default setting: {@value #DEFAULT_INDEX_VERSION}
940 	 *
941 	 * @param version
942 	 *            the version to write. The special version 0 designates the
943 	 *            oldest (most compatible) format available for the objects.
944 	 * @see PackIndexWriter
945 	 */
946 	public void setIndexVersion(int version) {
947 		indexVersion = version;
948 	}
949 
950 	/**
951 	 * True if writer is allowed to build bitmaps for indexes.
952 	 *
953 	 * Default setting: {@value #DEFAULT_BUILD_BITMAPS}
954 	 *
955 	 * @return true if delta base is the writer can choose to output an index
956 	 *         with bitmaps.
957 	 * @since 3.0
958 	 */
959 	public boolean isBuildBitmaps() {
960 		return buildBitmaps;
961 	}
962 
963 	/**
964 	 * Set writer to allow building bitmaps for supported pack files.
965 	 *
966 	 * Index files can include bitmaps to speed up future ObjectWalks.
967 	 *
968 	 * Default setting: {@value #DEFAULT_BUILD_BITMAPS}
969 	 *
970 	 * @param buildBitmaps
971 	 *            boolean indicating whether bitmaps may be included in the
972 	 *            index.
973 	 * @since 3.0
974 	 */
975 	public void setBuildBitmaps(boolean buildBitmaps) {
976 		this.buildBitmaps = buildBitmaps;
977 	}
978 
979 	/**
980 	 * Get the count of most recent commits for which to build bitmaps.
981 	 *
982 	 * Default setting: {@value #DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT}
983 	 *
984 	 * @return the count of most recent commits for which to build bitmaps
985 	 * @since 4.2
986 	 */
987 	public int getBitmapContiguousCommitCount() {
988 		return bitmapContiguousCommitCount;
989 	}
990 
991 	/**
992 	 * Set the count of most recent commits for which to build bitmaps.
993 	 *
994 	 * Default setting: {@value #DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT}
995 	 *
996 	 * @param count
997 	 *            the count of most recent commits for which to build bitmaps
998 	 * @since 4.2
999 	 */
1000 	public void setBitmapContiguousCommitCount(int count) {
1001 		bitmapContiguousCommitCount = count;
1002 	}
1003 
1004 	/**
1005 	 * Get the count at which to switch from "bitmapRecentCommitSpan" to
1006 	 * "bitmapDistantCommitSpan".
1007 	 *
1008 	 * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_COUNT}
1009 	 *
1010 	 * @return the count for switching between recent and distant spans
1011 	 * @since 4.2
1012 	 */
1013 	public int getBitmapRecentCommitCount() {
1014 		return bitmapRecentCommitCount;
1015 	}
1016 
1017 	/**
1018 	 * Set the count at which to switch from "bitmapRecentCommitSpan" to
1019 	 * "bitmapDistantCommitSpan".
1020 	 *
1021 	 * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_COUNT}
1022 	 *
1023 	 * @param count
1024 	 *            the count for switching between recent and distant spans
1025 	 * @since 4.2
1026 	 */
1027 	public void setBitmapRecentCommitCount(int count) {
1028 		bitmapRecentCommitCount = count;
1029 	}
1030 
1031 	/**
1032 	 * Get the span of commits when building bitmaps for recent history.
1033 	 *
1034 	 * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_SPAN}
1035 	 *
1036 	 * @return the span of commits when building bitmaps for recent history
1037 	 * @since 4.2
1038 	 */
1039 	public int getBitmapRecentCommitSpan() {
1040 		return bitmapRecentCommitSpan;
1041 	}
1042 
1043 	/**
1044 	 * Set the span of commits when building bitmaps for recent history.
1045 	 *
1046 	 * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_SPAN}
1047 	 *
1048 	 * @param span
1049 	 *            the span of commits when building bitmaps for recent history
1050 	 * @since 4.2
1051 	 */
1052 	public void setBitmapRecentCommitSpan(int span) {
1053 		bitmapRecentCommitSpan = span;
1054 	}
1055 
1056 	/**
1057 	 * Get the span of commits when building bitmaps for distant history.
1058 	 *
1059 	 * Default setting: {@value #DEFAULT_BITMAP_DISTANT_COMMIT_SPAN}
1060 	 *
1061 	 * @return the span of commits when building bitmaps for distant history
1062 	 * @since 4.2
1063 	 */
1064 	public int getBitmapDistantCommitSpan() {
1065 		return bitmapDistantCommitSpan;
1066 	}
1067 
1068 	/**
1069 	 * Set the span of commits when building bitmaps for distant history.
1070 	 *
1071 	 * Default setting: {@value #DEFAULT_BITMAP_DISTANT_COMMIT_SPAN}
1072 	 *
1073 	 * @param span
1074 	 *            the span of commits when building bitmaps for distant history
1075 	 * @since 4.2
1076 	 */
1077 	public void setBitmapDistantCommitSpan(int span) {
1078 		bitmapDistantCommitSpan = span;
1079 	}
1080 
1081 	/**
1082 	 * Get the count of branches deemed "excessive". If the count of branches in
1083 	 * a repository exceeds this number and bitmaps are enabled, "inactive"
1084 	 * branches will have fewer bitmaps than "active" branches.
1085 	 *
1086 	 * Default setting: {@value #DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT}
1087 	 *
1088 	 * @return the count of branches deemed "excessive"
1089 	 * @since 4.2
1090 	 */
1091 	public int getBitmapExcessiveBranchCount() {
1092 		return bitmapExcessiveBranchCount;
1093 	}
1094 
1095 	/**
1096 	 * Set the count of branches deemed "excessive". If the count of branches in
1097 	 * a repository exceeds this number and bitmaps are enabled, "inactive"
1098 	 * branches will have fewer bitmaps than "active" branches.
1099 	 *
1100 	 * Default setting: {@value #DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT}
1101 	 *
1102 	 * @param count
1103 	 *            the count of branches deemed "excessive"
1104 	 * @since 4.2
1105 	 */
1106 	public void setBitmapExcessiveBranchCount(int count) {
1107 		bitmapExcessiveBranchCount = count;
1108 	}
1109 
1110 	/**
1111 	 * Get the age in days that marks a branch as "inactive".
1112 	 *
1113 	 * Default setting: {@value #DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS}
1114 	 *
1115 	 * @return the age in days that marks a branch as "inactive"
1116 	 * @since 4.2
1117 	 */
1118 	public int getBitmapInactiveBranchAgeInDays() {
1119 		return bitmapInactiveBranchAgeInDays;
1120 	}
1121 
1122 	/**
1123 	 * Get the max time to spend during the search for reuse phase.
1124 	 *
1125 	 * Default setting: {@value #DEFAULT_SEARCH_FOR_REUSE_TIMEOUT}
1126 	 *
1127 	 * @return the maximum time to spend during the search for reuse phase.
1128 	 * @since 5.13
1129 	 */
1130 	public Duration getSearchForReuseTimeout() {
1131 		return searchForReuseTimeout;
1132 	}
1133 
1134 	/**
1135 	 * Set the age in days that marks a branch as "inactive".
1136 	 *
1137 	 * Default setting: {@value #DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS}
1138 	 *
1139 	 * @param ageInDays
1140 	 *            the age in days that marks a branch as "inactive"
1141 	 * @since 4.2
1142 	 */
1143 	public void setBitmapInactiveBranchAgeInDays(int ageInDays) {
1144 		bitmapInactiveBranchAgeInDays = ageInDays;
1145 	}
1146 
1147 	/**
1148 	 * Set the max time to spend during the search for reuse phase.
1149 	 *
1150 	 * @param timeout
1151 	 *            max time allowed during the search for reuse phase
1152 	 *
1153 	 *            Default setting: {@value #DEFAULT_SEARCH_FOR_REUSE_TIMEOUT}
1154 	 * @since 5.13
1155 	 */
1156 	public void setSearchForReuseTimeout(Duration timeout) {
1157 		searchForReuseTimeout = timeout;
1158 	}
1159 
1160 	/**
1161 	 * Update properties by setting fields from the configuration.
1162 	 *
1163 	 * If a property's corresponding variable is not defined in the supplied
1164 	 * configuration, then it is left unmodified.
1165 	 *
1166 	 * @param rc
1167 	 *            configuration to read properties from.
1168 	 */
1169 	public void fromConfig(Config rc) {
1170 		setMaxDeltaDepth(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_DEPTH,
1171 				getMaxDeltaDepth()));
1172 		setDeltaSearchWindowSize(rc.getInt(CONFIG_PACK_SECTION,
1173 				CONFIG_KEY_WINDOW, getDeltaSearchWindowSize()));
1174 		setDeltaSearchMemoryLimit(rc.getLong(CONFIG_PACK_SECTION,
1175 				CONFIG_KEY_WINDOW_MEMORY, getDeltaSearchMemoryLimit()));
1176 		setDeltaCacheSize(rc.getLong(CONFIG_PACK_SECTION,
1177 				CONFIG_KEY_DELTA_CACHE_SIZE, getDeltaCacheSize()));
1178 		setDeltaCacheLimit(rc.getInt(CONFIG_PACK_SECTION,
1179 				CONFIG_KEY_DELTA_CACHE_LIMIT, getDeltaCacheLimit()));
1180 		setCompressionLevel(rc.getInt(CONFIG_PACK_SECTION,
1181 				CONFIG_KEY_COMPRESSION, rc.getInt(CONFIG_CORE_SECTION,
1182 						CONFIG_KEY_COMPRESSION, getCompressionLevel())));
1183 		setIndexVersion(rc.getInt(CONFIG_PACK_SECTION,
1184 				CONFIG_KEY_INDEXVERSION,
1185 				getIndexVersion()));
1186 		setBigFileThreshold(rc.getInt(CONFIG_CORE_SECTION,
1187 				CONFIG_KEY_BIGFILE_THRESHOLD, getBigFileThreshold()));
1188 		setThreads(rc.getInt(CONFIG_PACK_SECTION, CONFIG_KEY_THREADS,
1189 				getThreads()));
1190 
1191 		// These variables aren't standardized
1192 		setReuseDeltas(rc.getBoolean(CONFIG_PACK_SECTION,
1193 				CONFIG_KEY_REUSE_DELTAS, isReuseDeltas()));
1194 		setReuseObjects(rc.getBoolean(CONFIG_PACK_SECTION,
1195 				CONFIG_KEY_REUSE_OBJECTS, isReuseObjects()));
1196 		setDeltaCompress(rc.getBoolean(CONFIG_PACK_SECTION,
1197 				CONFIG_KEY_DELTA_COMPRESSION, isDeltaCompress()));
1198 		setCutDeltaChains(rc.getBoolean(CONFIG_PACK_SECTION,
1199 				CONFIG_KEY_CUT_DELTACHAINS, getCutDeltaChains()));
1200 		setSinglePack(rc.getBoolean(CONFIG_PACK_SECTION,
1201 				CONFIG_KEY_SINGLE_PACK,
1202 				getSinglePack()));
1203 		setBuildBitmaps(rc.getBoolean(CONFIG_PACK_SECTION,
1204 				CONFIG_KEY_BUILD_BITMAPS, isBuildBitmaps()));
1205 		setBitmapContiguousCommitCount(rc.getInt(CONFIG_PACK_SECTION,
1206 				CONFIG_KEY_BITMAP_CONTIGUOUS_COMMIT_COUNT,
1207 				getBitmapContiguousCommitCount()));
1208 		setBitmapRecentCommitCount(rc.getInt(CONFIG_PACK_SECTION,
1209 				CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT,
1210 				getBitmapRecentCommitCount()));
1211 		setBitmapRecentCommitSpan(rc.getInt(CONFIG_PACK_SECTION,
1212 				CONFIG_KEY_BITMAP_RECENT_COMMIT_COUNT,
1213 				getBitmapRecentCommitSpan()));
1214 		setBitmapDistantCommitSpan(rc.getInt(CONFIG_PACK_SECTION,
1215 				CONFIG_KEY_BITMAP_DISTANT_COMMIT_SPAN,
1216 				getBitmapDistantCommitSpan()));
1217 		setBitmapExcessiveBranchCount(rc.getInt(CONFIG_PACK_SECTION,
1218 				CONFIG_KEY_BITMAP_EXCESSIVE_BRANCH_COUNT,
1219 				getBitmapExcessiveBranchCount()));
1220 		setBitmapInactiveBranchAgeInDays(rc.getInt(CONFIG_PACK_SECTION,
1221 				CONFIG_KEY_BITMAP_INACTIVE_BRANCH_AGE_INDAYS,
1222 				getBitmapInactiveBranchAgeInDays()));
1223 		setSearchForReuseTimeout(Duration.ofSeconds(rc.getTimeUnit(
1224 				CONFIG_PACK_SECTION, null,
1225 				CONFIG_KEY_SEARCH_FOR_REUSE_TIMEOUT,
1226 				getSearchForReuseTimeout().getSeconds(), TimeUnit.SECONDS)));
1227 		setWaitPreventRacyPack(rc.getBoolean(CONFIG_PACK_SECTION,
1228 				CONFIG_KEY_WAIT_PREVENT_RACYPACK, isWaitPreventRacyPack()));
1229 		setMinSizePreventRacyPack(rc.getLong(CONFIG_PACK_SECTION,
1230 				CONFIG_KEY_MIN_SIZE_PREVENT_RACYPACK,
1231 				getMinSizePreventRacyPack()));
1232 	}
1233 
1234 	/** {@inheritDoc} */
1235 	@Override
1236 	public String toString() {
1237 		final StringBuilder b = new StringBuilder();
1238 		b.append("maxDeltaDepth=").append(getMaxDeltaDepth()); //$NON-NLS-1$
1239 		b.append(", deltaSearchWindowSize=").append(getDeltaSearchWindowSize()); //$NON-NLS-1$
1240 		b.append(", deltaSearchMemoryLimit=") //$NON-NLS-1$
1241 				.append(getDeltaSearchMemoryLimit());
1242 		b.append(", deltaCacheSize=").append(getDeltaCacheSize()); //$NON-NLS-1$
1243 		b.append(", deltaCacheLimit=").append(getDeltaCacheLimit()); //$NON-NLS-1$
1244 		b.append(", compressionLevel=").append(getCompressionLevel()); //$NON-NLS-1$
1245 		b.append(", indexVersion=").append(getIndexVersion()); //$NON-NLS-1$
1246 		b.append(", bigFileThreshold=").append(getBigFileThreshold()); //$NON-NLS-1$
1247 		b.append(", threads=").append(getThreads()); //$NON-NLS-1$
1248 		b.append(", reuseDeltas=").append(isReuseDeltas()); //$NON-NLS-1$
1249 		b.append(", reuseObjects=").append(isReuseObjects()); //$NON-NLS-1$
1250 		b.append(", deltaCompress=").append(isDeltaCompress()); //$NON-NLS-1$
1251 		b.append(", buildBitmaps=").append(isBuildBitmaps()); //$NON-NLS-1$
1252 		b.append(", bitmapContiguousCommitCount=") //$NON-NLS-1$
1253 				.append(getBitmapContiguousCommitCount());
1254 		b.append(", bitmapRecentCommitCount=") //$NON-NLS-1$
1255 				.append(getBitmapRecentCommitCount());
1256 		b.append(", bitmapRecentCommitSpan=") //$NON-NLS-1$
1257 				.append(getBitmapRecentCommitSpan());
1258 		b.append(", bitmapDistantCommitSpan=") //$NON-NLS-1$
1259 				.append(getBitmapDistantCommitSpan());
1260 		b.append(", bitmapExcessiveBranchCount=") //$NON-NLS-1$
1261 				.append(getBitmapExcessiveBranchCount());
1262 		b.append(", bitmapInactiveBranchAge=") //$NON-NLS-1$
1263 				.append(getBitmapInactiveBranchAgeInDays());
1264 		b.append(", searchForReuseTimeout") //$NON-NLS-1$
1265 				.append(getSearchForReuseTimeout());
1266 		b.append(", singlePack=").append(getSinglePack()); //$NON-NLS-1$
1267 		return b.toString();
1268 	}
1269 }