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