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