View Javadoc
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  
11  package org.eclipse.jgit.storage.file;
12  
13  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
14  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_DELTA_BASE_CACHE_LIMIT;
15  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_LIMIT;
16  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_MMAP;
17  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_OPENFILES;
18  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_WINDOWSIZE;
19  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_STREAM_FILE_TRESHOLD;
20  import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_USE_STRONGREFS;
21  
22  import org.eclipse.jgit.internal.storage.file.WindowCache;
23  import org.eclipse.jgit.lib.Config;
24  import org.eclipse.jgit.storage.pack.PackConfig;
25  
26  /**
27   * Configuration parameters for JVM-wide buffer cache used by JGit.
28   */
29  public class WindowCacheConfig {
30  	/** 1024 (number of bytes in one kibibyte/kilobyte) */
31  	public static final int KB = 1024;
32  
33  	/** 1024 {@link #KB} (number of bytes in one mebibyte/megabyte) */
34  	public static final int MB = 1024 * KB;
35  
36  	private int packedGitOpenFiles;
37  
38  	private long packedGitLimit;
39  
40  	private boolean useStrongRefs;
41  
42  	private int packedGitWindowSize;
43  
44  	private boolean packedGitMMAP;
45  
46  	private int deltaBaseCacheLimit;
47  
48  	private int streamFileThreshold;
49  
50  	private boolean exposeStats;
51  
52  	/**
53  	 * Create a default configuration.
54  	 */
55  	public WindowCacheConfig() {
56  		packedGitOpenFiles = 128;
57  		packedGitLimit = 10 * MB;
58  		useStrongRefs = false;
59  		packedGitWindowSize = 8 * KB;
60  		packedGitMMAP = false;
61  		deltaBaseCacheLimit = 10 * MB;
62  		streamFileThreshold = PackConfig.DEFAULT_BIG_FILE_THRESHOLD;
63  		exposeStats = true;
64  	}
65  
66  	/**
67  	 * Get maximum number of streams to open at a time.
68  	 *
69  	 * @return maximum number of streams to open at a time. Open packs count
70  	 *         against the process limits. <b>Default is 128.</b>
71  	 */
72  	public int getPackedGitOpenFiles() {
73  		return packedGitOpenFiles;
74  	}
75  
76  	/**
77  	 * Set maximum number of streams to open at a time.
78  	 *
79  	 * @param fdLimit
80  	 *            maximum number of streams to open at a time. Open packs count
81  	 *            against the process limits
82  	 */
83  	public void setPackedGitOpenFiles(int fdLimit) {
84  		packedGitOpenFiles = fdLimit;
85  	}
86  
87  	/**
88  	 * Get maximum number bytes of heap memory to dedicate to caching pack file
89  	 * data.
90  	 *
91  	 * @return maximum number bytes of heap memory to dedicate to caching pack
92  	 *         file data. <b>Default is 10 MB.</b>
93  	 */
94  	public long getPackedGitLimit() {
95  		return packedGitLimit;
96  	}
97  
98  	/**
99  	 * Set maximum number bytes of heap memory to dedicate to caching pack file
100 	 * data.
101 	 *
102 	 * @param newLimit
103 	 *            maximum number bytes of heap memory to dedicate to caching
104 	 *            pack file data.
105 	 */
106 	public void setPackedGitLimit(long newLimit) {
107 		packedGitLimit = newLimit;
108 	}
109 
110 	/**
111 	 * Get whether the window cache should use strong references or
112 	 * SoftReferences
113 	 *
114 	 * @return {@code true} if the window cache should use strong references,
115 	 *         otherwise it will use {@link java.lang.ref.SoftReference}s
116 	 * @since 5.1.13
117 	 */
118 	public boolean isPackedGitUseStrongRefs() {
119 		return useStrongRefs;
120 	}
121 
122 	/**
123 	 * Set if the cache should use strong refs or soft refs
124 	 *
125 	 * @param useStrongRefs
126 	 *            if @{code true} the cache strongly references cache pages
127 	 *            otherwise it uses {@link java.lang.ref.SoftReference}s which
128 	 *            can be evicted by the Java gc if heap is almost full
129 	 * @since 5.1.13
130 	 */
131 	public void setPackedGitUseStrongRefs(boolean useStrongRefs) {
132 		this.useStrongRefs = useStrongRefs;
133 	}
134 
135 	/**
136 	 * Get size in bytes of a single window mapped or read in from the pack
137 	 * file.
138 	 *
139 	 * @return size in bytes of a single window mapped or read in from the pack
140 	 *         file. <b>Default is 8 KB.</b>
141 	 */
142 	public int getPackedGitWindowSize() {
143 		return packedGitWindowSize;
144 	}
145 
146 	/**
147 	 * Set size in bytes of a single window read in from the pack file.
148 	 *
149 	 * @param newSize
150 	 *            size in bytes of a single window read in from the pack file.
151 	 */
152 	public void setPackedGitWindowSize(int newSize) {
153 		packedGitWindowSize = newSize;
154 	}
155 
156 	/**
157 	 * Whether to use Java NIO virtual memory mapping for windows
158 	 *
159 	 * @return {@code true} enables use of Java NIO virtual memory mapping for
160 	 *         windows; false reads entire window into a byte[] with standard
161 	 *         read calls. <b>Default false.</b>
162 	 */
163 	public boolean isPackedGitMMAP() {
164 		return packedGitMMAP;
165 	}
166 
167 	/**
168 	 * Set whether to enable use of Java NIO virtual memory mapping for windows
169 	 *
170 	 * @param usemmap
171 	 *            {@code true} enables use of Java NIO virtual memory mapping
172 	 *            for windows; false reads entire window into a byte[] with
173 	 *            standard read calls.
174 	 */
175 	public void setPackedGitMMAP(boolean usemmap) {
176 		packedGitMMAP = usemmap;
177 	}
178 
179 	/**
180 	 * Get maximum number of bytes to cache in delta base cache for inflated,
181 	 * recently accessed objects, without delta chains.
182 	 *
183 	 * @return maximum number of bytes to cache in delta base cache for
184 	 *         inflated, recently accessed objects, without delta chains.
185 	 *         <b>Default 10 MB.</b>
186 	 */
187 	public int getDeltaBaseCacheLimit() {
188 		return deltaBaseCacheLimit;
189 	}
190 
191 	/**
192 	 * Set maximum number of bytes to cache in delta base cache for inflated,
193 	 * recently accessed objects, without delta chains.
194 	 *
195 	 * @param newLimit
196 	 *            maximum number of bytes to cache in delta base cache for
197 	 *            inflated, recently accessed objects, without delta chains.
198 	 */
199 	public void setDeltaBaseCacheLimit(int newLimit) {
200 		deltaBaseCacheLimit = newLimit;
201 	}
202 
203 	/**
204 	 * Get the size threshold beyond which objects must be streamed.
205 	 *
206 	 * @return the size threshold beyond which objects must be streamed.
207 	 */
208 	public int getStreamFileThreshold() {
209 		return streamFileThreshold;
210 	}
211 
212 	/**
213 	 * Set new byte limit for objects that must be streamed.
214 	 *
215 	 * @param newLimit
216 	 *            new byte limit for objects that must be streamed. Objects
217 	 *            smaller than this size can be obtained as a contiguous byte
218 	 *            array, while objects bigger than this size require using an
219 	 *            {@link org.eclipse.jgit.lib.ObjectStream}.
220 	 */
221 	public void setStreamFileThreshold(int newLimit) {
222 		streamFileThreshold = newLimit;
223 	}
224 
225 	/**
226 	 * Tell whether the statistics JMX bean should be automatically registered.
227 	 * <p>
228 	 * Registration of that bean via JMX is additionally subject to a boolean
229 	 * JGit-specific user config "jmx.WindowCacheStats". The bean will be
230 	 * registered only if this user config is {@code true} <em>and</em>
231 	 * {@code getExposeStatsViaJmx() == true}.
232 	 * </p>
233 	 * <p>
234 	 * By default, this returns {@code true} unless changed via
235 	 * {@link #setExposeStatsViaJmx(boolean)}.
236 	 *
237 	 * @return whether to expose WindowCacheStats statistics via JMX upon
238 	 *         {@link #install()}
239 	 * @since 5.8
240 	 */
241 	public boolean getExposeStatsViaJmx() {
242 		return exposeStats;
243 	}
244 
245 	/**
246 	 * Defines whether the statistics JMX MBean should be automatically set up.
247 	 * (By default {@code true}.) If set to {@code false}, the JMX monitoring
248 	 * bean is not registered.
249 	 *
250 	 * @param expose
251 	 *            whether to register the JMX Bean
252 	 * @since 5.8
253 	 */
254 	public void setExposeStatsViaJmx(boolean expose) {
255 		exposeStats = expose;
256 	}
257 
258 	/**
259 	 * Update properties by setting fields from the configuration.
260 	 * <p>
261 	 * If a property is not defined in the configuration, then it is left
262 	 * unmodified.
263 	 *
264 	 * @param rc
265 	 *            configuration to read properties from.
266 	 * @return {@code this}.
267 	 * @since 3.0
268 	 */
269 	public WindowCacheConfig fromConfig(Config rc) {
270 		setPackedGitUseStrongRefs(rc.getBoolean(CONFIG_CORE_SECTION,
271 				CONFIG_KEY_PACKED_GIT_USE_STRONGREFS,
272 				isPackedGitUseStrongRefs()));
273 		setPackedGitOpenFiles(rc.getInt(CONFIG_CORE_SECTION, null,
274 				CONFIG_KEY_PACKED_GIT_OPENFILES, getPackedGitOpenFiles()));
275 		setPackedGitLimit(rc.getLong(CONFIG_CORE_SECTION, null,
276 				CONFIG_KEY_PACKED_GIT_LIMIT, getPackedGitLimit()));
277 		setPackedGitWindowSize(rc.getInt(CONFIG_CORE_SECTION, null,
278 				CONFIG_KEY_PACKED_GIT_WINDOWSIZE, getPackedGitWindowSize()));
279 		setPackedGitMMAP(rc.getBoolean(CONFIG_CORE_SECTION, null,
280 				CONFIG_KEY_PACKED_GIT_MMAP, isPackedGitMMAP()));
281 		setDeltaBaseCacheLimit(rc.getInt(CONFIG_CORE_SECTION, null,
282 				CONFIG_KEY_DELTA_BASE_CACHE_LIMIT, getDeltaBaseCacheLimit()));
283 
284 		long maxMem = Runtime.getRuntime().maxMemory();
285 		long sft = rc.getLong(CONFIG_CORE_SECTION, null,
286 				CONFIG_KEY_STREAM_FILE_TRESHOLD, getStreamFileThreshold());
287 		sft = Math.min(sft, maxMem / 4); // don't use more than 1/4 of the heap
288 		sft = Math.min(sft, Integer.MAX_VALUE); // cannot exceed array length
289 		setStreamFileThreshold((int) sft);
290 		return this;
291 	}
292 
293 	/**
294 	 * Install this configuration as the live settings.
295 	 * <p>
296 	 * The new configuration is applied immediately. If the new limits are
297 	 * smaller than what is currently cached, older entries will be purged
298 	 * as soon as possible to allow the cache to meet the new limit.
299 	 *
300 	 * @since 3.0
301 	 */
302 	@SuppressWarnings("deprecation")
303 	public void install() {
304 		WindowCache.reconfigure(this);
305 	}
306 }