DfsBlockCacheConfig.java

  1. /*
  2.  * Copyright (C) 2011, 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.internal.storage.dfs;

  11. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
  12. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_DFS_SECTION;
  13. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BLOCK_LIMIT;
  14. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BLOCK_SIZE;
  15. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_CONCURRENCY_LEVEL;
  16. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_STREAM_RATIO;

  17. import java.text.MessageFormat;
  18. import java.util.function.Consumer;

  19. import org.eclipse.jgit.internal.JGitText;
  20. import org.eclipse.jgit.lib.Config;

  21. /**
  22.  * Configuration parameters for
  23.  * {@link org.eclipse.jgit.internal.storage.dfs.DfsBlockCache}.
  24.  */
  25. public class DfsBlockCacheConfig {
  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 long blockLimit;
  31.     private int blockSize;
  32.     private double streamRatio;
  33.     private int concurrencyLevel;

  34.     private Consumer<Long> refLock;

  35.     /**
  36.      * Create a default configuration.
  37.      */
  38.     public DfsBlockCacheConfig() {
  39.         setBlockLimit(32 * MB);
  40.         setBlockSize(64 * KB);
  41.         setStreamRatio(0.30);
  42.         setConcurrencyLevel(32);
  43.     }

  44.     /**
  45.      * Get maximum number bytes of heap memory to dedicate to caching pack file
  46.      * data.
  47.      *
  48.      * @return maximum number bytes of heap memory to dedicate to caching pack
  49.      *         file data. <b>Default is 32 MB.</b>
  50.      */
  51.     public long getBlockLimit() {
  52.         return blockLimit;
  53.     }

  54.     /**
  55.      * Set maximum number bytes of heap memory to dedicate to caching pack file
  56.      * data.
  57.      * <p>
  58.      * It is strongly recommended to set the block limit to be an integer multiple
  59.      * of the block size. This constraint is not enforced by this method (since
  60.      * it may be called before {@link #setBlockSize(int)}), but it is enforced by
  61.      * {@link #fromConfig(Config)}.
  62.      *
  63.      * @param newLimit
  64.      *            maximum number bytes of heap memory to dedicate to caching
  65.      *            pack file data; must be positive.
  66.      * @return {@code this}
  67.      */
  68.     public DfsBlockCacheConfig setBlockLimit(long newLimit) {
  69.         if (newLimit <= 0) {
  70.             throw new IllegalArgumentException(MessageFormat.format(
  71.                     JGitText.get().blockLimitNotPositive,
  72.                     Long.valueOf(newLimit)));
  73.         }
  74.         blockLimit = newLimit;
  75.         return this;
  76.     }

  77.     /**
  78.      * Get size in bytes of a single window mapped or read in from the pack
  79.      * file.
  80.      *
  81.      * @return size in bytes of a single window mapped or read in from the pack
  82.      *         file. <b>Default is 64 KB.</b>
  83.      */
  84.     public int getBlockSize() {
  85.         return blockSize;
  86.     }

  87.     /**
  88.      * Set size in bytes of a single window read in from the pack file.
  89.      *
  90.      * @param newSize
  91.      *            size in bytes of a single window read in from the pack file.
  92.      *            The value must be a power of 2.
  93.      * @return {@code this}
  94.      */
  95.     public DfsBlockCacheConfig setBlockSize(int newSize) {
  96.         int size = Math.max(512, newSize);
  97.         if ((size & (size - 1)) != 0) {
  98.             throw new IllegalArgumentException(
  99.                     JGitText.get().blockSizeNotPowerOf2);
  100.         }
  101.         blockSize = size;
  102.         return this;
  103.     }

  104.     /**
  105.      * Get the estimated number of threads concurrently accessing the cache.
  106.      *
  107.      * @return the estimated number of threads concurrently accessing the cache.
  108.      *         <b>Default is 32.</b>
  109.      */
  110.     public int getConcurrencyLevel() {
  111.         return concurrencyLevel;
  112.     }

  113.     /**
  114.      * Set the estimated number of threads concurrently accessing the cache.
  115.      *
  116.      * @param newConcurrencyLevel
  117.      *            the estimated number of threads concurrently accessing the
  118.      *            cache.
  119.      * @return {@code this}
  120.      */
  121.     public DfsBlockCacheConfig setConcurrencyLevel(
  122.             final int newConcurrencyLevel) {
  123.         concurrencyLevel = newConcurrencyLevel;
  124.         return this;
  125.     }

  126.     /**
  127.      * Get highest percentage of {@link #getBlockLimit()} a single pack can
  128.      * occupy while being copied by the pack reuse strategy.
  129.      *
  130.      * @return highest percentage of {@link #getBlockLimit()} a single pack can
  131.      *         occupy while being copied by the pack reuse strategy. <b>Default
  132.      *         is 0.30, or 30%</b>.
  133.      */
  134.     public double getStreamRatio() {
  135.         return streamRatio;
  136.     }

  137.     /**
  138.      * Set percentage of cache to occupy with a copied pack.
  139.      *
  140.      * @param ratio
  141.      *            percentage of cache to occupy with a copied pack.
  142.      * @return {@code this}
  143.      */
  144.     public DfsBlockCacheConfig setStreamRatio(double ratio) {
  145.         streamRatio = Math.max(0, Math.min(ratio, 1.0));
  146.         return this;
  147.     }

  148.     /**
  149.      * Get the consumer of the object reference lock wait time in milliseconds.
  150.      *
  151.      * @return consumer of wait time in milliseconds.
  152.      */
  153.     public Consumer<Long> getRefLockWaitTimeConsumer() {
  154.         return refLock;
  155.     }

  156.     /**
  157.      * Set the consumer for lock wait time.
  158.      *
  159.      * @param c
  160.      *            consumer of wait time in milliseconds.
  161.      * @return {@code this}
  162.      */
  163.     public DfsBlockCacheConfig setRefLockWaitTimeConsumer(Consumer<Long> c) {
  164.         refLock = c;
  165.         return this;
  166.     }

  167.     /**
  168.      * Update properties by setting fields from the configuration.
  169.      * <p>
  170.      * If a property is not defined in the configuration, then it is left
  171.      * unmodified.
  172.      * <p>
  173.      * Enforces certain constraints on the combination of settings in the config,
  174.      * for example that the block limit is a multiple of the block size.
  175.      *
  176.      * @param rc
  177.      *            configuration to read properties from.
  178.      * @return {@code this}
  179.      */
  180.     public DfsBlockCacheConfig fromConfig(Config rc) {
  181.         long cfgBlockLimit = rc.getLong(
  182.                 CONFIG_CORE_SECTION,
  183.                 CONFIG_DFS_SECTION,
  184.                 CONFIG_KEY_BLOCK_LIMIT,
  185.                 getBlockLimit());
  186.         int cfgBlockSize = rc.getInt(
  187.                 CONFIG_CORE_SECTION,
  188.                 CONFIG_DFS_SECTION,
  189.                 CONFIG_KEY_BLOCK_SIZE,
  190.                 getBlockSize());
  191.         if (cfgBlockLimit % cfgBlockSize != 0) {
  192.             throw new IllegalArgumentException(MessageFormat.format(
  193.                     JGitText.get().blockLimitNotMultipleOfBlockSize,
  194.                     Long.valueOf(cfgBlockLimit),
  195.                     Long.valueOf(cfgBlockSize)));
  196.         }

  197.         setBlockLimit(cfgBlockLimit);
  198.         setBlockSize(cfgBlockSize);

  199.         setConcurrencyLevel(rc.getInt(
  200.                 CONFIG_CORE_SECTION,
  201.                 CONFIG_DFS_SECTION,
  202.                 CONFIG_KEY_CONCURRENCY_LEVEL,
  203.                 getConcurrencyLevel()));

  204.         String v = rc.getString(
  205.                 CONFIG_CORE_SECTION,
  206.                 CONFIG_DFS_SECTION,
  207.                 CONFIG_KEY_STREAM_RATIO);
  208.         if (v != null) {
  209.             try {
  210.                 setStreamRatio(Double.parseDouble(v));
  211.             } catch (NumberFormatException e) {
  212.                 throw new IllegalArgumentException(MessageFormat.format(
  213.                         JGitText.get().enumValueNotSupported3,
  214.                         CONFIG_CORE_SECTION,
  215.                         CONFIG_DFS_SECTION,
  216.                         CONFIG_KEY_STREAM_RATIO, v), e);
  217.             }
  218.         }
  219.         return this;
  220.     }
  221. }