WindowCacheConfig.java

  1. /*
  2.  * Copyright (C) 2009, Google Inc. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.storage.file;

  11. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
  12. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_BASE_CACHE_LIMIT;
  13. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_LIMIT;
  14. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_MMAP;
  15. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_OPENFILES;
  16. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_WINDOWSIZE;
  17. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_STREAM_FILE_TRESHOLD;
  18. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_USE_STRONGREFS;

  19. import org.eclipse.jgit.internal.storage.file.WindowCache;
  20. import org.eclipse.jgit.lib.Config;
  21. import org.eclipse.jgit.storage.pack.PackConfig;

  22. /**
  23.  * Configuration parameters for JVM-wide buffer cache used by JGit.
  24.  */
  25. public class WindowCacheConfig {
  26.     /** 1024 (number of bytes in one kibibyte/kilobyte) */
  27.     public static final int KB = 1024;

  28.     /** 1024 {@link #KB} (number of bytes in one mebibyte/megabyte) */
  29.     public static final int MB = 1024 * KB;

  30.     private int packedGitOpenFiles;

  31.     private long packedGitLimit;

  32.     private boolean useStrongRefs;

  33.     private int packedGitWindowSize;

  34.     private boolean packedGitMMAP;

  35.     private int deltaBaseCacheLimit;

  36.     private int streamFileThreshold;

  37.     private boolean exposeStats;

  38.     /**
  39.      * Create a default configuration.
  40.      */
  41.     public WindowCacheConfig() {
  42.         packedGitOpenFiles = 128;
  43.         packedGitLimit = 10 * MB;
  44.         useStrongRefs = false;
  45.         packedGitWindowSize = 8 * KB;
  46.         packedGitMMAP = false;
  47.         deltaBaseCacheLimit = 10 * MB;
  48.         streamFileThreshold = PackConfig.DEFAULT_BIG_FILE_THRESHOLD;
  49.         exposeStats = true;
  50.     }

  51.     /**
  52.      * Get maximum number of streams to open at a time.
  53.      *
  54.      * @return maximum number of streams to open at a time. Open packs count
  55.      *         against the process limits. <b>Default is 128.</b>
  56.      */
  57.     public int getPackedGitOpenFiles() {
  58.         return packedGitOpenFiles;
  59.     }

  60.     /**
  61.      * Set maximum number of streams to open at a time.
  62.      *
  63.      * @param fdLimit
  64.      *            maximum number of streams to open at a time. Open packs count
  65.      *            against the process limits
  66.      */
  67.     public void setPackedGitOpenFiles(int fdLimit) {
  68.         packedGitOpenFiles = fdLimit;
  69.     }

  70.     /**
  71.      * Get maximum number bytes of heap memory to dedicate to caching pack file
  72.      * data.
  73.      *
  74.      * @return maximum number bytes of heap memory to dedicate to caching pack
  75.      *         file data. <b>Default is 10 MB.</b>
  76.      */
  77.     public long getPackedGitLimit() {
  78.         return packedGitLimit;
  79.     }

  80.     /**
  81.      * Set maximum number bytes of heap memory to dedicate to caching pack file
  82.      * data.
  83.      *
  84.      * @param newLimit
  85.      *            maximum number bytes of heap memory to dedicate to caching
  86.      *            pack file data.
  87.      */
  88.     public void setPackedGitLimit(long newLimit) {
  89.         packedGitLimit = newLimit;
  90.     }

  91.     /**
  92.      * Get whether the window cache should use strong references or
  93.      * SoftReferences
  94.      *
  95.      * @return {@code true} if the window cache should use strong references,
  96.      *         otherwise it will use {@link java.lang.ref.SoftReference}s
  97.      * @since 5.1.13
  98.      */
  99.     public boolean isPackedGitUseStrongRefs() {
  100.         return useStrongRefs;
  101.     }

  102.     /**
  103.      * Set if the cache should use strong refs or soft refs
  104.      *
  105.      * @param useStrongRefs
  106.      *            if @{code true} the cache strongly references cache pages
  107.      *            otherwise it uses {@link java.lang.ref.SoftReference}s which
  108.      *            can be evicted by the Java gc if heap is almost full
  109.      * @since 5.1.13
  110.      */
  111.     public void setPackedGitUseStrongRefs(boolean useStrongRefs) {
  112.         this.useStrongRefs = useStrongRefs;
  113.     }

  114.     /**
  115.      * Get size in bytes of a single window mapped or read in from the pack
  116.      * file.
  117.      *
  118.      * @return size in bytes of a single window mapped or read in from the pack
  119.      *         file. <b>Default is 8 KB.</b>
  120.      */
  121.     public int getPackedGitWindowSize() {
  122.         return packedGitWindowSize;
  123.     }

  124.     /**
  125.      * Set size in bytes of a single window read in from the pack file.
  126.      *
  127.      * @param newSize
  128.      *            size in bytes of a single window read in from the pack file.
  129.      */
  130.     public void setPackedGitWindowSize(int newSize) {
  131.         packedGitWindowSize = newSize;
  132.     }

  133.     /**
  134.      * Whether to use Java NIO virtual memory mapping for windows
  135.      *
  136.      * @return {@code true} enables use of Java NIO virtual memory mapping for
  137.      *         windows; false reads entire window into a byte[] with standard
  138.      *         read calls. <b>Default false.</b>
  139.      */
  140.     public boolean isPackedGitMMAP() {
  141.         return packedGitMMAP;
  142.     }

  143.     /**
  144.      * Set whether to enable use of Java NIO virtual memory mapping for windows
  145.      *
  146.      * @param usemmap
  147.      *            {@code true} enables use of Java NIO virtual memory mapping
  148.      *            for windows; false reads entire window into a byte[] with
  149.      *            standard read calls.
  150.      */
  151.     public void setPackedGitMMAP(boolean usemmap) {
  152.         packedGitMMAP = usemmap;
  153.     }

  154.     /**
  155.      * Get maximum number of bytes to cache in delta base cache for inflated,
  156.      * recently accessed objects, without delta chains.
  157.      *
  158.      * @return maximum number of bytes to cache in delta base cache for
  159.      *         inflated, recently accessed objects, without delta chains.
  160.      *         <b>Default 10 MB.</b>
  161.      */
  162.     public int getDeltaBaseCacheLimit() {
  163.         return deltaBaseCacheLimit;
  164.     }

  165.     /**
  166.      * Set maximum number of bytes to cache in delta base cache for inflated,
  167.      * recently accessed objects, without delta chains.
  168.      *
  169.      * @param newLimit
  170.      *            maximum number of bytes to cache in delta base cache for
  171.      *            inflated, recently accessed objects, without delta chains.
  172.      */
  173.     public void setDeltaBaseCacheLimit(int newLimit) {
  174.         deltaBaseCacheLimit = newLimit;
  175.     }

  176.     /**
  177.      * Get the size threshold beyond which objects must be streamed.
  178.      *
  179.      * @return the size threshold beyond which objects must be streamed.
  180.      */
  181.     public int getStreamFileThreshold() {
  182.         return streamFileThreshold;
  183.     }

  184.     /**
  185.      * Set new byte limit for objects that must be streamed.
  186.      *
  187.      * @param newLimit
  188.      *            new byte limit for objects that must be streamed. Objects
  189.      *            smaller than this size can be obtained as a contiguous byte
  190.      *            array, while objects bigger than this size require using an
  191.      *            {@link org.eclipse.jgit.lib.ObjectStream}.
  192.      */
  193.     public void setStreamFileThreshold(int newLimit) {
  194.         streamFileThreshold = newLimit;
  195.     }

  196.     /**
  197.      * Tell whether the statistics JMX bean should be automatically registered.
  198.      * <p>
  199.      * Registration of that bean via JMX is additionally subject to a boolean
  200.      * JGit-specific user config "jmx.WindowCacheStats". The bean will be
  201.      * registered only if this user config is {@code true} <em>and</em>
  202.      * {@code getExposeStatsViaJmx() == true}.
  203.      * </p>
  204.      * <p>
  205.      * By default, this returns {@code true} unless changed via
  206.      * {@link #setExposeStatsViaJmx(boolean)}.
  207.      *
  208.      * @return whether to expose WindowCacheStats statistics via JMX upon
  209.      *         {@link #install()}
  210.      * @since 5.8
  211.      */
  212.     public boolean getExposeStatsViaJmx() {
  213.         return exposeStats;
  214.     }

  215.     /**
  216.      * Defines whether the statistics JMX MBean should be automatically set up.
  217.      * (By default {@code true}.) If set to {@code false}, the JMX monitoring
  218.      * bean is not registered.
  219.      *
  220.      * @param expose
  221.      *            whether to register the JMX Bean
  222.      * @since 5.8
  223.      */
  224.     public void setExposeStatsViaJmx(boolean expose) {
  225.         exposeStats = expose;
  226.     }

  227.     /**
  228.      * Update properties by setting fields from the configuration.
  229.      * <p>
  230.      * If a property is not defined in the configuration, then it is left
  231.      * unmodified.
  232.      *
  233.      * @param rc
  234.      *            configuration to read properties from.
  235.      * @return {@code this}.
  236.      * @since 3.0
  237.      */
  238.     public WindowCacheConfig fromConfig(Config rc) {
  239.         setPackedGitUseStrongRefs(rc.getBoolean(CONFIG_CORE_SECTION,
  240.                 CONFIG_KEY_PACKED_GIT_USE_STRONGREFS,
  241.                 isPackedGitUseStrongRefs()));
  242.         setPackedGitOpenFiles(rc.getInt(CONFIG_CORE_SECTION, null,
  243.                 CONFIG_KEY_PACKED_GIT_OPENFILES, getPackedGitOpenFiles()));
  244.         setPackedGitLimit(rc.getLong(CONFIG_CORE_SECTION, null,
  245.                 CONFIG_KEY_PACKED_GIT_LIMIT, getPackedGitLimit()));
  246.         setPackedGitWindowSize(rc.getInt(CONFIG_CORE_SECTION, null,
  247.                 CONFIG_KEY_PACKED_GIT_WINDOWSIZE, getPackedGitWindowSize()));
  248.         setPackedGitMMAP(rc.getBoolean(CONFIG_CORE_SECTION, null,
  249.                 CONFIG_KEY_PACKED_GIT_MMAP, isPackedGitMMAP()));
  250.         setDeltaBaseCacheLimit(rc.getInt(CONFIG_CORE_SECTION, null,
  251.                 CONFIG_KEY_DELTA_BASE_CACHE_LIMIT, getDeltaBaseCacheLimit()));

  252.         long maxMem = Runtime.getRuntime().maxMemory();
  253.         long sft = rc.getLong(CONFIG_CORE_SECTION, null,
  254.                 CONFIG_KEY_STREAM_FILE_TRESHOLD, getStreamFileThreshold());
  255.         sft = Math.min(sft, maxMem / 4); // don't use more than 1/4 of the heap
  256.         sft = Math.min(sft, Integer.MAX_VALUE); // cannot exceed array length
  257.         setStreamFileThreshold((int) sft);
  258.         return this;
  259.     }

  260.     /**
  261.      * Install this configuration as the live settings.
  262.      * <p>
  263.      * The new configuration is applied immediately. If the new limits are
  264.      * smaller than what is currently cached, older entries will be purged
  265.      * as soon as possible to allow the cache to meet the new limit.
  266.      *
  267.      * @since 3.0
  268.      */
  269.     @SuppressWarnings("deprecation")
  270.     public void install() {
  271.         WindowCache.reconfigure(this);
  272.     }
  273. }