示例#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
        private CachedCodeEntry CacheCode(string key)
        {
            CachedCodeEntry entry = null;

            lock (livecode)
            {
                for (LinkedListNode <CachedCodeEntry> node = livecode.First; node != null; node = node.Next)
                {
                    if (node.Value._key == key)
                    {
                        livecode.Remove(node);
                        livecode.AddFirst(node);
                        return(node.Value);
                    }
                }
                if (cacheSize != 0)
                {
                    entry = new CachedCodeEntry(key, this.capnames, this.capslist, this.code, this.caps, this.capsize, this.runnerref, this.replref);
                    livecode.AddFirst(entry);
                    if (livecode.Count > cacheSize)
                    {
                        livecode.RemoveLast();
                    }
                }
            }
            return(entry);
        }
示例#3
0
        private CachedCodeEntry GetCachedCodeEntryInternal(CachedCodeEntryKey key, bool isToAdd)
        {
            lock (s_cache)
            {
                // first look for it in the cache and move it to the head
                CachedCodeEntry entry = LookupCachedAndPromote(key);
                // it wasn't in the cache, so we'll add a new one
                if (entry == null && isToAdd && s_cacheSize != 0) // check cache size again in case it changed
                {
                    entry = new CachedCodeEntry(key, capnames, capslist, _code, caps, capsize, _runnerref, _replref);
                    // put first in linked list:
                    if (s_cacheFirst != null)
                    {
                        SysDebug.Assert(s_cacheFirst.Next == null);
                        s_cacheFirst.Next = entry;
                        entry.Previous    = s_cacheFirst;
                    }
                    s_cacheFirst = entry;

                    s_cacheCount++;
                    if (s_cacheCount >= CacheDictionarySwitchLimit)
                    {
                        if (s_cacheCount == CacheDictionarySwitchLimit)
                        {
                            FillCacheDictionary();
                        }
                        else
                        {
                            s_cache.Add(key, entry);
                        }
                        SysDebug.Assert(s_cacheCount == s_cache.Count);
                    }

                    // update last in linked list:
                    if (s_cacheLast == null)
                    {
                        s_cacheLast = entry;
                    }
                    else if (s_cacheCount > s_cacheSize) // remove last
                    {
                        CachedCodeEntry last = s_cacheLast;
                        if (s_cacheCount >= CacheDictionarySwitchLimit)
                        {
                            SysDebug.Assert(s_cache[last.Key] == s_cacheLast);
                            s_cache.Remove(last.Key);
                        }

                        SysDebug.Assert(last.Previous == null);
                        SysDebug.Assert(last.Next != null);
                        SysDebug.Assert(last.Next.Previous == last);
                        last.Next.Previous = null;
                        s_cacheLast        = last.Next;
                        s_cacheCount--;
                    }
                }
                return(entry);
            }
        }
示例#4
0
        private void FillCacheDictionary()
        {
            s_cache.Clear();
            CachedCodeEntry next = s_cacheFirst;

            while (next != null)
            {
                s_cache.Add(next.Key, next);
                next = next.Previous;
            }
        }
示例#5
0
        [MethodImpl(MethodImplOptions.AggressiveInlining)] // Unprofitable inline - JIT overly pessimistic
        private static bool TryGetCacheValue(CachedCodeEntryKey key, out CachedCodeEntry entry)
        {
            if (s_cacheCount >= CacheDictionarySwitchLimit)
            {
                SysDebug.Assert((s_cacheFirst != null && s_cacheLast != null && s_cache.Count > 0) ||
                                (s_cacheFirst == null && s_cacheLast == null && s_cache.Count == 0),
                                "Linked list and Dict should be synchronized");
                return(s_cache.TryGetValue(key, out entry));
            }

            return(TryGetCacheValueSmall(key, out entry));
        }
示例#6
0
        // Add current code to the cache
        private CachedCodeEntry CacheCode(String key)
        {
            CachedCodeEntry newcached;

            newcached = new CachedCodeEntry(roptions, capnames, capslist, code, caps, capsize, runnerref, replref);

            lock (livecode) {
                livecode[key] = newcached;
            }

            return(newcached);
        }
示例#7
0
        private static bool TryGetCacheValueSmall(CachedCodeEntryKey key, out CachedCodeEntry entry)
        {
            entry = s_cacheFirst?.Previous; // first already checked
            while (entry != null)
            {
                if (entry.Key == key)
                {
                    return(true);
                }
                entry = entry.Previous;
            }

            return(false);
        }
