118 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| 	MIT License http://www.opensource.org/licenses/mit-license.php
 | |
| 	Author Mark Knichel @mknichel
 | |
| */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| let dualStringBufferCaching = true;
 | |
| 
 | |
| /**
 | |
|  * @returns {boolean} Whether the optimization to cache copies of both the
 | |
|  * string and buffer version of source content is enabled. This is enabled by
 | |
|  * default to improve performance but can consume more memory since values are
 | |
|  * stored twice.
 | |
|  */
 | |
| function isDualStringBufferCachingEnabled() {
 | |
| 	return dualStringBufferCaching;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Enables an optimization to save both string and buffer in memory to avoid
 | |
|  * repeat conversions between the two formats when they are requested. This
 | |
|  * is enabled by default. This option can improve performance but can consume
 | |
|  * additional memory since values are stored twice.
 | |
|  * @returns {void}
 | |
|  */
 | |
| function enableDualStringBufferCaching() {
 | |
| 	dualStringBufferCaching = true;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Disables the optimization to save both string and buffer in memory. This
 | |
|  * may increase performance but should reduce memory usage in the Webpack
 | |
|  * compiler.
 | |
|  * @returns {void}
 | |
|  */
 | |
| function disableDualStringBufferCaching() {
 | |
| 	dualStringBufferCaching = false;
 | |
| }
 | |
| 
 | |
| const interningStringMap = new Map();
 | |
| 
 | |
| let enableStringInterningRefCount = 0;
 | |
| 
 | |
| /**
 | |
|  * @returns {boolean} value
 | |
|  */
 | |
| function isStringInterningEnabled() {
 | |
| 	return enableStringInterningRefCount > 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Starts a memory optimization to avoid repeat copies of the same string in
 | |
|  * memory by caching a single reference to the string. This can reduce memory
 | |
|  * usage if the same string is repeated many times in the compiler, such as
 | |
|  * when Webpack layers are used with the same files.
 | |
|  *
 | |
|  * {@link exitStringInterningRange} should be called when string interning is
 | |
|  * no longer necessary to free up the memory used by the interned strings. If
 | |
|  * {@link enterStringInterningRange} has been called multiple times, then
 | |
|  * this method may not immediately free all the memory until
 | |
|  * {@link exitStringInterningRange} has been called to end all string
 | |
|  * interning ranges.
 | |
|  * @returns {void}
 | |
|  */
 | |
| function enterStringInterningRange() {
 | |
| 	enableStringInterningRefCount++;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Stops the current string interning range. Once all string interning ranges
 | |
|  * have been exited, this method will free all the memory used by the interned
 | |
|  * strings. This method should be called once for each time that
 | |
|  * {@link enterStringInterningRange} was called.
 | |
|  * @returns {void}
 | |
|  */
 | |
| function exitStringInterningRange() {
 | |
| 	if (--enableStringInterningRefCount <= 0) {
 | |
| 		interningStringMap.clear();
 | |
| 		enableStringInterningRefCount = 0;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Saves the string in a map to ensure that only one copy of the string exists
 | |
|  * in memory at a given time. This is controlled by {@link enableStringInterning}
 | |
|  * and {@link disableStringInterning}. Callers are expect to manage the memory
 | |
|  * of the interned strings by calling {@link disableStringInterning} after the
 | |
|  * compiler no longer needs to save the interned memory.
 | |
|  * @param {string} str A string to be interned.
 | |
|  * @returns {string} The original string or a reference to an existing string of the same value if it has already been interned.
 | |
|  */
 | |
| function internString(str) {
 | |
| 	if (
 | |
| 		!isStringInterningEnabled() ||
 | |
| 		!str ||
 | |
| 		str.length < 128 ||
 | |
| 		typeof str !== "string"
 | |
| 	) {
 | |
| 		return str;
 | |
| 	}
 | |
| 	let internedString = interningStringMap.get(str);
 | |
| 	if (internedString === undefined) {
 | |
| 		internedString = str;
 | |
| 		interningStringMap.set(str, internedString);
 | |
| 	}
 | |
| 	return internedString;
 | |
| }
 | |
| 
 | |
| module.exports = {
 | |
| 	disableDualStringBufferCaching,
 | |
| 	enableDualStringBufferCaching,
 | |
| 	internString,
 | |
| 	isDualStringBufferCachingEnabled,
 | |
| 	enterStringInterningRange,
 | |
| 	exitStringInterningRange,
 | |
| };
 |