Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

WindowCacheConfig.java 9.9KB

Increase core.streamFileThreshold default to 50 MiB Projects like org.eclipse.mdt contain large XML files about 6 MiB in size. So does the Android project platform/frameworks/base. Doing a clone of either project with JGit takes forever to checkout the files into the working directory, because delta decompression tends to be very expensive as we need to constantly reposition the base stream for each copy instruction. This can be made worse by a very bad ordering of offsets, possibly due to an XML editor that doesn't preserve the order of elements in the file very well. Increasing the threshold to the same limit PackWriter uses when doing delta compression (50 MiB) permits a default configured JGit to decompress these XML file objects using the faster random-access arrays, rather than re-seeking through an inflate stream, significantly reducing checkout time after a clone. Since this new limit may be dangerously close to the JVM maximum heap size, every allocation attempt is now wrapped in a try/catch so that JGit can degrade by switching to the large object stream mode when the allocation is refused. It will run slower, but the operation will still complete. The large stream mode will run very well for big objects that aren't delta compressed, and is acceptable for delta compressed objects that are using only forward referencing copy instructions. Copies using prior offsets are still going to be horrible, and there is nothing we can do about it except increase core.streamFileThreshold. We might in the future want to consider changing the way the delta generators work in JGit and native C Git to avoid prior offsets once an object reaches a certain size, even if that causes the delta instruction stream to be slightly larger. Unfortunately native C Git won't want to do that until its also able to stream objects rather than malloc them as contiguous blocks. Change-Id: Ief7a3896afce15073e80d3691bed90c6a3897307 Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
il y a 13 ans
Increase core.streamFileThreshold default to 50 MiB Projects like org.eclipse.mdt contain large XML files about 6 MiB in size. So does the Android project platform/frameworks/base. Doing a clone of either project with JGit takes forever to checkout the files into the working directory, because delta decompression tends to be very expensive as we need to constantly reposition the base stream for each copy instruction. This can be made worse by a very bad ordering of offsets, possibly due to an XML editor that doesn't preserve the order of elements in the file very well. Increasing the threshold to the same limit PackWriter uses when doing delta compression (50 MiB) permits a default configured JGit to decompress these XML file objects using the faster random-access arrays, rather than re-seeking through an inflate stream, significantly reducing checkout time after a clone. Since this new limit may be dangerously close to the JVM maximum heap size, every allocation attempt is now wrapped in a try/catch so that JGit can degrade by switching to the large object stream mode when the allocation is refused. It will run slower, but the operation will still complete. The large stream mode will run very well for big objects that aren't delta compressed, and is acceptable for delta compressed objects that are using only forward referencing copy instructions. Copies using prior offsets are still going to be horrible, and there is nothing we can do about it except increase core.streamFileThreshold. We might in the future want to consider changing the way the delta generators work in JGit and native C Git to avoid prior offsets once an object reaches a certain size, even if that causes the delta instruction stream to be slightly larger. Unfortunately native C Git won't want to do that until its also able to stream objects rather than malloc them as contiguous blocks. Change-Id: Ief7a3896afce15073e80d3691bed90c6a3897307 Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
il y a 13 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright (C) 2009, Google Inc.
  3. * and other copyright owners as documented in the project's IP log.
  4. *
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Distribution License v1.0 which
  7. * accompanies this distribution, is reproduced below, and is
  8. * available at http://www.eclipse.org/org/documents/edl-v10.php
  9. *
  10. * All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or
  13. * without modification, are permitted provided that the following
  14. * conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. *
  19. * - Redistributions in binary form must reproduce the above
  20. * copyright notice, this list of conditions and the following
  21. * disclaimer in the documentation and/or other materials provided
  22. * with the distribution.
  23. *
  24. * - Neither the name of the Eclipse Foundation, Inc. nor the
  25. * names of its contributors may be used to endorse or promote
  26. * products derived from this software without specific prior
  27. * written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  30. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  31. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  34. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  38. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  41. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42. */
  43. package org.eclipse.jgit.storage.file;
  44. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
  45. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_BASE_CACHE_LIMIT;
  46. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_LIMIT;
  47. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_MMAP;
  48. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_OPENFILES;
  49. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_WINDOWSIZE;
  50. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_STREAM_FILE_TRESHOLD;
  51. import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_USE_STRONGREFS;
  52. import org.eclipse.jgit.internal.storage.file.WindowCache;
  53. import org.eclipse.jgit.lib.Config;
  54. import org.eclipse.jgit.storage.pack.PackConfig;
  55. /**
  56. * Configuration parameters for JVM-wide buffer cache used by JGit.
  57. */
  58. public class WindowCacheConfig {
  59. /** 1024 (number of bytes in one kibibyte/kilobyte) */
  60. public static final int KB = 1024;
  61. /** 1024 {@link #KB} (number of bytes in one mebibyte/megabyte) */
  62. public static final int MB = 1024 * KB;
  63. private int packedGitOpenFiles;
  64. private long packedGitLimit;
  65. private boolean useStrongRefs;
  66. private int packedGitWindowSize;
  67. private boolean packedGitMMAP;
  68. private int deltaBaseCacheLimit;
  69. private int streamFileThreshold;
  70. /**
  71. * Create a default configuration.
  72. */
  73. public WindowCacheConfig() {
  74. packedGitOpenFiles = 128;
  75. packedGitLimit = 10 * MB;
  76. useStrongRefs = false;
  77. packedGitWindowSize = 8 * KB;
  78. packedGitMMAP = false;
  79. deltaBaseCacheLimit = 10 * MB;
  80. streamFileThreshold = PackConfig.DEFAULT_BIG_FILE_THRESHOLD;
  81. }
  82. /**
  83. * Get maximum number of streams to open at a time.
  84. *
  85. * @return maximum number of streams to open at a time. Open packs count
  86. * against the process limits. <b>Default is 128.</b>
  87. */
  88. public int getPackedGitOpenFiles() {
  89. return packedGitOpenFiles;
  90. }
  91. /**
  92. * Set maximum number of streams to open at a time.
  93. *
  94. * @param fdLimit
  95. * maximum number of streams to open at a time. Open packs count
  96. * against the process limits
  97. */
  98. public void setPackedGitOpenFiles(int fdLimit) {
  99. packedGitOpenFiles = fdLimit;
  100. }
  101. /**
  102. * Get maximum number bytes of heap memory to dedicate to caching pack file
  103. * data.
  104. *
  105. * @return maximum number bytes of heap memory to dedicate to caching pack
  106. * file data. <b>Default is 10 MB.</b>
  107. */
  108. public long getPackedGitLimit() {
  109. return packedGitLimit;
  110. }
  111. /**
  112. * Set maximum number bytes of heap memory to dedicate to caching pack file
  113. * data.
  114. *
  115. * @param newLimit
  116. * maximum number bytes of heap memory to dedicate to caching
  117. * pack file data.
  118. */
  119. public void setPackedGitLimit(long newLimit) {
  120. packedGitLimit = newLimit;
  121. }
  122. /**
  123. * Get whether the window cache should use strong references or
  124. * SoftReferences
  125. *
  126. * @return {@code true} if the window cache should use strong references,
  127. * otherwise it will use {@link java.lang.ref.SoftReference}s
  128. * @since 5.1.13
  129. */
  130. public boolean isPackedGitUseStrongRefs() {
  131. return useStrongRefs;
  132. }
  133. /**
  134. * Set if the cache should use strong refs or soft refs
  135. *
  136. * @param useStrongRefs
  137. * if @{code true} the cache strongly references cache pages
  138. * otherwise it uses {@link java.lang.ref.SoftReference}s which
  139. * can be evicted by the Java gc if heap is almost full
  140. * @since 5.1.13
  141. */
  142. public void setPackedGitUseStrongRefs(boolean useStrongRefs) {
  143. this.useStrongRefs = useStrongRefs;
  144. }
  145. /**
  146. * Get size in bytes of a single window mapped or read in from the pack
  147. * file.
  148. *
  149. * @return size in bytes of a single window mapped or read in from the pack
  150. * file. <b>Default is 8 KB.</b>
  151. */
  152. public int getPackedGitWindowSize() {
  153. return packedGitWindowSize;
  154. }
  155. /**
  156. * Set size in bytes of a single window read in from the pack file.
  157. *
  158. * @param newSize
  159. * size in bytes of a single window read in from the pack file.
  160. */
  161. public void setPackedGitWindowSize(int newSize) {
  162. packedGitWindowSize = newSize;
  163. }
  164. /**
  165. * Whether to use Java NIO virtual memory mapping for windows
  166. *
  167. * @return {@code true} enables use of Java NIO virtual memory mapping for
  168. * windows; false reads entire window into a byte[] with standard
  169. * read calls. <b>Default false.</b>
  170. */
  171. public boolean isPackedGitMMAP() {
  172. return packedGitMMAP;
  173. }
  174. /**
  175. * Set whether to enable use of Java NIO virtual memory mapping for windows
  176. *
  177. * @param usemmap
  178. * {@code true} enables use of Java NIO virtual memory mapping
  179. * for windows; false reads entire window into a byte[] with
  180. * standard read calls.
  181. */
  182. public void setPackedGitMMAP(boolean usemmap) {
  183. packedGitMMAP = usemmap;
  184. }
  185. /**
  186. * Get maximum number of bytes to cache in delta base cache for inflated,
  187. * recently accessed objects, without delta chains.
  188. *
  189. * @return maximum number of bytes to cache in delta base cache for
  190. * inflated, recently accessed objects, without delta chains.
  191. * <b>Default 10 MB.</b>
  192. */
  193. public int getDeltaBaseCacheLimit() {
  194. return deltaBaseCacheLimit;
  195. }
  196. /**
  197. * Set maximum number of bytes to cache in delta base cache for inflated,
  198. * recently accessed objects, without delta chains.
  199. *
  200. * @param newLimit
  201. * maximum number of bytes to cache in delta base cache for
  202. * inflated, recently accessed objects, without delta chains.
  203. */
  204. public void setDeltaBaseCacheLimit(int newLimit) {
  205. deltaBaseCacheLimit = newLimit;
  206. }
  207. /**
  208. * Get the size threshold beyond which objects must be streamed.
  209. *
  210. * @return the size threshold beyond which objects must be streamed.
  211. */
  212. public int getStreamFileThreshold() {
  213. return streamFileThreshold;
  214. }
  215. /**
  216. * Set new byte limit for objects that must be streamed.
  217. *
  218. * @param newLimit
  219. * new byte limit for objects that must be streamed. Objects
  220. * smaller than this size can be obtained as a contiguous byte
  221. * array, while objects bigger than this size require using an
  222. * {@link org.eclipse.jgit.lib.ObjectStream}.
  223. */
  224. public void setStreamFileThreshold(int newLimit) {
  225. streamFileThreshold = newLimit;
  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. }