示例#8
0
        private CachedCodeEntry GetCachedCode(CachedCodeEntryKey key, bool isToAdd)
        {
            // to avoid lock:
            CachedCodeEntry first = s_cacheFirst;

            if (first?.Key == key)
            {
                return(first);
            }
            if (s_cacheSize == 0)
            {
                return(null);
            }

            return(GetCachedCodeEntryInternal(key, isToAdd));
        }
示例#9
0
        private static CachedCodeEntry LookupCachedAndPromote(CachedCodeEntryKey key)
        {
            SysDebug.Assert(Monitor.IsEntered(s_cache));
            if (s_cacheFirst?.Key == key) // again check this as could have been promoted by other thread
            {
                return(s_cacheFirst);
            }

            if (TryGetCacheValue(key, out CachedCodeEntry entry))
            {
                // promote:
                SysDebug.Assert(s_cacheFirst != entry, "key should not get s_livecode_first");
                SysDebug.Assert(s_cacheFirst != null, "as Dict has at least one");
                SysDebug.Assert(s_cacheFirst.Next == null);
                SysDebug.Assert(s_cacheFirst.Previous != null);
                SysDebug.Assert(entry.Next != null, "not first so Next should exist");
                SysDebug.Assert(entry.Next.Previous == entry);
                if (s_cacheLast == entry)
                {
                    SysDebug.Assert(entry.Previous == null, "last");
                    s_cacheLast = entry.Next;
                }
                else
                {
                    SysDebug.Assert(entry.Previous != null, "in middle");
                    SysDebug.Assert(entry.Previous.Next == entry);
                    entry.Previous.Next = entry.Next;
                }
                entry.Next.Previous = entry.Previous;

                s_cacheFirst.Next = entry;
                entry.Previous    = s_cacheFirst;
                entry.Next        = null;
                s_cacheFirst      = entry;
            }

            return(entry);
        }
示例#10
0
文件: regex.cs 项目: ArildF/masters
        // Add current code to the cache
        private CachedCodeEntry CacheCode(String key) {
            CachedCodeEntry newcached;

            newcached = new CachedCodeEntry(roptions, capnames, capslist, code, caps, capsize, runnerref, replref);

            lock (livecode) {
                livecode[key] = newcached;
            }

            return newcached;
        }
 private CachedCodeEntry CacheCode(string key)
 {
     CachedCodeEntry entry = null;
     lock (livecode)
     {
         for (LinkedListNode<CachedCodeEntry> node = livecode.First; node != null; node = node.Next)
         {
             if (node.Value._key == key)
             {
                 livecode.Remove(node);
                 livecode.AddFirst(node);
                 return node.Value;
             }
         }
         if (cacheSize != 0)
         {
             entry = new CachedCodeEntry(key, this.capnames, this.capslist, this.code, this.caps, this.capsize, this.runnerref, this.replref);
             livecode.AddFirst(entry);
             if (livecode.Count > cacheSize)
             {
                 livecode.RemoveLast();
             }
         }
     }
     return entry;
 }
示例#12
0
        // Returns a Regex object corresponding to the given pattern, compiled with
        // the specified options.
        //| <include file='doc\Regex.uex' path='docs/doc[@for="Regex.Regex1"]/*' />
        /// <devdoc>
        ///    <para>
        ///       Creates and compiles a regular expression object for the
        ///       specified regular expression
        ///       with options that modify the pattern.
        ///    </para>
        /// </devdoc>
        public Regex(String pattern, RegexOptions options)
        {
            RegexTree       tree;
            CachedCodeEntry cached;

            if (pattern == null)
            {
                throw new ArgumentNullException("pattern");
            }


            if (options < RegexOptions.None || (((int)options) >> MaxOptionShift) != 0)
            {
                throw new ArgumentOutOfRangeException("options");
            }
            if ((options & RegexOptions.ECMAScript) != 0 &&
                (options & ~(RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled
#if DBG
                             | RegexOptions.Debug
#endif
                             )) != 0)
            {
                throw new ArgumentOutOfRangeException("options");
            }

            //XXX: String key = ((int) options).ToString(NumberFormatInfo.InvariantInfo) + ":" + pattern;
            String key = ((int)options).ToString() + ":" + pattern;

#if REGEX_USE_CACHE
            cached = LookupCached(key);
#else
            cached = null;
#endif
            this.pattern  = pattern;
            this.roptions = options;

            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 REGEX_USE_CACHE
                cachedentry = CacheCode(key);
#endif
            }
            else
            {
                caps     = cached._caps;
                capnames = cached._capnames;
                capslist = cached._capslist;
                capsize  = cached._capsize;
                code     = cached._code;
//                factory    = cached._factory;
                runnerref       = cached._runnerref;
                replref         = cached._replref;
                refsInitialized = true;

                cachedentry = cached;
            }
