CreateInternal( string tokenizedString, Module macroSource, bool verbatim, TokenizedStringArray positionalTokens, EFlags flags) { if (null == tokenizedString) { return(null); } // strings can be created during the multithreaded phase lock (Cache) { if (0 == (flags & EFlags.NoCache)) { var search = Cache.Where((ts) => { // first check the simple states for equivalence if (ts.OriginalString == tokenizedString && ts.ModuleWithMacros == macroSource && ts.Verbatim == verbatim) { // and then check the positional tokens, if they exist var samePosTokenCount = ((null != positionalTokens) && (positionalTokens.Count() == ts.PositionalTokens.Count())) || ((null == positionalTokens) && (0 == ts.PositionalTokens.Count())); if (!samePosTokenCount) { return(false); } for (int i = 0; i < ts.PositionalTokens.Count(); ++i) { // because positional tokens are TokenizedStrings, they will refer to the same object if (ts.PositionalTokens[i] != positionalTokens[i]) { return(false); } } return(true); } else { return(false); } }); var foundTS = search.FirstOrDefault(); if (null != foundTS) { ++foundTS.RefCount; return(foundTS); } } var newTS = new TokenizedString(tokenizedString, macroSource, verbatim, positionalTokens, flags); Cache.Add(newTS); return(newTS); } }
CreateInternal( string tokenizedString, Module macroSource, bool verbatim, TokenizedStringArray positionalTokens, EFlags flags) { if (null == tokenizedString) { return(null); } // strings can be created during the multithreaded phase, so synchronize on the cache used if (verbatim) { // covers all verbatim strings lock (VerbatimCache) { if (0 == (flags & EFlags.NoCache)) { var foundTS = VerbatimCache.FirstOrDefault((ts) => { if (ts.OriginalString == tokenizedString) { return(true); } return(false); }); if (null != foundTS) { ++foundTS.RefCount; return(foundTS); } } var newTS = new TokenizedString(tokenizedString, macroSource, verbatim, positionalTokens, flags); VerbatimCache.Add(newTS); AllStrings.Add(newTS); return(newTS); } } else { // covers all strings associated with a module (for macros), or no module but with positional arguments var stringCache = (null != macroSource) ? macroSource.TokenizedStringCache : NoModuleCache; lock (stringCache) { if (0 == (flags & EFlags.NoCache)) { var foundTS = stringCache.FirstOrDefault((ts) => { if (ts.OriginalString == tokenizedString) { // and then check the positional tokens, if they exist var samePosTokenCount = ((null != positionalTokens) && (positionalTokens.Count() == ts.PositionalTokens.Count())) || ((null == positionalTokens) && (0 == ts.PositionalTokens.Count())); if (!samePosTokenCount) { return(false); } for (int i = 0; i < ts.PositionalTokens.Count(); ++i) { // because positional tokens are TokenizedStrings, they will refer to the same object if (ts.PositionalTokens[i] != positionalTokens[i]) { return(false); } } return(true); } else { return(false); } }); if (null != foundTS) { ++foundTS.RefCount; return(foundTS); } } var newTS = new TokenizedString(tokenizedString, macroSource, verbatim, positionalTokens, flags); stringCache.Add(newTS); AllStrings.Add(newTS); return(newTS); } } }