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 <= 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 }