//
// Singularity does not support compilation of regular expressions
//          // if the compile option is set, then compile the code if it's not already
//          if (UseOptionC() && factory == null) {
//              factory = Compile(code, roptions);
//              cachedentry.AddCompiled(factory);
//              code = null;
//          }
//
        }
示例#13
0
        private Regex(string pattern, RegexOptions options, bool useCache)
        {
            CachedCodeEntry cachedAndUpdate = null;
            string          str             = null;

            if (pattern == null)
            {
                throw new ArgumentNullException("pattern");
            }
            if ((options < RegexOptions.None) || ((((int)options) >> 10) != 0))
            {
                throw new ArgumentOutOfRangeException("options");
            }
            if (((options & RegexOptions.ECMAScript) != RegexOptions.None) && ((options & ~(RegexOptions.CultureInvariant | RegexOptions.ECMAScript | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase)) != RegexOptions.None))
            {
                throw new ArgumentOutOfRangeException("options");
            }
            if ((options & RegexOptions.CultureInvariant) != RegexOptions.None)
            {
                str = CultureInfo.InvariantCulture.ToString();
            }
            else
            {
                str = CultureInfo.CurrentCulture.ToString();
            }
            string[] strArray = new string[] { ((int)options).ToString(NumberFormatInfo.InvariantInfo), ":", str, ":", pattern };
            string   key      = string.Concat(strArray);

            cachedAndUpdate = LookupCachedAndUpdate(key);
            this.pattern    = pattern;
            this.roptions   = options;
            if (cachedAndUpdate == null)
            {
                RegexTree t = RegexParser.Parse(pattern, this.roptions);
                this.capnames = t._capnames;
                this.capslist = t._capslist;
                this.code     = RegexWriter.Write(t);
                this.caps     = this.code._caps;
                this.capsize  = this.code._capsize;
                this.InitializeReferences();
                t = null;
                if (useCache)
                {
                    cachedAndUpdate = this.CacheCode(key);
                }
            }
            else
            {
                this.caps            = cachedAndUpdate._caps;
                this.capnames        = cachedAndUpdate._capnames;
                this.capslist        = cachedAndUpdate._capslist;
                this.capsize         = cachedAndUpdate._capsize;
                this.code            = cachedAndUpdate._code;
                this.factory         = cachedAndUpdate._factory;
                this.runnerref       = cachedAndUpdate._runnerref;
                this.replref         = cachedAndUpdate._replref;
                this.refsInitialized = true;
            }
            if (this.UseOptionC() && (this.factory == null))
            {
                this.factory = this.Compile(this.code, this.roptions);
                if (useCache && (cachedAndUpdate != null))
                {
                    cachedAndUpdate.AddCompiled(this.factory);
                }
                this.code = null;
            }
        }
