/* * Find code cache based on options+pattern */ static CachedCodeEntry LookupCachedAndUpdate(CachedCodeEntryKey key) { s_cacheLock.EnterReadLock(); if (s_cache.TryGetValue(key, out CachedCodeEntry entry)) { entry._usedstamp = s_recentstamp; } s_cacheLock.ExitReadLock(); // return(entry); }
/* * Add current code to the cache */ private void CacheCode(CachedCodeEntryKey key) { var newcached = new CachedCodeEntry(capnames, capslist, _code, caps, capsize, _runnerref, _replref) { _usedstamp = s_recentstamp++, }; s_cacheLock.EnterWriteLock(); s_cache[key] = newcached; s_cacheLock.ExitWriteLock(); if (s_cache.Count > s_cacheSize) { DropEntryFromCache(); } }
private Regex(string pattern, RegexOptions options, TimeSpan matchTimeout, bool useCache) { // validate parameters: if (pattern == null) { throw new ArgumentNullException(nameof(pattern)); } if (options < RegexOptions.None || (((int)options) >> MaxOptionShift) != 0) { throw new ArgumentOutOfRangeException(nameof(options)); } if ((options & RegexOptions.ECMAScript) != 0 && (options & ~(RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant #if DEBUG | RegexOptions.Debug #endif )) != 0) { throw new ArgumentOutOfRangeException(nameof(options)); } ValidateMatchTimeout(matchTimeout); this.pattern = pattern; this.roptions = options; // Try to look up this regex in the cache. We do this regardless of whether useCache is true since there's // really no reason not to. var key = new CachedCodeEntryKey(options, pattern); var cached = LookupCachedAndUpdate(key); internalMatchTimeout = matchTimeout; if (cached == null) { // Parse the input var tree = RegexParser.Parse(pattern, roptions); // Extract the relevant information capnames = tree.CapNames; capslist = tree.CapsList; _code = RegexWriter.Write(tree); caps = _code._caps; capsize = _code._capsize; InitializeReferences(); if (useCache) { CacheCode(key); } } else { caps = cached._caps; capnames = cached._capnames; capslist = cached._capslist; capsize = cached._capsize; _code = cached._code; _runnerref = cached._runnerref; _replref = cached._replref; _refsInitialized = true; } }