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 /** Create a default configuration. */ 264 public PackConfig() { 265 // Fields are initialized to defaults. 266 } 267 268 /** 269 * Create a configuration honoring the repository's settings. 270 * 271 * @param db 272 * the repository to read settings from. The repository is not 273 * retained by the new configuration, instead its settings are 274 * copied during the constructor. 275 */ 276 public PackConfig(Repository db) { 277 fromConfig(db.getConfig()); 278 } 279 280 /** 281 * Create a configuration honoring settings in a {@link Config}. 282 * 283 * @param cfg 284 * the source to read settings from. The source is not retained 285 * by the new configuration, instead its settings are copied 286 * during the constructor. 287 */ 288 public PackConfig(Config cfg) { 289 fromConfig(cfg); 290 } 291 292 /** 293 * Copy an existing configuration to a new instance. 294 * 295 * @param cfg 296 * the source configuration to copy from. 297 */ 298 public PackConfig(PackConfig cfg) { 299 this.compressionLevel = cfg.compressionLevel; 300 this.reuseDeltas = cfg.reuseDeltas; 301 this.reuseObjects = cfg.reuseObjects; 302 this.preserveOldPacks = cfg.preserveOldPacks; 303 this.prunePreserved = cfg.prunePreserved; 304 this.deltaBaseAsOffset = cfg.deltaBaseAsOffset; 305 this.deltaCompress = cfg.deltaCompress; 306 this.maxDeltaDepth = cfg.maxDeltaDepth; 307 this.deltaSearchWindowSize = cfg.deltaSearchWindowSize; 308 this.deltaSearchMemoryLimit = cfg.deltaSearchMemoryLimit; 309 this.deltaCacheSize = cfg.deltaCacheSize; 310 this.deltaCacheLimit = cfg.deltaCacheLimit; 311 this.bigFileThreshold = cfg.bigFileThreshold; 312 this.threads = cfg.threads; 313 this.executor = cfg.executor; 314 this.indexVersion = cfg.indexVersion; 315 this.buildBitmaps = cfg.buildBitmaps; 316 this.bitmapContiguousCommitCount = cfg.bitmapContiguousCommitCount; 317 this.bitmapRecentCommitCount = cfg.bitmapRecentCommitCount; 318 this.bitmapRecentCommitSpan = cfg.bitmapRecentCommitSpan; 319 this.bitmapDistantCommitSpan = cfg.bitmapDistantCommitSpan; 320 this.bitmapExcessiveBranchCount = cfg.bitmapExcessiveBranchCount; 321 this.bitmapInactiveBranchAgeInDays = cfg.bitmapInactiveBranchAgeInDays; 322 this.cutDeltaChains = cfg.cutDeltaChains; 323 } 324 325 /** 326 * Check whether to reuse deltas existing in repository. 327 * 328 * Default setting: {@value #DEFAULT_REUSE_DELTAS} 329 * 330 * @return true if object is configured to reuse deltas; false otherwise. 331 */ 332 public boolean isReuseDeltas() { 333 return reuseDeltas; 334 } 335 336 /** 337 * Set reuse deltas configuration option for the writer. 338 * 339 * When enabled, writer will search for delta representation of object in 340 * repository and use it if possible. Normally, only deltas with base to 341 * another object existing in set of objects to pack will be used. The 342 * exception however is thin-packs where the base object may exist on the 343 * other side. 344 * 345 * When raw delta data is directly copied from a pack file, its checksum is 346 * computed to verify the data is not corrupt. 347 * 348 * Default setting: {@value #DEFAULT_REUSE_DELTAS} 349 * 350 * @param reuseDeltas 351 * boolean indicating whether or not try to reuse deltas. 352 */ 353 public void setReuseDeltas(boolean reuseDeltas) { 354 this.reuseDeltas = reuseDeltas; 355 } 356 357 /** 358 * Checks whether to reuse existing objects representation in repository. 359 * 360 * Default setting: {@value #DEFAULT_REUSE_OBJECTS} 361 * 362 * @return true if writer is configured to reuse objects representation from 363 * pack; false otherwise. 364 */ 365 public boolean isReuseObjects() { 366 return reuseObjects; 367 } 368 369 /** 370 * Set reuse objects configuration option for the writer. 371 * 372 * If enabled, writer searches for compressed representation in a pack file. 373 * If possible, compressed data is directly copied from such a pack file. 374 * Data checksum is verified. 375 * 376 * Default setting: {@value #DEFAULT_REUSE_OBJECTS} 377 * 378 * @param reuseObjects 379 * boolean indicating whether or not writer should reuse existing 380 * objects representation. 381 */ 382 public void setReuseObjects(boolean reuseObjects) { 383 this.reuseObjects = reuseObjects; 384 } 385 386 /** 387 * Checks whether to preserve old packs in a preserved directory 388 * 389 * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS} 390 * 391 * @return true if repacking will preserve old pack files. 392 * @since 4.7 393 */ 394 public boolean isPreserveOldPacks() { 395 return preserveOldPacks; 396 } 397 398 /** 399 * Set preserve old packs configuration option for repacking. 400 * 401 * If enabled, old pack files are moved into a preserved subdirectory instead 402 * of being deleted 403 * 404 * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS} 405 * 406 * @param preserveOldPacks 407 * boolean indicating whether or not preserve old pack files 408 * @since 4.7 409 */ 410 public void setPreserveOldPacks(boolean preserveOldPacks) { 411 this.preserveOldPacks = preserveOldPacks; 412 } 413 414 /** 415 * Checks whether to remove preserved pack files in a preserved directory 416 * 417 * Default setting: {@value #DEFAULT_PRUNE_PRESERVED} 418 * 419 * @return true if repacking will remove preserved pack files. 420 * @since 4.7 421 */ 422 public boolean isPrunePreserved() { 423 return prunePreserved; 424 } 425 426 /** 427 * Set prune preserved configuration option for repacking. 428 * 429 * If enabled, preserved pack files are removed from a preserved subdirectory 430 * 431 * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS} 432 * 433 * @param prunePreserved 434 * boolean indicating whether or not preserve old pack files 435 * @since 4.7 436 */ 437 public void setPrunePreserved(boolean prunePreserved) { 438 this.prunePreserved = prunePreserved; 439 } 440 441 /** 442 * True if writer can use offsets to point to a delta base. 443 * 444 * If true the writer may choose to use an offset to point to a delta base 445 * in the same pack, this is a newer style of reference that saves space. 446 * False if the writer has to use the older (and more compatible style) of 447 * storing the full ObjectId of the delta base. 448 * 449 * Default setting: {@value #DEFAULT_DELTA_BASE_AS_OFFSET} 450 * 451 * @return true if delta base is stored as an offset; false if it is stored 452 * as an ObjectId. 453 */ 454 public boolean isDeltaBaseAsOffset() { 455 return deltaBaseAsOffset; 456 } 457 458 /** 459 * Set writer delta base format. 460 * 461 * Delta base can be written as an offset in a pack file (new approach 462 * reducing file size) or as an object id (legacy approach, compatible with 463 * old readers). 464 * 465 * Default setting: {@value #DEFAULT_DELTA_BASE_AS_OFFSET} 466 * 467 * @param deltaBaseAsOffset 468 * boolean indicating whether delta base can be stored as an 469 * offset. 470 */ 471 public void setDeltaBaseAsOffset(boolean deltaBaseAsOffset) { 472 this.deltaBaseAsOffset = deltaBaseAsOffset; 473 } 474 475 /** 476 * Check whether the writer will create new deltas on the fly. 477 * 478 * Default setting: {@value #DEFAULT_DELTA_COMPRESS} 479 * 480 * @return true if the writer will create a new delta when either 481 * {@link #isReuseDeltas()} is false, or no suitable delta is 482 * available for reuse. 483 */ 484 public boolean isDeltaCompress() { 485 return deltaCompress; 486 } 487 488 /** 489 * Set whether or not the writer will create new deltas on the fly. 490 * 491 * Default setting: {@value #DEFAULT_DELTA_COMPRESS} 492 * 493 * @param deltaCompress 494 * true to create deltas when {@link #isReuseDeltas()} is false, 495 * or when a suitable delta isn't available for reuse. Set to 496 * false to write whole objects instead. 497 */ 498 public void setDeltaCompress(boolean deltaCompress) { 499 this.deltaCompress = deltaCompress; 500 } 501 502 /** 503 * Get maximum depth of delta chain set up for the writer. 504 * 505 * Generated chains are not longer than this value. 506 * 507 * Default setting: {@value #DEFAULT_MAX_DELTA_DEPTH} 508 * 509 * @return maximum delta chain depth. 510 */ 511 public int getMaxDeltaDepth() { 512 return maxDeltaDepth; 513 } 514 515 /** 516 * Set up maximum depth of delta chain for the writer. 517 * 518 * Generated chains are not longer than this value. Too low value causes low 519 * compression level, while too big makes unpacking (reading) longer. 520 * 521 * Default setting: {@value #DEFAULT_MAX_DELTA_DEPTH} 522 * 523 * @param maxDeltaDepth 524 * maximum delta chain depth. 525 */ 526 public void setMaxDeltaDepth(int maxDeltaDepth) { 527 this.maxDeltaDepth = maxDeltaDepth; 528 } 529 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 * Get the number of objects to try when looking for a delta base. 559 * 560 * This limit is per thread, if 4 threads are used the actual memory used 561 * will be 4 times this value. 562 * 563 * Default setting: {@value #DEFAULT_DELTA_SEARCH_WINDOW_SIZE} 564 * 565 * @return the object count to be searched. 566 */ 567 public int getDeltaSearchWindowSize() { 568 return deltaSearchWindowSize; 569 } 570 571 /** 572 * Set the number of objects considered when searching for a delta base. 573 * 574 * Default setting: {@value #DEFAULT_DELTA_SEARCH_WINDOW_SIZE} 575 * 576 * @param objectCount 577 * number of objects to search at once. Must be at least 2. 578 */ 579 public void setDeltaSearchWindowSize(int objectCount) { 580 if (objectCount <= 2) 581 setDeltaCompress(false); 582 else 583 deltaSearchWindowSize = objectCount; 584 } 585 586 /** 587 * Get maximum number of bytes to put into the delta search window. 588 * 589 * Default setting is 0, for an unlimited amount of memory usage. Actual 590 * memory used is the lower limit of either this setting, or the sum of 591 * space used by at most {@link #getDeltaSearchWindowSize()} objects. 592 * 593 * This limit is per thread, if 4 threads are used the actual memory limit 594 * will be 4 times this value. 595 * 596 * @return the memory limit. 597 */ 598 public long getDeltaSearchMemoryLimit() { 599 return deltaSearchMemoryLimit; 600 } 601 602 /** 603 * Set the maximum number of bytes to put into the delta search window. 604 * 605 * Default setting is 0, for an unlimited amount of memory usage. If the 606 * memory limit is reached before {@link #getDeltaSearchWindowSize()} the 607 * window size is temporarily lowered. 608 * 609 * @param memoryLimit 610 * Maximum number of bytes to load at once, 0 for unlimited. 611 */ 612 public void setDeltaSearchMemoryLimit(long memoryLimit) { 613 deltaSearchMemoryLimit = memoryLimit; 614 } 615 616 /** 617 * Get the size of the in-memory delta cache. 618 * 619 * This limit is for the entire writer, even if multiple threads are used. 620 * 621 * Default setting: {@value #DEFAULT_DELTA_CACHE_SIZE} 622 * 623 * @return maximum number of bytes worth of delta data to cache in memory. 624 * If 0 the cache is infinite in size (up to the JVM heap limit 625 * anyway). A very tiny size such as 1 indicates the cache is 626 * effectively disabled. 627 */ 628 public long getDeltaCacheSize() { 629 return deltaCacheSize; 630 } 631 632 /** 633 * Set the maximum number of bytes of delta data to cache. 634 * 635 * During delta search, up to this many bytes worth of small or hard to 636 * compute deltas will be stored in memory. This cache speeds up writing by 637 * allowing the cached entry to simply be dumped to the output stream. 638 * 639 * Default setting: {@value #DEFAULT_DELTA_CACHE_SIZE} 640 * 641 * @param size 642 * number of bytes to cache. Set to 0 to enable an infinite 643 * cache, set to 1 (an impossible size for any delta) to disable 644 * the cache. 645 */ 646 public void setDeltaCacheSize(long size) { 647 deltaCacheSize = size; 648 } 649 650 /** 651 * Maximum size in bytes of a delta to cache. 652 * 653 * Default setting: {@value #DEFAULT_DELTA_CACHE_LIMIT} 654 * 655 * @return maximum size (in bytes) of a delta that should be cached. 656 */ 657 public int getDeltaCacheLimit() { 658 return deltaCacheLimit; 659 } 660 661 /** 662 * Set the maximum size of a delta that should be cached. 663 * 664 * During delta search, any delta smaller than this size will be cached, up 665 * to the {@link #getDeltaCacheSize()} maximum limit. This speeds up writing 666 * by allowing these cached deltas to be output as-is. 667 * 668 * Default setting: {@value #DEFAULT_DELTA_CACHE_LIMIT} 669 * 670 * @param size 671 * maximum size (in bytes) of a delta to be cached. 672 */ 673 public void setDeltaCacheLimit(int size) { 674 deltaCacheLimit = size; 675 } 676 677 /** 678 * Get the maximum file size that will be delta compressed. 679 * 680 * Files bigger than this setting will not be delta compressed, as they are 681 * more than likely already highly compressed binary data files that do not 682 * delta compress well, such as MPEG videos. 683 * 684 * Default setting: {@value #DEFAULT_BIG_FILE_THRESHOLD} 685 * 686 * @return the configured big file threshold. 687 */ 688 public int getBigFileThreshold() { 689 return bigFileThreshold; 690 } 691 692 /** 693 * Set the maximum file size that should be considered for deltas. 694 * 695 * Default setting: {@value #DEFAULT_BIG_FILE_THRESHOLD} 696 * 697 * @param bigFileThreshold 698 * the limit, in bytes. 699 */ 700 public void setBigFileThreshold(int bigFileThreshold) { 701 this.bigFileThreshold = bigFileThreshold; 702 } 703 704 /** 705 * Get the compression level applied to objects in the pack. 706 * 707 * Default setting: {@value java.util.zip.Deflater#DEFAULT_COMPRESSION} 708 * 709 * @return current compression level, see {@link java.util.zip.Deflater}. 710 */ 711 public int getCompressionLevel() { 712 return compressionLevel; 713 } 714 715 /** 716 * Set the compression level applied to objects in the pack. 717 * 718 * Default setting: {@value java.util.zip.Deflater#DEFAULT_COMPRESSION} 719 * 720 * @param level 721 * compression level, must be a valid level recognized by the 722 * {@link java.util.zip.Deflater} class. 723 */ 724 public void setCompressionLevel(int level) { 725 compressionLevel = level; 726 } 727 728 /** 729 * Get the number of threads used during delta compression. 730 * 731 * Default setting: 0 (auto-detect processors) 732 * 733 * @return number of threads used for delta compression. 0 will auto-detect 734 * the threads to the number of available processors. 735 */ 736 public int getThreads() { 737 return threads; 738 } 739 740 /** 741 * Set the number of threads to use for delta compression. 742 * 743 * During delta compression, if there are enough objects to be considered 744 * the writer will start up concurrent threads and allow them to compress 745 * different sections of the repository concurrently. 746 * 747 * An application thread pool can be set by {@link #setExecutor(Executor)}. 748 * If not set a temporary pool will be created by the writer, and torn down 749 * automatically when compression is over. 750 * 751 * Default setting: 0 (auto-detect processors) 752 * 753 * @param threads 754 * number of threads to use. If <= 0 the number of available 755 * processors for this JVM is used. 756 */ 757 public void setThreads(int threads) { 758 this.threads = threads; 759 } 760 761 /** @return the preferred thread pool to execute delta search on. */ 762 public Executor getExecutor() { 763 return executor; 764 } 765 766 /** 767 * Set the executor to use when using threads. 768 * 769 * During delta compression if the executor is non-null jobs will be queued 770 * up on it to perform delta compression in parallel. Aside from setting the 771 * executor, the caller must set {@link #setThreads(int)} to enable threaded 772 * delta search. 773 * 774 * @param executor 775 * executor to use for threads. Set to null to create a temporary 776 * executor just for the writer. 777 */ 778 public void setExecutor(Executor executor) { 779 this.executor = executor; 780 } 781 782 /** 783 * Get the pack index file format version this instance creates. 784 * 785 * Default setting: {@value #DEFAULT_INDEX_VERSION} 786 * 787 * @return the index version, the special version 0 designates the oldest 788 * (most compatible) format available for the objects. 789 * @see PackIndexWriter 790 */ 791 public int getIndexVersion() { 792 return indexVersion; 793 } 794 795 /** 796 * Set the pack index file format version this instance will create. 797 * 798 * Default setting: {@value #DEFAULT_INDEX_VERSION} 799 * 800 * @param version 801 * the version to write. The special version 0 designates the 802 * oldest (most compatible) format available for the objects. 803 * @see PackIndexWriter 804 */ 805 public void setIndexVersion(int version) { 806 indexVersion = version; 807 } 808 809 /** 810 * True if writer is allowed to build bitmaps for indexes. 811 * 812 * Default setting: {@value #DEFAULT_BUILD_BITMAPS} 813 * 814 * @return true if delta base is the writer can choose to output an index 815 * with bitmaps. 816 * @since 3.0 817 */ 818 public boolean isBuildBitmaps() { 819 return buildBitmaps; 820 } 821 822 /** 823 * Set writer to allow building bitmaps for supported pack files. 824 * 825 * Index files can include bitmaps to speed up future ObjectWalks. 826 * 827 * Default setting: {@value #DEFAULT_BUILD_BITMAPS} 828 * 829 * @param buildBitmaps 830 * boolean indicating whether bitmaps may be included in the 831 * index. 832 * @since 3.0 833 */ 834 public void setBuildBitmaps(boolean buildBitmaps) { 835 this.buildBitmaps = buildBitmaps; 836 } 837 838 /** 839 * Get the count of most recent commits for which to build bitmaps. 840 * 841 * Default setting: {@value #DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT} 842 * 843 * @return the count of most recent commits for which to build bitmaps 844 * @since 4.2 845 */ 846 public int getBitmapContiguousCommitCount() { 847 return bitmapContiguousCommitCount; 848 } 849 850 /** 851 * Set the count of most recent commits for which to build bitmaps. 852 * 853 * Default setting: {@value #DEFAULT_BITMAP_CONTIGUOUS_COMMIT_COUNT} 854 * 855 * @param count 856 * the count of most recent commits for which to build bitmaps 857 * @since 4.2 858 */ 859 public void setBitmapContiguousCommitCount(int count) { 860 bitmapContiguousCommitCount = count; 861 } 862 863 /** 864 * Get the count at which to switch from "bitmapRecentCommitSpan" to 865 * "bitmapDistantCommitSpan". 866 * 867 * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_COUNT} 868 * 869 * @return the count for switching between recent and distant spans 870 * @since 4.2 871 */ 872 public int getBitmapRecentCommitCount() { 873 return bitmapRecentCommitCount; 874 } 875 876 /** 877 * Set the count at which to switch from "bitmapRecentCommitSpan" to 878 * "bitmapDistantCommitSpan". 879 * 880 * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_COUNT} 881 * 882 * @param count 883 * the count for switching between recent and distant spans 884 * @since 4.2 885 */ 886 public void setBitmapRecentCommitCount(int count) { 887 bitmapRecentCommitCount = count; 888 } 889 890 /** 891 * Get the span of commits when building bitmaps for recent history. 892 * 893 * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_SPAN} 894 * 895 * @return the span of commits when building bitmaps for recent history 896 * @since 4.2 897 */ 898 public int getBitmapRecentCommitSpan() { 899 return bitmapRecentCommitSpan; 900 } 901 902 /** 903 * Set the span of commits when building bitmaps for recent history. 904 * 905 * Default setting: {@value #DEFAULT_BITMAP_RECENT_COMMIT_SPAN} 906 * 907 * @param span 908 * the span of commits when building bitmaps for recent history 909 * @since 4.2 910 */ 911 public void setBitmapRecentCommitSpan(int span) { 912 bitmapRecentCommitSpan = span; 913 } 914 915 /** 916 * Get the span of commits when building bitmaps for distant history. 917 * 918 * Default setting: {@value #DEFAULT_BITMAP_DISTANT_COMMIT_SPAN} 919 * 920 * @return the span of commits when building bitmaps for distant history 921 * @since 4.2 922 */ 923 public int getBitmapDistantCommitSpan() { 924 return bitmapDistantCommitSpan; 925 } 926 927 /** 928 * Set the span of commits when building bitmaps for distant history. 929 * 930 * Default setting: {@value #DEFAULT_BITMAP_DISTANT_COMMIT_SPAN} 931 * 932 * @param span 933 * the span of commits when building bitmaps for distant history 934 * @since 4.2 935 */ 936 public void setBitmapDistantCommitSpan(int span) { 937 bitmapDistantCommitSpan = span; 938 } 939 940 /** 941 * Get the count of branches deemed "excessive". If the count of branches in 942 * a repository exceeds this number and bitmaps are enabled, "inactive" 943 * branches will have fewer bitmaps than "active" branches. 944 * 945 * Default setting: {@value #DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT} 946 * 947 * @return the count of branches deemed "excessive" 948 * @since 4.2 949 */ 950 public int getBitmapExcessiveBranchCount() { 951 return bitmapExcessiveBranchCount; 952 } 953 954 /** 955 * Set the count of branches deemed "excessive". If the count of branches in 956 * a repository exceeds this number and bitmaps are enabled, "inactive" 957 * branches will have fewer bitmaps than "active" branches. 958 * 959 * Default setting: {@value #DEFAULT_BITMAP_EXCESSIVE_BRANCH_COUNT} 960 * 961 * @param count 962 * the count of branches deemed "excessive" 963 * @since 4.2 964 */ 965 public void setBitmapExcessiveBranchCount(int count) { 966 bitmapExcessiveBranchCount = count; 967 } 968 969 /** 970 * Get the the age in days that marks a branch as "inactive". 971 * 972 * Default setting: {@value #DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS} 973 * 974 * @return the age in days that marks a branch as "inactive" 975 * @since 4.2 976 */ 977 public int getBitmapInactiveBranchAgeInDays() { 978 return bitmapInactiveBranchAgeInDays; 979 } 980 981 /** 982 * Set the the age in days that marks a branch as "inactive". 983 * 984 * Default setting: {@value #DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS} 985 * 986 * @param ageInDays 987 * the age in days that marks a branch as "inactive" 988 * @since 4.2 989 */ 990 public void setBitmapInactiveBranchAgeInDays(int ageInDays) { 991 bitmapInactiveBranchAgeInDays = ageInDays; 992 } 993 994 /** 995 * Update properties by setting fields from the configuration. 996 * 997 * If a property's corresponding variable is not defined in the supplied 998 * configuration, then it is left unmodified. 999 * 1000 * @param rc 1001 * configuration to read properties from. 1002 */ 1003 public void fromConfig(final Config rc) { 1004 setMaxDeltaDepth(rc.getInt("pack", "depth", getMaxDeltaDepth())); //$NON-NLS-1$ //$NON-NLS-2$ 1005 setDeltaSearchWindowSize(rc.getInt( 1006 "pack", "window", getDeltaSearchWindowSize())); //$NON-NLS-1$ //$NON-NLS-2$ 1007 setDeltaSearchMemoryLimit(rc.getLong( 1008 "pack", "windowmemory", getDeltaSearchMemoryLimit())); //$NON-NLS-1$ //$NON-NLS-2$ 1009 setDeltaCacheSize(rc.getLong( 1010 "pack", "deltacachesize", getDeltaCacheSize())); //$NON-NLS-1$ //$NON-NLS-2$ 1011 setDeltaCacheLimit(rc.getInt( 1012 "pack", "deltacachelimit", getDeltaCacheLimit())); //$NON-NLS-1$ //$NON-NLS-2$ 1013 setCompressionLevel(rc.getInt("pack", "compression", //$NON-NLS-1$ //$NON-NLS-2$ 1014 rc.getInt("core", "compression", getCompressionLevel()))); //$NON-NLS-1$ //$NON-NLS-2$ 1015 setIndexVersion(rc.getInt("pack", "indexversion", getIndexVersion())); //$NON-NLS-1$ //$NON-NLS-2$ 1016 setBigFileThreshold(rc.getInt( 1017 "core", "bigfilethreshold", getBigFileThreshold())); //$NON-NLS-1$ //$NON-NLS-2$ 1018 setThreads(rc.getInt("pack", "threads", getThreads())); //$NON-NLS-1$ //$NON-NLS-2$ 1019 1020 // These variables aren't standardized 1021 // 1022 setReuseDeltas(rc.getBoolean("pack", "reusedeltas", isReuseDeltas())); //$NON-NLS-1$ //$NON-NLS-2$ 1023 setReuseObjects( 1024 rc.getBoolean("pack", "reuseobjects", isReuseObjects())); //$NON-NLS-1$ //$NON-NLS-2$ 1025 setDeltaCompress( 1026 rc.getBoolean("pack", "deltacompression", isDeltaCompress())); //$NON-NLS-1$ //$NON-NLS-2$ 1027 setCutDeltaChains( 1028 rc.getBoolean("pack", "cutdeltachains", getCutDeltaChains())); //$NON-NLS-1$ //$NON-NLS-2$ 1029 setBuildBitmaps( 1030 rc.getBoolean("pack", "buildbitmaps", isBuildBitmaps())); //$NON-NLS-1$ //$NON-NLS-2$ 1031 setBitmapContiguousCommitCount( 1032 rc.getInt("pack", "bitmapcontiguouscommitcount", //$NON-NLS-1$ //$NON-NLS-2$ 1033 getBitmapContiguousCommitCount())); 1034 setBitmapRecentCommitCount(rc.getInt("pack", "bitmaprecentcommitcount", //$NON-NLS-1$ //$NON-NLS-2$ 1035 getBitmapRecentCommitCount())); 1036 setBitmapRecentCommitSpan(rc.getInt("pack", "bitmaprecentcommitspan", //$NON-NLS-1$ //$NON-NLS-2$ 1037 getBitmapRecentCommitSpan())); 1038 setBitmapDistantCommitSpan(rc.getInt("pack", "bitmapdistantcommitspan", //$NON-NLS-1$ //$NON-NLS-2$ 1039 getBitmapDistantCommitSpan())); 1040 setBitmapExcessiveBranchCount(rc.getInt("pack", //$NON-NLS-1$ 1041 "bitmapexcessivebranchcount", getBitmapExcessiveBranchCount())); //$NON-NLS-1$ 1042 setBitmapInactiveBranchAgeInDays( 1043 rc.getInt("pack", "bitmapinactivebranchageindays", //$NON-NLS-1$ //$NON-NLS-2$ 1044 getBitmapInactiveBranchAgeInDays())); 1045 } 1046 1047 @Override 1048 public String toString() { 1049 final StringBuilder b = new StringBuilder(); 1050 b.append("maxDeltaDepth=").append(getMaxDeltaDepth()); //$NON-NLS-1$ 1051 b.append(", deltaSearchWindowSize=").append(getDeltaSearchWindowSize()); //$NON-NLS-1$ 1052 b.append(", deltaSearchMemoryLimit=") //$NON-NLS-1$ 1053 .append(getDeltaSearchMemoryLimit()); 1054 b.append(", deltaCacheSize=").append(getDeltaCacheSize()); //$NON-NLS-1$ 1055 b.append(", deltaCacheLimit=").append(getDeltaCacheLimit()); //$NON-NLS-1$ 1056 b.append(", compressionLevel=").append(getCompressionLevel()); //$NON-NLS-1$ 1057 b.append(", indexVersion=").append(getIndexVersion()); //$NON-NLS-1$ 1058 b.append(", bigFileThreshold=").append(getBigFileThreshold()); //$NON-NLS-1$ 1059 b.append(", threads=").append(getThreads()); //$NON-NLS-1$ 1060 b.append(", reuseDeltas=").append(isReuseDeltas()); //$NON-NLS-1$ 1061 b.append(", reuseObjects=").append(isReuseObjects()); //$NON-NLS-1$ 1062 b.append(", deltaCompress=").append(isDeltaCompress()); //$NON-NLS-1$ 1063 b.append(", buildBitmaps=").append(isBuildBitmaps()); //$NON-NLS-1$ 1064 b.append(", bitmapContiguousCommitCount=") //$NON-NLS-1$ 1065 .append(getBitmapContiguousCommitCount()); 1066 b.append(", bitmapRecentCommitCount=") //$NON-NLS-1$ 1067 .append(getBitmapRecentCommitCount()); 1068 b.append(", bitmapRecentCommitSpan=") //$NON-NLS-1$ 1069 .append(getBitmapRecentCommitSpan()); 1070 b.append(", bitmapDistantCommitSpan=") //$NON-NLS-1$ 1071 .append(getBitmapDistantCommitSpan()); 1072 b.append(", bitmapExcessiveBranchCount=") //$NON-NLS-1$ 1073 .append(getBitmapExcessiveBranchCount()); 1074 b.append(", bitmapInactiveBranchAge=") //$NON-NLS-1$ 1075 .append(getBitmapInactiveBranchAgeInDays()); 1076 return b.toString(); 1077 } 1078 }