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