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