Пример #1
0
        /*
         * Add current code to the cache
         */
        private CachedCodeEntry CacheCode(CachedCodeEntryKey key)
        {
            CachedCodeEntry newcached = null;

            lock (s_livecode)
            {
                // first look for it in the cache and move it to the head
                for (LinkedListNode <CachedCodeEntry> current = s_livecode.First; current != null; current = current.Next)
                {
                    if (current.Value._key == key)
                    {
                        s_livecode.Remove(current);
                        s_livecode.AddFirst(current);
                        return(current.Value);
                    }
                }

                // it wasn't in the cache, so we'll add a new one.  Shortcut out for the case where cacheSize is zero.
                if (s_cacheSize != 0)
                {
                    newcached = new CachedCodeEntry(key, capnames, capslist, _code, caps, capsize, _runnerref, _replref);
                    s_livecode.AddFirst(newcached);
                    if (s_livecode.Count > s_cacheSize)
                    {
                        s_livecode.RemoveLast();
                    }
                }
            }

            return(newcached);
        }
Пример #2
0
        /*
         * 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);
        }
Пример #3
0
        internal CachedCodeEntry(CachedCodeEntryKey key, Dictionary <string, int> capnames, string[] capslist, RegexCode code, Dictionary <int, int> caps, int capsize, ExclusiveReference runner, SharedReference repl)
        {
            _key      = key;
            _capnames = capnames;
            _capslist = capslist;

            _code    = code;
            _caps    = caps;
            _capsize = capsize;

            _runnerref = runner;
            _replref   = repl;
        }
Пример #4
0
        /*
         * 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();
            }
        }
Пример #5
0
        /*
         * Find code cache based on options+pattern
         */
        private static CachedCodeEntry LookupCachedAndUpdate(CachedCodeEntryKey key)
        {
            lock (s_livecode)
            {
                for (LinkedListNode <CachedCodeEntry> current = s_livecode.First; current != null; current = current.Next)
                {
                    if (current.Value._key == key)
                    {
                        // If we find an entry in the cache, move it to the head at the same time.
                        s_livecode.Remove(current);
                        s_livecode.AddFirst(current);
                        return(current.Value);
                    }
                }
            }

            return(null);
        }
Пример #6
0
        private Regex(string pattern, RegexOptions options, TimeSpan matchTimeout, bool useCache)
        {
            RegexTree       tree;
            CachedCodeEntry cached     = null;
            string          cultureKey = null;

            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);

            // 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.
            if ((options & RegexOptions.CultureInvariant) != 0)
            {
                cultureKey = CultureInfo.InvariantCulture.ToString(); // "English (United States)"
            }
            else
            {
                cultureKey = CultureInfo.CurrentCulture.ToString();
            }

            var key = new CachedCodeEntryKey(options, cultureKey, pattern);
            cached = LookupCachedAndUpdate(key);

            this.pattern = pattern;
            roptions     = options;

            internalMatchTimeout = matchTimeout;

            if (cached == null)
            {
                // Parse the input
                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();

                tree = null;
                if (useCache)
                {
                    cached = 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;
            }
        }