示例#14
0
        /*
         * Add current code to the cache
         */
        private CachedCodeEntry CacheCode(String key) {
            CachedCodeEntry newcached = null;

            lock (livecode) {
                // first look for it in the cache and move it to the head
                for (LinkedListNode<CachedCodeEntry> current = livecode.First; current != null; current = current.Next) {
                    if (current.Value._key == key) {
                        livecode.Remove(current);
                        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 (cacheSize != 0) {
                    newcached = new CachedCodeEntry(key, capnames, capslist, code, caps, capsize, runnerref, replref);
                    livecode.AddFirst(newcached);
                    if (livecode.Count > cacheSize)
                        livecode.RemoveLast();
                }
            }

            return newcached;
        }
示例#15
0
        private Regex(String pattern, RegexOptions options, bool useCache)
        {
            RegexTree       tree;
            CachedCodeEntry cached     = null;
            string          cultureKey = null;

            if (pattern == null)
            {
                throw new ArgumentNullException("pattern");
            }
            if (options < RegexOptions.None || (((int)options) >> MaxOptionShift) != 0)
            {
                throw new ArgumentOutOfRangeException("options");
            }
            if ((options & RegexOptions.ECMAScript) != 0 &&
                (options & ~(RegexOptions.ECMAScript |
                             RegexOptions.IgnoreCase |
                             RegexOptions.Multiline |
                             RegexOptions.Compiled |
                             RegexOptions.CultureInvariant
#if DBG
                             | RegexOptions.Debug
#endif
                             )) != 0)
            {
                throw new ArgumentOutOfRangeException("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.
            if ((options & RegexOptions.CultureInvariant) != 0)
            {
                cultureKey = CultureInfo.InvariantCulture.ThreeLetterWindowsLanguageName;
            }
            else
            {
                cultureKey = CultureInfo.CurrentCulture.ThreeLetterWindowsLanguageName;
            }

            String key = ((int)options).ToString(NumberFormatInfo.InvariantInfo) + ":" + cultureKey + ":" + pattern;
            cached = LookupCachedAndUpdate(key);

            this.pattern  = pattern;
            this.roptions = options;

            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;
                factory         = cached._factory;
                runnerref       = cached._runnerref;
                replref         = cached._replref;
                refsInitialized = true;
            }

            // if the compile option is set, then compile the code if it's not already
            if (UseOptionC() && factory == null)
            {
                factory = Compile(code, roptions);

                if (useCache && cached != null)
                {
                    cached.AddCompiled(factory);
                }
                code = null;
            }
        }
示例#16
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;
            }
        }
示例#17
0
        private Regex(string pattern, RegexOptions options, TimeSpan matchTimeout, bool addToCache)
        {
            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.Compiled |
                             RegexOptions.CultureInvariant
#if DEBUG
                             | RegexOptions.Debug
#endif
                             )) != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(options));
            }

            ValidateMatchTimeout(matchTimeout);

            // After parameter validation assign
            this.pattern         = pattern;
            roptions             = options;
            internalMatchTimeout = matchTimeout;

            // Cache handling. Try to look up this regex in the cache.
            CultureInfo culture = (options & RegexOptions.CultureInvariant) != 0 ?
                                  CultureInfo.InvariantCulture :
                                  CultureInfo.CurrentCulture;
            var             key    = new CachedCodeEntryKey(options, culture.ToString(), pattern);
            CachedCodeEntry cached = GetCachedCode(key, false);

            if (cached == null)
            {
                // Parse the input
                RegexTree tree = RegexParser.Parse(pattern, roptions, culture);

                // Extract the relevant information
                capnames = tree.CapNames;
                capslist = tree.CapsList;
                _code    = RegexWriter.Write(tree);
                caps     = _code.Caps;
                capsize  = _code.CapSize;

                InitializeReferences();

                tree = null;
                if (addToCache)
                {
                    cached = GetCachedCode(key, true);
                }
            }
            else
            {
                caps     = cached.Caps;
                capnames = cached.Capnames;
                capslist = cached.Capslist;
                capsize  = cached.Capsize;
                _code    = cached.Code;
#if FEATURE_COMPILED
                factory = cached.Factory;
#endif

                // Cache runner and replacement
                _runnerref       = cached.Runnerref;
                _replref         = cached.ReplRef;
                _refsInitialized = true;
            }

#if FEATURE_COMPILED
            // if the compile option is set, then compile the code if it's not already
            if (UseOptionC() && factory == null)
            {
                factory = Compile(_code, roptions);

                if (addToCache && cached != null)
                {
                    cached.AddCompiled(factory);
                }

                _code = null;
            }
#endif
        }
示例#18
0
文件: regex.cs 项目: ArildF/masters
        // Returns a Regex object corresponding to the given pattern, compiled with
        // the specified options.
        /// <include file='doc\Regex.uex' path='docs/doc[@for="Regex.Regex1"]/*' />
        /// <devdoc>
        ///    <para>
        ///       Creates and compiles a regular expression object for the
        ///       specified regular expression
        ///       with options that modify the pattern.
        ///    </para>
        /// </devdoc>
        public Regex(String pattern, RegexOptions options) {
            RegexTree tree;
            CachedCodeEntry cached;

            if (pattern == null) 
                throw new ArgumentNullException("pattern");


            if (options < RegexOptions.None || ( ((int) options) >> MaxOptionShift) != 0)
                throw new ArgumentOutOfRangeException("options");
            if ((options &   RegexOptions.ECMAScript) != 0
             && (options & ~(RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled
#if DBG
                           | RegexOptions.Debug
#endif
                                               )) != 0)
                throw new ArgumentOutOfRangeException("options");

            String key = ((int) options).ToString(NumberFormatInfo.InvariantInfo) + ":" + pattern;

            cached = LookupCached(key);

            this.pattern = pattern;
            this.roptions = options;

            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;
                cachedentry= CacheCode(key);
            }
            else {
                caps       = cached._caps;
                capnames   = cached._capnames;
                capslist   = cached._capslist;
                capsize    = cached._capsize;
                code       = cached._code;
                factory    = cached._factory;
                runnerref  = cached._runnerref;
                replref    = cached._replref;
                refsInitialized = true;

                cachedentry     = cached;
            }

            // if the compile option is set, then compile the code if it's not already
            if (UseOptionC() && factory == null) {
                factory = Compile(code, roptions);
                cachedentry.AddCompiled(factory);
                code = null;
            }
        }