You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2020/01/08 08:35:09 UTC

[lucenenet] branch master updated (049b771 -> 01d65bb)

This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git.


    from 049b771  Merge pull request #234 from Shazwazza/moving-markdown-converter
     new 4517cdc  Lucene.Net.Index.DocTermOrds: Removed unnecessary O(n) operation (call to .ToList())
     new 4a5fa6d  Lucene.Net.Search.Payloads.PayloadSpanUtil::ctor(): Eliminated unnecessary O(n + n) operation when instantiating SpanOrQuery
     new 39f1ef3  Lucene.Net.Index.StandardDirectoryReader: Eliminated unnecessary O(n + n) operation and cast
     new c08eb10  Lucene.Net.Index.FilterDirectoryReader: Eliminated unnecessary O(n + n) operation
     new 6a7b255  Lucene.Net.Index.BaseCompositeReader: Eliminated unnecessary O(n + n) operation and cast
     new 01d65bb  SWEEP: Eliminated several unnecessary lookups by converting ContainsKey to TryGetValue

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Directory.Build.targets                            |  2 ++
 .../Analysis/CharFilter/MappingCharFilter.cs       |  3 +-
 .../Compound/Hyphenation/HyphenationTree.cs        |  4 +--
 .../Analysis/Compound/Hyphenation/PatternParser.cs |  3 +-
 .../Analysis/Hunspell/Dictionary.cs                | 12 +++----
 .../Analysis/Nl/DutchStemmer.cs                    | 11 ++----
 .../Pattern/PatternCaptureGroupFilterFactory.cs    |  2 +-
 .../Analysis/Query/QueryAutoStopWordAnalyzer.cs    |  3 +-
 .../Analysis/Synonym/SynonymFilterFactory.cs       |  2 +-
 .../Analysis/Synonym/SynonymMap.cs                 |  3 +-
 .../Analysis/Util/CharArrayMap.cs                  |  4 +--
 .../Analysis/Util/CharacterUtils.cs                |  6 ++--
 .../Language/DaitchMokotoffSoundex.cs              |  4 +--
 src/Lucene.Net.Analysis.SmartCn/Hhmm/BiSegGraph.cs |  5 +--
 .../Egothor.Stemmer/Optimizer.cs                   |  5 ++-
 .../Egothor.Stemmer/Row.cs                         |  3 +-
 src/Lucene.Net.Benchmark/Quality/Trec/TrecJudge.cs |  8 +----
 .../Support/Sax/Helpers/NamespaceSupport.cs        |  4 +--
 .../KNearestNeighborClassifier.cs                  |  4 +--
 .../JS/JavascriptCompiler.cs                       | 11 ++----
 src/Lucene.Net.Facet/FacetsConfig.cs               | 40 +++++++++------------
 .../Taxonomy/Directory/DirectoryTaxonomyWriter.cs  |  4 +--
 .../AbstractSecondPassGroupingCollector.cs         |  2 +-
 src/Lucene.Net.Grouping/SearchGroup.cs             |  3 +-
 .../Classic/QueryParserBase.cs                     |  4 +--
 src/Lucene.Net.QueryParser/Ext/Extensions.cs       |  9 ++---
 .../Flexible/Core/Nodes/QueryNodeImpl.cs           |  2 ++
 .../Surround/Query/SpanNearClauseFactory.cs        |  4 +--
 .../Analysis/BaseTokenStreamTestCase.cs            |  8 ++---
 .../Analysis/ValidatingTokenFilter.cs              |  6 ++--
 .../Index/BaseIndexFileFormatTestCase.cs           |  2 +-
 .../Index/BaseTermVectorsFormatTestCase.cs         | 27 +++++++++-----
 src/Lucene.Net.TestFramework/Util/Fst/FSTTester.cs | 10 +++---
 .../Analysis/Core/TestRandomChains.cs              |  6 ++--
 .../Analysis/Synonym/TestSynonymMapFilter.cs       |  3 +-
 .../Taxonomy/TestTaxonomyFacetCounts.cs            |  3 +-
 .../Taxonomy/TestTaxonomyFacetSumValueSource.cs    |  3 +-
 .../AllGroupHeadsCollectorTest.cs                  |  4 +--
 .../GroupFacetCollectorTest.cs                     | 23 +++++-------
 src/Lucene.Net.Tests.Grouping/TestGrouping.cs      |  6 ++--
 .../VectorHighlight/SimpleFragmentsBuilderTest.cs  |  6 ++--
 src/Lucene.Net.Tests.Join/TestJoinUtil.cs          | 42 ++++++++++------------
 .../Document/TestLazyDocument.cs                   |  4 +--
 .../Suggest/Analyzing/AnalyzingSuggesterTest.cs    |  4 +--
 .../Suggest/Analyzing/TestFreeTextSuggester.cs     | 11 +++---
 .../Suggest/DocumentDictionaryTest.cs              |  8 ++---
 .../Suggest/DocumentValueSourceDictionaryTest.cs   | 10 +++---
 src/Lucene.Net.Tests/Index/TestMultiFields.cs      |  6 ++--
 src/Lucene.Net.Tests/Index/TestPostingsOffsets.cs  | 11 +++---
 .../Search/TestCustomSearcherSort.cs               |  4 +--
 .../Codecs/PerField/PerFieldDocValuesFormat.cs     |  7 ++--
 .../Codecs/PerField/PerFieldPostingsFormat.cs      |  7 ++--
 src/Lucene.Net/Index/BaseCompositeReader.cs        | 14 +++++---
 src/Lucene.Net/Index/DocTermOrds.cs                |  2 +-
 src/Lucene.Net/Index/FilterDirectoryReader.cs      |  6 ++--
 src/Lucene.Net/Index/IndexFileDeleter.cs           | 23 +++++-------
 src/Lucene.Net/Index/IndexWriter.cs                |  8 ++---
 src/Lucene.Net/Index/StandardDirectoryReader.cs    |  4 +--
 src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs  | 12 ++++---
 src/Lucene.Net/Search/Spans/SpanOrQuery.cs         | 13 +++++--
 src/Lucene.Net/Util/FieldCacheSanityChecker.cs     |  5 +--
 src/Lucene.Net/Util/MapOfSets.cs                   | 22 ++++--------
 62 files changed, 223 insertions(+), 274 deletions(-)


[lucenenet] 01/06: Lucene.Net.Index.DocTermOrds: Removed unnecessary O(n) operation (call to .ToList())

Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 4517cdc56c05fca5c49a13b85c002a70ed63609e
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Tue Jan 7 20:00:20 2020 +0700

    Lucene.Net.Index.DocTermOrds: Removed unnecessary O(n) operation (call to .ToList())
---
 src/Lucene.Net/Index/DocTermOrds.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Lucene.Net/Index/DocTermOrds.cs b/src/Lucene.Net/Index/DocTermOrds.cs
index 424e6b7..af9d76d 100644
--- a/src/Lucene.Net/Index/DocTermOrds.cs
+++ b/src/Lucene.Net/Index/DocTermOrds.cs
@@ -819,7 +819,7 @@ namespace Lucene.Net.Index
                     return SeekStatus.FOUND;
                 }
 
-                int startIdx = outerInstance.m_indexedTermsArray.ToList().BinarySearch(target);
+                int startIdx = Array.BinarySearch(outerInstance.m_indexedTermsArray, target);
 
                 if (startIdx >= 0)
                 {


[lucenenet] 02/06: Lucene.Net.Search.Payloads.PayloadSpanUtil::ctor(): Eliminated unnecessary O(n + n) operation when instantiating SpanOrQuery

Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 4a5fa6d1e32537f0d337259e52712c1b6b1a0453
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Tue Jan 7 21:19:52 2020 +0700

    Lucene.Net.Search.Payloads.PayloadSpanUtil::ctor(): Eliminated unnecessary O(n + n) operation when instantiating SpanOrQuery
---
 src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs | 12 +++++++-----
 src/Lucene.Net/Search/Spans/SpanOrQuery.cs        | 13 ++++++++++---
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs b/src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs
index 57281e9..448f037 100644
--- a/src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs
+++ b/src/Lucene.Net/Search/Payloads/PayloadSpanUtil.cs
@@ -135,16 +135,18 @@ namespace Lucene.Net.Search.Payloads
                         }
                     }
 
-                    IList<Query>[] disjunctLists = new List<Query>[maxPosition + 1];
+                    // LUCENENET: Changed from Query to SpanQuery to eliminate the O(n) cast
+                    // required to instantiate SpanOrQuery below
+                    IList<SpanQuery>[] disjunctLists = new List<SpanQuery>[maxPosition + 1];
                     int distinctPositions = 0;
 
                     for (int i = 0; i < termArrays.Count; ++i)
                     {
                         Term[] termArray = termArrays[i];
-                        IList<Query> disjuncts = disjunctLists[positions[i]];
+                        IList<SpanQuery> disjuncts = disjunctLists[positions[i]]; // LUCENENET: Changed from Query to SpanQuery
                         if (disjuncts == null)
                         {
-                            disjuncts = (disjunctLists[positions[i]] = new List<Query>(termArray.Length));
+                            disjuncts = (disjunctLists[positions[i]] = new List<SpanQuery>(termArray.Length)); // LUCENENET: Changed from Query to SpanQuery
                             ++distinctPositions;
                         }
                         foreach (Term term in termArray)
@@ -158,10 +160,10 @@ namespace Lucene.Net.Search.Payloads
                     SpanQuery[] clauses = new SpanQuery[distinctPositions];
                     for (int i = 0; i < disjunctLists.Length; ++i)
                     {
-                        IList<Query> disjuncts = disjunctLists[i];
+                        IList<SpanQuery> disjuncts = disjunctLists[i]; // LUCENENET: Changed from Query to SpanQuery
                         if (disjuncts != null)
                         {
-                            clauses[position++] = new SpanOrQuery(disjuncts.OfType<SpanQuery>().ToArray());
+                            clauses[position++] = new SpanOrQuery(disjuncts);
                         }
                         else
                         {
diff --git a/src/Lucene.Net/Search/Spans/SpanOrQuery.cs b/src/Lucene.Net/Search/Spans/SpanOrQuery.cs
index 6ed635c..93825dc 100644
--- a/src/Lucene.Net/Search/Spans/SpanOrQuery.cs
+++ b/src/Lucene.Net/Search/Spans/SpanOrQuery.cs
@@ -42,11 +42,18 @@ namespace Lucene.Net.Search.Spans
 
         /// <summary>
         /// Construct a <see cref="SpanOrQuery"/> merging the provided <paramref name="clauses"/>. </summary>
-        public SpanOrQuery(params SpanQuery[] clauses)
+        public SpanOrQuery(params SpanQuery[] clauses) : this((IList<SpanQuery>)clauses) { }
+
+        // LUCENENET specific overload.
+        // LUCENENET TODO: API - This constructor was added to eliminate casting with PayloadSpanUtil. Make public?
+        // It would be more useful if the type was an IEnumerable<SpanQuery>, but
+        // need to rework the allocation below. It would also be better to change AddClause() to Add() to make
+        // the C# collection initializer function.
+        internal SpanOrQuery(IList<SpanQuery> clauses)
         {
             // copy clauses array into an ArrayList
-            this.clauses = new EquatableList<SpanQuery>(clauses.Length);
-            for (int i = 0; i < clauses.Length; i++)
+            this.clauses = new EquatableList<SpanQuery>(clauses.Count);
+            for (int i = 0; i < clauses.Count; i++)
             {
                 AddClause(clauses[i]);
             }


[lucenenet] 03/06: Lucene.Net.Index.StandardDirectoryReader: Eliminated unnecessary O(n + n) operation and cast

Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 39f1ef38863e697fde521f7eea67e0d9261bbbf9
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Tue Jan 7 21:27:36 2020 +0700

    Lucene.Net.Index.StandardDirectoryReader: Eliminated unnecessary O(n + n) operation and cast
---
 src/Lucene.Net/Index/StandardDirectoryReader.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Lucene.Net/Index/StandardDirectoryReader.cs b/src/Lucene.Net/Index/StandardDirectoryReader.cs
index 5e50470..f6454f9 100644
--- a/src/Lucene.Net/Index/StandardDirectoryReader.cs
+++ b/src/Lucene.Net/Index/StandardDirectoryReader.cs
@@ -169,7 +169,7 @@ namespace Lucene.Net.Index
 
         /// <summary>
         /// This constructor is only used for <see cref="DoOpenIfChanged(SegmentInfos)"/> </summary>
-        private static DirectoryReader Open(Directory directory, SegmentInfos infos, IList<AtomicReader> oldReaders, int termInfosIndexDivisor)
+        private static DirectoryReader Open(Directory directory, SegmentInfos infos, IList<IndexReader> oldReaders, int termInfosIndexDivisor) // LUCENENET: Changed from AtomicReader to IndexReader to eliminate casting from the 1 place this is called from
         {
             // we put the old SegmentReaders in a map, that allows us
             // to lookup a reader using its segment name
@@ -424,7 +424,7 @@ namespace Lucene.Net.Index
 
         internal DirectoryReader DoOpenIfChanged(SegmentInfos infos)
         {
-            return StandardDirectoryReader.Open(m_directory, infos, GetSequentialSubReaders().OfType<AtomicReader>().ToList(), termInfosIndexDivisor);
+            return StandardDirectoryReader.Open(m_directory, infos, GetSequentialSubReaders(), termInfosIndexDivisor);
         }
 
         public override long Version


[lucenenet] 06/06: SWEEP: Eliminated several unnecessary lookups by converting ContainsKey to TryGetValue

Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 01d65bb1409cb34a8bc1444b67dd1ab011d6d4fa
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Tue Jan 7 23:18:18 2020 +0700

    SWEEP: Eliminated several unnecessary lookups by converting ContainsKey to TryGetValue
---
 Directory.Build.targets                            |  2 ++
 .../Analysis/CharFilter/MappingCharFilter.cs       |  3 +-
 .../Compound/Hyphenation/HyphenationTree.cs        |  4 +--
 .../Analysis/Compound/Hyphenation/PatternParser.cs |  3 +-
 .../Analysis/Hunspell/Dictionary.cs                | 12 +++----
 .../Analysis/Nl/DutchStemmer.cs                    | 11 ++----
 .../Pattern/PatternCaptureGroupFilterFactory.cs    |  2 +-
 .../Analysis/Query/QueryAutoStopWordAnalyzer.cs    |  3 +-
 .../Analysis/Synonym/SynonymFilterFactory.cs       |  2 +-
 .../Analysis/Synonym/SynonymMap.cs                 |  3 +-
 .../Analysis/Util/CharArrayMap.cs                  |  4 +--
 .../Analysis/Util/CharacterUtils.cs                |  6 ++--
 .../Language/DaitchMokotoffSoundex.cs              |  4 +--
 src/Lucene.Net.Analysis.SmartCn/Hhmm/BiSegGraph.cs |  5 +--
 .../Egothor.Stemmer/Optimizer.cs                   |  5 ++-
 .../Egothor.Stemmer/Row.cs                         |  3 +-
 src/Lucene.Net.Benchmark/Quality/Trec/TrecJudge.cs |  8 +----
 .../Support/Sax/Helpers/NamespaceSupport.cs        |  4 +--
 .../KNearestNeighborClassifier.cs                  |  4 +--
 .../JS/JavascriptCompiler.cs                       | 11 ++----
 src/Lucene.Net.Facet/FacetsConfig.cs               | 40 +++++++++------------
 .../Taxonomy/Directory/DirectoryTaxonomyWriter.cs  |  4 +--
 .../AbstractSecondPassGroupingCollector.cs         |  2 +-
 src/Lucene.Net.Grouping/SearchGroup.cs             |  3 +-
 .../Classic/QueryParserBase.cs                     |  4 +--
 src/Lucene.Net.QueryParser/Ext/Extensions.cs       |  9 ++---
 .../Flexible/Core/Nodes/QueryNodeImpl.cs           |  2 ++
 .../Surround/Query/SpanNearClauseFactory.cs        |  4 +--
 .../Analysis/BaseTokenStreamTestCase.cs            |  8 ++---
 .../Analysis/ValidatingTokenFilter.cs              |  6 ++--
 .../Index/BaseIndexFileFormatTestCase.cs           |  2 +-
 .../Index/BaseTermVectorsFormatTestCase.cs         | 27 +++++++++-----
 src/Lucene.Net.TestFramework/Util/Fst/FSTTester.cs | 10 +++---
 .../Analysis/Core/TestRandomChains.cs              |  6 ++--
 .../Analysis/Synonym/TestSynonymMapFilter.cs       |  3 +-
 .../Taxonomy/TestTaxonomyFacetCounts.cs            |  3 +-
 .../Taxonomy/TestTaxonomyFacetSumValueSource.cs    |  3 +-
 .../AllGroupHeadsCollectorTest.cs                  |  4 +--
 .../GroupFacetCollectorTest.cs                     | 23 +++++-------
 src/Lucene.Net.Tests.Grouping/TestGrouping.cs      |  6 ++--
 .../VectorHighlight/SimpleFragmentsBuilderTest.cs  |  6 ++--
 src/Lucene.Net.Tests.Join/TestJoinUtil.cs          | 42 ++++++++++------------
 .../Document/TestLazyDocument.cs                   |  4 +--
 .../Suggest/Analyzing/AnalyzingSuggesterTest.cs    |  4 +--
 .../Suggest/Analyzing/TestFreeTextSuggester.cs     | 11 +++---
 .../Suggest/DocumentDictionaryTest.cs              |  8 ++---
 .../Suggest/DocumentValueSourceDictionaryTest.cs   | 10 +++---
 src/Lucene.Net.Tests/Index/TestMultiFields.cs      |  6 ++--
 src/Lucene.Net.Tests/Index/TestPostingsOffsets.cs  | 11 +++---
 .../Search/TestCustomSearcherSort.cs               |  4 +--
 .../Codecs/PerField/PerFieldDocValuesFormat.cs     |  7 ++--
 .../Codecs/PerField/PerFieldPostingsFormat.cs      |  7 ++--
 src/Lucene.Net/Index/IndexFileDeleter.cs           | 23 +++++-------
 src/Lucene.Net/Index/IndexWriter.cs                |  8 ++---
 src/Lucene.Net/Util/FieldCacheSanityChecker.cs     |  5 +--
 src/Lucene.Net/Util/MapOfSets.cs                   | 22 ++++--------
 56 files changed, 190 insertions(+), 256 deletions(-)

diff --git a/Directory.Build.targets b/Directory.Build.targets
index a1f7171..774ba44 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -30,6 +30,8 @@
     <DefineConstants>$(DefineConstants);FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR</DefineConstants>
     <DefineConstants>$(DefineConstants);FEATURE_CONDITIONALWEAKTABLE_ADDORUPDATE</DefineConstants>
 
+    <DefineConstants>$(DefineConstants);FEATURE_HASHSET_CAPACITY</DefineConstants>
+    
   </PropertyGroup>
 
   <!-- Features in .NET Framework 4.5+, .NET Standard 2.x, .NET Core 2.x, and .NET Core 3.x -->
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs b/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs
index de79d64..484891d 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/CharFilter/MappingCharFilter.cs
@@ -130,8 +130,7 @@ namespace Lucene.Net.Analysis.CharFilters
                 {
                     // LUCENENET fix: Check the dictionary to ensure it contains a key before reading it.
                     char key = Convert.ToChar((char)firstCH);
-                    FST.Arc<CharsRef> arc = cachedRootArcs.ContainsKey(key) ? cachedRootArcs[key] : null;
-                    if (arc != null)
+                    if (cachedRootArcs.TryGetValue(key, out FST.Arc<CharsRef> arc) && arc != null)
                     {
                         if (!FST.TargetHasArcs(arc))
                         {
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Compound/Hyphenation/HyphenationTree.cs b/src/Lucene.Net.Analysis.Common/Analysis/Compound/Hyphenation/HyphenationTree.cs
index 2342d2c..3d43e34 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Compound/Hyphenation/HyphenationTree.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Compound/Hyphenation/HyphenationTree.cs
@@ -469,11 +469,11 @@ namespace Lucene.Net.Analysis.Compound.Hyphenation
 
             // check exception list first
             string sw = new string(word, 1, len);
-            if (m_stoplist.ContainsKey(sw))
+            // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+            if (m_stoplist.TryGetValue(sw, out IList<object> hw))
             {
                 // assume only simple hyphens (Hyphen.pre="-", Hyphen.post = Hyphen.no =
                 // null)
-                IList<object> hw = m_stoplist[sw];
                 int j = 0;
                 for (i = 0; i < hw.Count; i++)
                 {
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Compound/Hyphenation/PatternParser.cs b/src/Lucene.Net.Analysis.Common/Analysis/Compound/Hyphenation/PatternParser.cs
index f73d675..b49e37d 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Compound/Hyphenation/PatternParser.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Compound/Hyphenation/PatternParser.cs
@@ -432,8 +432,7 @@ namespace Lucene.Net.Analysis.Compound.Hyphenation
         {
             if (local.Equals("hyphen-char", StringComparison.Ordinal))
             {
-                string h = attrs.ContainsKey("value") ? attrs["value"] : null;
-                if (h != null && h.Length == 1)
+                if (attrs.TryGetValue("value", out string h) && h != null && h.Length == 1)
                 {
                     hyphenChar = h[0];
                 }
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs b/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
index 27bf50d..49b04c2 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Hunspell/Dictionary.cs
@@ -480,8 +480,7 @@ namespace Lucene.Net.Analysis.Hunspell
                 }
 
                 // deduplicate patterns
-                int? patternIndex = seenPatterns.ContainsKey(regex) ? seenPatterns[regex] : null;
-                if (patternIndex == null)
+                if (!seenPatterns.TryGetValue(regex, out int? patternIndex) || patternIndex == null)
                 {
                     patternIndex = patterns.Count;
                     if (patternIndex > short.MaxValue)
@@ -493,8 +492,7 @@ namespace Lucene.Net.Analysis.Hunspell
                     patterns.Add(pattern);
                 }
 
-                int? stripOrd = seenStrips.ContainsKey(strip) ? seenStrips[strip] : null;
-                if (stripOrd == null)
+                if (!seenStrips.TryGetValue(strip, out int? stripOrd) || stripOrd == null)
                 {
                     stripOrd = seenStrips.Count;
                     seenStrips[strip] = stripOrd;
@@ -535,11 +533,9 @@ namespace Lucene.Net.Analysis.Hunspell
                     affixArg = cleaned.ToString();
                 }
 
-                IList<char?> list = affixes.ContainsKey(affixArg) ? affixes[affixArg] : null;
-                if (list == null)
+                if (!affixes.TryGetValue(affixArg, out IList<char?> list) || list == null)
                 {
-                    list = new List<char?>();
-                    affixes[affixArg] = list;
+                    affixes[affixArg] = list = new List<char?>();
                 }
 
                 list.Add((char)currentAffix);
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Nl/DutchStemmer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Nl/DutchStemmer.cs
index 43ef3fc..0e9ccd8 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Nl/DutchStemmer.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Nl/DutchStemmer.cs
@@ -60,16 +60,9 @@ namespace Lucene.Net.Analysis.Nl
             {
                 return term;
             }
-            if (_stemDict != null && _stemDict.ContainsKey(term))
+            if (_stemDict != null && _stemDict.TryGetValue(term, out string value))
             {
-                if (_stemDict[term] is string)
-                {
-                    return (string)_stemDict[term];
-                }
-                else
-                {
-                    return null;
-                }
+                return value;
             }
 
             // Reset the StringBuilder.
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Pattern/PatternCaptureGroupFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/Pattern/PatternCaptureGroupFilterFactory.cs
index e446ad2..d7648cc 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Pattern/PatternCaptureGroupFilterFactory.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Pattern/PatternCaptureGroupFilterFactory.cs
@@ -41,7 +41,7 @@ namespace Lucene.Net.Analysis.Pattern
             : base(args)
         {
             pattern = GetPattern(args, "pattern");
-            preserveOriginal = args.ContainsKey("preserve_original") ? bool.Parse(args["preserve_original"]) : true;
+            preserveOriginal = args.TryGetValue("preserve_original", out string value) ? bool.Parse(value) : true;
         }
 
         public override TokenStream Create(TokenStream input)
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Query/QueryAutoStopWordAnalyzer.cs b/src/Lucene.Net.Analysis.Common/Analysis/Query/QueryAutoStopWordAnalyzer.cs
index 70f432a..fa6f338 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Query/QueryAutoStopWordAnalyzer.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Query/QueryAutoStopWordAnalyzer.cs
@@ -151,8 +151,7 @@ namespace Lucene.Net.Analysis.Query
 
         protected override TokenStreamComponents WrapComponents(string fieldName, TokenStreamComponents components)
         {
-            var stopWords = stopWordsPerField.ContainsKey(fieldName) ? stopWordsPerField[fieldName] : null;
-            if (stopWords == null)
+            if (!stopWordsPerField.TryGetValue(fieldName, out HashSet<string> stopWords) || stopWords == null)
             {
                 return components;
             }
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SynonymFilterFactory.cs b/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SynonymFilterFactory.cs
index 457b729..78c253f 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SynonymFilterFactory.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SynonymFilterFactory.cs
@@ -73,7 +73,7 @@ namespace Lucene.Net.Analysis.Synonym
             {
                 // check if you use the new optional arg "format". this makes no sense for the old one, 
                 // as its wired to solr's synonyms format only.
-                if (args.ContainsKey("format") && !args["format"].Equals("solr", StringComparison.Ordinal))
+                if (args.TryGetValue("format", out string value) && !value.Equals("solr", StringComparison.Ordinal))
                 {
                     throw new System.ArgumentException("You must specify luceneMatchVersion >= 3.4 to use alternate synonyms formats");
                 }
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SynonymMap.cs b/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SynonymMap.cs
index 16f0ea0..84e4c33 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SynonymMap.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Synonym/SynonymMap.cs
@@ -197,8 +197,7 @@ namespace Lucene.Net.Analysis.Synonym
                     //System.out.println("  output=" + output + " new ord=" + ord);
                 }
 
-                MapEntry e = workingSet.ContainsKey(input) ? workingSet[input] : null;
-                if (e == null)
+                if (!workingSet.TryGetValue(input, out MapEntry e) || e == null)
                 {
                     e = new MapEntry();
                     workingSet[CharsRef.DeepCopyOf(input)] = e; // make a copy, since we will keep around in our map
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
index 893404a..88fd5b5 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
@@ -767,10 +767,10 @@ namespace Lucene.Net.Analysis.Util
             {
                 while (iter.MoveNext())
                 {
-                    if (!this.ContainsKey(iter.Current.Key))
+                    if (!this.TryGetValue(iter.Current.Key, out TValue value))
                         return false;
 
-                    if (!EqualityComparer<TValue>.Default.Equals(this[iter.Current.Key], iter.Current.Value))
+                    if (!EqualityComparer<TValue>.Default.Equals(value, iter.Current.Value))
                         return false;
                 }
             }
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharacterUtils.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharacterUtils.cs
index 645618c..ffda963 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharacterUtils.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharacterUtils.cs
@@ -194,15 +194,15 @@ namespace Lucene.Net.Analysis.Util
             {
                 throw new System.ArgumentException("srcLen must be >= 0");
             }
-            int codePointCount_Renamed = 0;
+            int codePointCount = 0;
             for (int i = 0; i < srcLen; )
             {
                 int cp = CodePointAt(src, srcOff + i, srcOff + srcLen);
                 int charCount = Character.CharCount(cp);
-                dest[destOff + codePointCount_Renamed++] = cp;
+                dest[destOff + codePointCount++] = cp;
                 i += charCount;
             }
-            return codePointCount_Renamed;
+            return codePointCount;
         }
 
         /// <summary>
diff --git a/src/Lucene.Net.Analysis.Phonetic/Language/DaitchMokotoffSoundex.cs b/src/Lucene.Net.Analysis.Phonetic/Language/DaitchMokotoffSoundex.cs
index c0de1eb..1e51694 100644
--- a/src/Lucene.Net.Analysis.Phonetic/Language/DaitchMokotoffSoundex.cs
+++ b/src/Lucene.Net.Analysis.Phonetic/Language/DaitchMokotoffSoundex.cs
@@ -432,9 +432,9 @@ namespace Lucene.Net.Analysis.Phonetic.Language
                 }
 
                 ch = char.ToLowerInvariant(ch);
-                if (folding && FOLDINGS.ContainsKey(ch))
+                if (folding && FOLDINGS.TryGetValue(ch, out char newChar))
                 {
-                    ch = FOLDINGS[ch];
+                    ch = newChar;
                 }
                 sb.Append(ch);
             }
diff --git a/src/Lucene.Net.Analysis.SmartCn/Hhmm/BiSegGraph.cs b/src/Lucene.Net.Analysis.SmartCn/Hhmm/BiSegGraph.cs
index 6c2923e..772745f 100644
--- a/src/Lucene.Net.Analysis.SmartCn/Hhmm/BiSegGraph.cs
+++ b/src/Lucene.Net.Analysis.SmartCn/Hhmm/BiSegGraph.cs
@@ -130,10 +130,7 @@ namespace Lucene.Net.Analysis.Cn.Smart.Hhmm
         /// <returns><c>true</c> if a token pair exists</returns>
         public virtual bool IsToExist(int to)
         {
-            //return tokenPairListTable.get(Integer.valueOf(to)) != null;
-            //return tokenPairListTable.ContainsKey(to) && tokenPairListTable[to] != null;
-            IList<SegTokenPair> result;
-            return tokenPairListTable.TryGetValue(to, out result) && result != null;
+            return tokenPairListTable.TryGetValue(to, out IList<SegTokenPair> result) && result != null;
         }
 
         /// <summary>
diff --git a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Optimizer.cs b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Optimizer.cs
index ed97f98..29673c4 100644
--- a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Optimizer.cs
+++ b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Optimizer.cs
@@ -128,10 +128,9 @@ namespace Egothor.Stemmer
             foreach (char ch in master.cells.Keys)
             {
                 // XXX also must handle Cnt and Skip !!
-                Cell a = master.cells.ContainsKey(ch) ? master.cells[ch] : null;
-                Cell b = existing.cells.ContainsKey(ch) ? existing.cells[ch] : null;
+                master.cells.TryGetValue(ch, out Cell a);
 
-                Cell s = (b == null) ? new Cell(a) : Merge(a, b);
+                Cell s = !existing.cells.TryGetValue(ch, out Cell b) || (b == null) ? new Cell(a) : Merge(a, b);
                 if (s == null)
                 {
                     return null;
diff --git a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Row.cs b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Row.cs
index 39cb7d1..88b0e13 100644
--- a/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Row.cs
+++ b/src/Lucene.Net.Analysis.Stempel/Egothor.Stemmer/Row.cs
@@ -323,7 +323,8 @@ namespace Egothor.Stemmer
 
         internal Cell At(char index)
         {
-            return cells.ContainsKey(index) ? cells[index] : null;
+            cells.TryGetValue(index, out Cell value);
+            return value;
         }
     }
 }
diff --git a/src/Lucene.Net.Benchmark/Quality/Trec/TrecJudge.cs b/src/Lucene.Net.Benchmark/Quality/Trec/TrecJudge.cs
index c1c63ac..a191dd0 100644
--- a/src/Lucene.Net.Benchmark/Quality/Trec/TrecJudge.cs
+++ b/src/Lucene.Net.Benchmark/Quality/Trec/TrecJudge.cs
@@ -139,14 +139,8 @@ namespace Lucene.Net.Benchmarks.Quality.Trec
             for (int i = 0; i < qq.Length; i++)
             {
                 string id = qq[i].QueryID;
-                if (missingQueries.ContainsKey(id))
-                {
-                    missingQueries.Remove(id);
-                }
-                else
-                {
+                if (!missingQueries.Remove(id))
                     missingJudgements.Add(id);
-                }
             }
             bool isValid = true;
             if (missingJudgements.Count > 0)
diff --git a/src/Lucene.Net.Benchmark/Support/Sax/Helpers/NamespaceSupport.cs b/src/Lucene.Net.Benchmark/Support/Sax/Helpers/NamespaceSupport.cs
index 42e5564..06470d6 100644
--- a/src/Lucene.Net.Benchmark/Support/Sax/Helpers/NamespaceSupport.cs
+++ b/src/Lucene.Net.Benchmark/Support/Sax/Helpers/NamespaceSupport.cs
@@ -644,9 +644,9 @@ namespace Sax.Helpers
                 // Start by looking in the cache, and
                 // return immediately if the name
                 // is already known in this content
-                if (table.ContainsKey(qName))
+                if (table.TryGetValue(qName, out string[] value))
                 {
-                    return (string[])table[qName];
+                    return value;
                 }
 
                 // We haven't seen this name in this
diff --git a/src/Lucene.Net.Classification/KNearestNeighborClassifier.cs b/src/Lucene.Net.Classification/KNearestNeighborClassifier.cs
index 5122462..1f5e3c0 100644
--- a/src/Lucene.Net.Classification/KNearestNeighborClassifier.cs
+++ b/src/Lucene.Net.Classification/KNearestNeighborClassifier.cs
@@ -97,9 +97,9 @@ namespace Lucene.Net.Classification
             foreach (ScoreDoc scoreDoc in topDocs.ScoreDocs)
             {
                 BytesRef cl = new BytesRef(_indexSearcher.Doc(scoreDoc.Doc).GetField(_classFieldName).GetStringValue());
-                if (classCounts.ContainsKey(cl))
+                if (classCounts.TryGetValue(cl, out int value))
                 {
-                    classCounts[cl] = classCounts[cl] + 1;
+                    classCounts[cl] = value + 1;
                 }
                 else
                 {
diff --git a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs
index ddfaaf9..de47309 100644
--- a/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs
+++ b/src/Lucene.Net.Expressions/JS/JavascriptCompiler.cs
@@ -261,16 +261,11 @@ namespace Lucene.Net.Expressions.JS
                     }
                 case JavascriptParser.NAMESPACE_ID:
                     {
-                        int index;
-                        if (externalsMap.ContainsKey(text))
+                        if (!externalsMap.TryGetValue(text, out int index))
                         {
-                            index = externalsMap[text];
-                        }
-                        else
-                        {
-                            index = externalsMap.Count;
-                            externalsMap[text] = index;
+                            externalsMap[text] = index = externalsMap.Count;
                         }
+
                         gen.Emit(OpCodes.Nop);
 
                         gen.Emit(OpCodes.Ldarg_2);
diff --git a/src/Lucene.Net.Facet/FacetsConfig.cs b/src/Lucene.Net.Facet/FacetsConfig.cs
index d800319..1030b73 100644
--- a/src/Lucene.Net.Facet/FacetsConfig.cs
+++ b/src/Lucene.Net.Facet/FacetsConfig.cs
@@ -160,14 +160,14 @@ namespace Lucene.Net.Facet
         {
             lock (this)
             {
-                if (!fieldTypes.ContainsKey(dimName))
+                // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+                if (!fieldTypes.TryGetValue(dimName, out DimConfig fieldType))
                 {
-                    var ft = new DimConfig { IsHierarchical = v };
-                    fieldTypes[dimName] = ft;
+                    fieldTypes[dimName] = new DimConfig { IsHierarchical = v };
                 }
                 else
                 {
-                    fieldTypes[dimName].IsHierarchical = v;
+                    fieldType.IsHierarchical = v;
                 }
             }
         }
@@ -180,14 +180,14 @@ namespace Lucene.Net.Facet
         {
             lock (this)
             {
-                if (!fieldTypes.ContainsKey(dimName))
+                // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+                if (!fieldTypes.TryGetValue(dimName, out DimConfig fieldType))
                 {
-                    var ft = new DimConfig { IsMultiValued = v };
-                    fieldTypes[dimName] = ft;
+                    fieldTypes[dimName] = new DimConfig { IsMultiValued = v };
                 }
                 else
                 {
-                    fieldTypes[dimName].IsMultiValued = v;
+                    fieldType.IsMultiValued = v;
                 }
             }
         }
@@ -201,14 +201,14 @@ namespace Lucene.Net.Facet
         {
             lock (this)
             {
-                if (!fieldTypes.ContainsKey(dimName))
+                // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+                if (!fieldTypes.TryGetValue(dimName, out DimConfig fieldType))
                 {
-                    var ft = new DimConfig { RequireDimCount = v };
-                    fieldTypes[dimName] = ft;
+                    fieldTypes[dimName] = new DimConfig { RequireDimCount = v };
                 }
                 else
                 {
-                    fieldTypes[dimName].RequireDimCount = v;
+                    fieldType.RequireDimCount = v;
                 }
             }
         }
@@ -222,14 +222,14 @@ namespace Lucene.Net.Facet
         {
             lock (this)
             {
-                if (!fieldTypes.ContainsKey(dimName))
+                // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+                if (!fieldTypes.TryGetValue(dimName, out DimConfig fieldType))
                 {
-                    var ft = new DimConfig { IndexFieldName = indexFieldName };
-                    fieldTypes[dimName] = ft;
+                    fieldTypes[dimName] = new DimConfig { IndexFieldName = indexFieldName };
                 }
                 else
                 {
-                    fieldTypes[dimName].IndexFieldName = indexFieldName;
+                    fieldType.IndexFieldName = indexFieldName;
                 }
             }
         }
@@ -237,13 +237,7 @@ namespace Lucene.Net.Facet
         /// <summary>
         /// Returns map of field name to <see cref="DimConfig"/>.
         /// </summary>
-        public virtual IDictionary<string, DimConfig> DimConfigs
-        {
-            get
-            {
-                return fieldTypes;
-            }
-        }
+        public virtual IDictionary<string, DimConfig> DimConfigs => fieldTypes;
 
         private static void CheckSeen(HashSet<string> seenDims, string dim)
         {
diff --git a/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyWriter.cs b/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyWriter.cs
index 2c52168..439c105 100644
--- a/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyWriter.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyWriter.cs
@@ -202,9 +202,9 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
             {
                 string epochStr = null;
                 IDictionary<string, string> commitData = ReadCommitData(directory);
-                if (commitData != null && commitData.ContainsKey(INDEX_EPOCH))
+                if (commitData != null && commitData.TryGetValue(INDEX_EPOCH, out string value))
                 {
-                    epochStr = commitData[INDEX_EPOCH];
+                    epochStr = value;
                 }
                 // no commit data, or no epoch in it means an old taxonomy, so set its epoch to 1, for lack
                 // of a better value.
diff --git a/src/Lucene.Net.Grouping/AbstractSecondPassGroupingCollector.cs b/src/Lucene.Net.Grouping/AbstractSecondPassGroupingCollector.cs
index 396efc6..18eb85a 100644
--- a/src/Lucene.Net.Grouping/AbstractSecondPassGroupingCollector.cs
+++ b/src/Lucene.Net.Grouping/AbstractSecondPassGroupingCollector.cs
@@ -131,7 +131,7 @@ namespace Lucene.Net.Search.Grouping
             float maxScore = float.MinValue;
             foreach (var group in groups)
             {
-                AbstractSecondPassGroupingCollector.SearchGroupDocs<TGroupValue> groupDocs = m_groupMap.ContainsKey(group.GroupValue) ? m_groupMap[group.GroupValue] : null;
+                AbstractSecondPassGroupingCollector.SearchGroupDocs<TGroupValue> groupDocs = m_groupMap[group.GroupValue];
                 TopDocs topDocs = groupDocs.Collector.GetTopDocs(withinGroupOffset, maxDocsPerGroup);
                 groupDocsResult[groupIDX++] = new GroupDocs<TGroupValue>(float.NaN,
                                                                               topDocs.MaxScore,
diff --git a/src/Lucene.Net.Grouping/SearchGroup.cs b/src/Lucene.Net.Grouping/SearchGroup.cs
index c03d93c..a34e24b 100644
--- a/src/Lucene.Net.Grouping/SearchGroup.cs
+++ b/src/Lucene.Net.Grouping/SearchGroup.cs
@@ -331,8 +331,7 @@ namespace Lucene.Net.Search.Grouping
                 while (shard.Iter.MoveNext())
                 {
                     ISearchGroup<T> group = shard.Next();
-                    MergedGroup<T> mergedGroup = groupsSeen.ContainsKey(group.GroupValue) ? groupsSeen[group.GroupValue] : null;
-                    bool isNew = mergedGroup == null;
+                    bool isNew = !groupsSeen.TryGetValue(group.GroupValue, out MergedGroup<T> mergedGroup) || mergedGroup == null;
                     //System.out.println("    next group=" + (group.groupValue == null ? "null" : ((BytesRef) group.groupValue).utf8ToString()) + " sort=" + Arrays.toString(group.sortValues));
 
                     if (isNew)
diff --git a/src/Lucene.Net.QueryParser/Classic/QueryParserBase.cs b/src/Lucene.Net.QueryParser/Classic/QueryParserBase.cs
index 0dcffee..cafc31f 100644
--- a/src/Lucene.Net.QueryParser/Classic/QueryParserBase.cs
+++ b/src/Lucene.Net.QueryParser/Classic/QueryParserBase.cs
@@ -365,13 +365,13 @@ namespace Lucene.Net.QueryParsers.Classic
                 return this.dateResolution;
             }
 
-            if (!fieldToDateResolution.ContainsKey(fieldName))
+            if (!fieldToDateResolution.TryGetValue(fieldName, out DateTools.Resolution resolution))
             {
                 // no date resolutions set for the given field; return default date resolution instead
                 return this.dateResolution;
             }
 
-            return fieldToDateResolution[fieldName];
+            return resolution;
         }
 
         /// <summary>
diff --git a/src/Lucene.Net.QueryParser/Ext/Extensions.cs b/src/Lucene.Net.QueryParser/Ext/Extensions.cs
index 195940f..44c7d9b 100644
--- a/src/Lucene.Net.QueryParser/Ext/Extensions.cs
+++ b/src/Lucene.Net.QueryParser/Ext/Extensions.cs
@@ -86,17 +86,14 @@ namespace Lucene.Net.QueryParsers.Ext
         /// <code>null</code> if no extension can be found for the key.</returns>
         public ParserExtension GetExtension(string key)
         {
-            if (key == null || !this.extensions.ContainsKey(key)) return null;
-            return this.extensions[key];
+            if (key == null || !this.extensions.TryGetValue(key, out ParserExtension value)) return null;
+            return value;
         }
 
         /// <summary>
         /// Returns the extension field delimiter
         /// </summary>
-        public virtual char ExtensionFieldDelimiter
-        {
-            get { return extensionFieldDelimiter; }
-        }
+        public virtual char ExtensionFieldDelimiter => extensionFieldDelimiter;
 
         /// <summary>
         /// Splits a extension field and returns the field / extension part as a
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs
index b779f9a..256f625 100644
--- a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs
@@ -194,6 +194,8 @@ namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
             return this.tags[CultureInfo.InvariantCulture.TextInfo.ToLower(tagName)];
         }
 
+        // LUCENENET TODO: API - Create TryGetTag method to combine the above 2 operations
+
         private IQueryNode parent = null;
 
         private void SetParent(IQueryNode parent)
diff --git a/src/Lucene.Net.QueryParser/Surround/Query/SpanNearClauseFactory.cs b/src/Lucene.Net.QueryParser/Surround/Query/SpanNearClauseFactory.cs
index 8fbc219..6bcd67b 100644
--- a/src/Lucene.Net.QueryParser/Surround/Query/SpanNearClauseFactory.cs
+++ b/src/Lucene.Net.QueryParser/Surround/Query/SpanNearClauseFactory.cs
@@ -86,8 +86,8 @@ namespace Lucene.Net.QueryParsers.Surround.Query
         protected virtual void AddSpanQueryWeighted(SpanQuery sq, float weight)
         {
             float w;
-            if (weightBySpanQuery.ContainsKey(sq))
-                w = weightBySpanQuery[sq] + weight;
+            if (weightBySpanQuery.TryGetValue(sq, out float weightValue))
+                w = weightValue + weight;
             else
                 w = weight;
             weightBySpanQuery[sq] = w;
diff --git a/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs b/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
index 9717393..d9cba86 100644
--- a/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Analysis/BaseTokenStreamTestCase.cs
@@ -305,7 +305,7 @@ namespace Lucene.Net.Analysis
 
                             int posLength = posLengthAtt.PositionLength;
 
-                            if (!posToStartOffset.ContainsKey(pos))
+                            if (!posToStartOffset.TryGetValue(pos, out int? oldStartOffset))
                             {
                                 // First time we've seen a token leaving from this position:
                                 posToStartOffset[pos] = startOffset;
@@ -316,12 +316,12 @@ namespace Lucene.Net.Analysis
                                 // We've seen a token leaving from this position
                                 // before; verify the startOffset is the same:
                                 //System.out.println("  + vs " + pos + " -> " + startOffset);
-                                Assert.AreEqual((int)posToStartOffset[pos], startOffset, "pos=" + pos + " posLen=" + posLength + " token=" + termAtt);
+                                Assert.AreEqual(oldStartOffset.GetValueOrDefault(), startOffset, "pos=" + pos + " posLen=" + posLength + " token=" + termAtt);
                             }
 
                             int endPos = pos + posLength;
 
-                            if (!posToEndOffset.ContainsKey(endPos))
+                            if (!posToEndOffset.TryGetValue(endPos, out int? oldEndOffset))
                             {
                                 // First time we've seen a token arriving to this position:
                                 posToEndOffset[endPos] = endOffset;
@@ -332,7 +332,7 @@ namespace Lucene.Net.Analysis
                                 // We've seen a token arriving to this position
                                 // before; verify the endOffset is the same:
                                 //System.out.println("  + ve " + endPos + " -> " + endOffset);
-                                Assert.AreEqual((int)posToEndOffset[endPos], endOffset, "pos=" + pos + " posLen=" + posLength + " token=" + termAtt);
+                                Assert.AreEqual(oldEndOffset.GetValueOrDefault(), endOffset, "pos=" + pos + " posLen=" + posLength + " token=" + termAtt);
                             }
                         }
                     }
diff --git a/src/Lucene.Net.TestFramework/Analysis/ValidatingTokenFilter.cs b/src/Lucene.Net.TestFramework/Analysis/ValidatingTokenFilter.cs
index f0e0de2..238c317 100644
--- a/src/Lucene.Net.TestFramework/Analysis/ValidatingTokenFilter.cs
+++ b/src/Lucene.Net.TestFramework/Analysis/ValidatingTokenFilter.cs
@@ -119,7 +119,7 @@ namespace Lucene.Net.Analysis
 
             if (offsetAtt != null && posIncAtt != null && offsetsAreCorrect)
             {
-                if (!posToStartOffset.ContainsKey(pos))
+                if (!posToStartOffset.TryGetValue(pos, out int oldStartOffset))
                 {
                     // First time we've seen a token leaving from this position:
                     posToStartOffset[pos] = startOffset;
@@ -130,7 +130,6 @@ namespace Lucene.Net.Analysis
                     // We've seen a token leaving from this position
                     // before; verify the startOffset is the same:
                     //System.out.println("  + vs " + pos + " -> " + startOffset);
-                    int oldStartOffset = posToStartOffset[pos];
                     if (oldStartOffset != startOffset)
                     {
                         throw new Exception(name + ": inconsistent startOffset at pos=" + pos + ": " + oldStartOffset + " vs " + startOffset + "; token=" + termAtt);
@@ -139,7 +138,7 @@ namespace Lucene.Net.Analysis
 
                 int endPos = pos + posLen;
 
-                if (!posToEndOffset.ContainsKey(endPos))
+                if (!posToEndOffset.TryGetValue(endPos, out int oldEndOffset))
                 {
                     // First time we've seen a token arriving to this position:
                     posToEndOffset[endPos] = endOffset;
@@ -150,7 +149,6 @@ namespace Lucene.Net.Analysis
                     // We've seen a token arriving to this position
                     // before; verify the endOffset is the same:
                     //System.out.println("  + ve " + endPos + " -> " + endOffset);
-                    int oldEndOffset = posToEndOffset[endPos];
                     if (oldEndOffset != endOffset)
                     {
                         throw new Exception(name + ": inconsistent endOffset at pos=" + endPos + ": " + oldEndOffset + " vs " + endOffset + "; token=" + termAtt);
diff --git a/src/Lucene.Net.TestFramework/Index/BaseIndexFileFormatTestCase.cs b/src/Lucene.Net.TestFramework/Index/BaseIndexFileFormatTestCase.cs
index 9c1da79..739ee68 100644
--- a/src/Lucene.Net.TestFramework/Index/BaseIndexFileFormatTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/BaseIndexFileFormatTestCase.cs
@@ -87,7 +87,7 @@ namespace Lucene.Net.Index
             foreach (string file in d.ListAll())
             {
                 string ext = IndexFileNames.GetExtension(file);
-                long previousLength = bytesUsedByExtension.ContainsKey(ext) ? bytesUsedByExtension[ext] : 0;
+                long previousLength = bytesUsedByExtension.TryGetValue(ext, out long length) ? length : 0;
                 bytesUsedByExtension[ext] = previousLength + d.FileLength(file);
             }
             foreach (string item in ExcludedExtensionsFromByteCounts)
diff --git a/src/Lucene.Net.TestFramework/Index/BaseTermVectorsFormatTestCase.cs b/src/Lucene.Net.TestFramework/Index/BaseTermVectorsFormatTestCase.cs
index 835734d..37d3126 100644
--- a/src/Lucene.Net.TestFramework/Index/BaseTermVectorsFormatTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/BaseTermVectorsFormatTestCase.cs
@@ -340,24 +340,24 @@ namespace Lucene.Net.Index
                 startOffsetToTerms = new Dictionary<int?, ISet<int?>>(len);
                 for (int i = 0; i < len; ++i)
                 {
-                    if (!positionToTerms.ContainsKey(positions[i]))
+                    if (!positionToTerms.TryGetValue(positions[i], out ISet<int?> positionTerms))
                     {
-                        positionToTerms[positions[i]] = new HashSet<int?>();//size1
+                        positionToTerms[positions[i]] = positionTerms = NewHashSet<int?>(1);
                     }
-                    positionToTerms[positions[i]].Add(i);
-                    if (!startOffsetToTerms.ContainsKey(startOffsets[i]))
+                    positionTerms.Add(i);
+                    if (!startOffsetToTerms.TryGetValue(startOffsets[i], out ISet<int?> startOffsetTerms))
                     {
-                        startOffsetToTerms[startOffsets[i]] = new HashSet<int?>();//size1
+                        startOffsetToTerms[startOffsets[i]] = startOffsetTerms = NewHashSet<int?>(1);
                     }
-                    startOffsetToTerms[startOffsets[i]].Add(i);
+                    startOffsetTerms.Add(i);
                 }
 
                 freqs = new Dictionary<string, int?>();
                 foreach (string term in terms)
                 {
-                    if (freqs.ContainsKey(term))
+                    if (freqs.TryGetValue(term, out int? freq))
                     {
-                        freqs[term] = freqs[term] + 1;
+                        freqs[term] = freq + 1;
                     }
                     else
                     {
@@ -373,6 +373,17 @@ namespace Lucene.Net.Index
                 pAtt = AddAttribute<IPayloadAttribute>();
             }
 
+            // LUCENENET: Since capacity wasn't added until .NET Standard 2.1,
+            // this wrapper ensures we can pass it even if it is ignored
+            private ISet<T> NewHashSet<T>(int capacity)
+            {
+#if FEATURE_HASHSET_CAPACITY
+                return new HashSet<T>(capacity);
+#else
+                return new HashSet<T>();
+#endif
+            }
+
             public virtual bool HasPayloads()
             {
                 foreach (BytesRef payload in payloads)
diff --git a/src/Lucene.Net.TestFramework/Util/Fst/FSTTester.cs b/src/Lucene.Net.TestFramework/Util/Fst/FSTTester.cs
index bd36c17..1d3d94e 100644
--- a/src/Lucene.Net.TestFramework/Util/Fst/FSTTester.cs
+++ b/src/Lucene.Net.TestFramework/Util/Fst/FSTTester.cs
@@ -827,8 +827,7 @@ namespace Lucene.Net.Util.Fst
                 for (int idx = 0; idx <= pair.Input.Length; idx++)
                 {
                     scratch.Length = idx;
-                    CountMinOutput<T> cmo = prefixes.ContainsKey(scratch) ? prefixes[scratch] : null;
-                    if (cmo == null)
+                    if (!prefixes.TryGetValue(scratch, out CountMinOutput<T> cmo) || cmo == null)
                     {
                         cmo = new CountMinOutput<T>();
                         cmo.Count = 1;
@@ -893,7 +892,7 @@ namespace Lucene.Net.Util.Fst
                         // consult our parent
                         scratch.Length = prefix.Length - 1;
                         Array.Copy(prefix.Int32s, prefix.Offset, scratch.Int32s, 0, scratch.Length);
-                        CountMinOutput<T> cmo2 = prefixes.ContainsKey(scratch) ? prefixes[scratch] : null;
+                        prefixes.TryGetValue(scratch, out CountMinOutput<T> cmo2);
                         //System.out.println("    parent count = " + (cmo2 == null ? -1 : cmo2.count));
                         keep = cmo2 != null && ((prune2 > 1 && cmo2.Count >= prune2) || (prune2 == 1 && (cmo2.Count >= 2 || prefix.Length <= 1)));
                     }
@@ -920,8 +919,7 @@ namespace Lucene.Net.Util.Fst
                     scratch.Length--;
                     while (scratch.Length >= 0)
                     {
-                        CountMinOutput<T> cmo2 = prefixes.ContainsKey(scratch) ? prefixes[scratch] : null;
-                        if (cmo2 != null)
+                        if (prefixes.TryGetValue(scratch, out CountMinOutput<T> cmo2) && cmo2 != null)
                         {
                             //System.out.println("    clear isLeaf " + inputToString(inputMode, scratch));
                             cmo2.IsLeaf = false;
@@ -965,7 +963,7 @@ namespace Lucene.Net.Util.Fst
                 {
                     Console.WriteLine("  fstEnum.next prefix=" + InputToString(inputMode, current.Input, false) + " output=" + outputs.OutputToString(current.Output));
                 }
-                CountMinOutput<T> cmo = prefixes.ContainsKey(current.Input) ? prefixes[current.Input] : null;
+                prefixes.TryGetValue(current.Input, out CountMinOutput<T> cmo);
                 Assert.IsNotNull(cmo);
                 Assert.IsTrue(cmo.IsLeaf || cmo.IsFinal);
                 //if (cmo.isFinal && !cmo.isLeaf) {
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestRandomChains.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestRandomChains.cs
index 9512f1f..0e8d27a 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestRandomChains.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Core/TestRandomChains.cs
@@ -936,14 +936,12 @@ namespace Lucene.Net.Analysis.Core
 
             private bool Broken(ConstructorInfo ctor, object[] args)
             {
-                IPredicate<object[]> pred = brokenConstructors.ContainsKey(ctor) ? brokenConstructors[ctor] : null;
-                return pred != null && pred.Apply(args);
+                return brokenConstructors.TryGetValue(ctor, out IPredicate<object[]> pred) && pred != null && pred.Apply(args);
             }
 
             private bool BrokenOffsets(ConstructorInfo ctor, object[] args)
             {
-                IPredicate<object[]> pred = brokenOffsetsConstructors.ContainsKey(ctor) ? brokenOffsetsConstructors[ctor] : null;
-                return pred != null && pred.Apply(args);
+                return brokenOffsetsConstructors.TryGetValue(ctor, out IPredicate<object[]> pred) && pred != null && pred.Apply(args);
             }
 
             // create a new random tokenizer from classpath
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Synonym/TestSynonymMapFilter.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Synonym/TestSynonymMapFilter.cs
index 7dd932d..0dd0057 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Synonym/TestSynonymMapFilter.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Synonym/TestSynonymMapFilter.cs
@@ -485,8 +485,7 @@ namespace Lucene.Net.Analysis.Synonym
             for (int synIDX = 0; synIDX < numSyn; synIDX++)
             {
                 string synIn = GetRandomString('a', alphabetSize, TestUtil.NextInt32(Random, 1, 5)).Trim();
-                OneSyn s = synMap.ContainsKey(synIn) ? synMap[synIn] : null;
-                if (s == null)
+                if (!synMap.TryGetValue(synIn, out OneSyn s) || s == null)
                 {
                     s = new OneSyn();
                     s.@in = synIn;
diff --git a/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyFacetCounts.cs b/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyFacetCounts.cs
index 707cad3..3ae7d05 100644
--- a/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyFacetCounts.cs
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyFacetCounts.cs
@@ -848,8 +848,7 @@ namespace Lucene.Net.Facet.Taxonomy
                         {
                             if (doc.dims[j] != null)
                             {
-                                int? v = expectedCounts[j].ContainsKey(doc.dims[j]) ? expectedCounts[j][doc.dims[j]] : null;
-                                if (v == null)
+                                if (!expectedCounts[j].TryGetValue(doc.dims[j], out int? v) || v == null)
                                 {
                                     expectedCounts[j][doc.dims[j]] = 1;
                                 }
diff --git a/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyFacetSumValueSource.cs b/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyFacetSumValueSource.cs
index 1430148..39d3822 100644
--- a/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyFacetSumValueSource.cs
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/TestTaxonomyFacetSumValueSource.cs
@@ -569,8 +569,7 @@ namespace Lucene.Net.Facet.Taxonomy
                         {
                             if (doc.dims[j] != null)
                             {
-                                float? v = expectedValues[j].ContainsKey(doc.dims[j]) ? expectedValues[j][doc.dims[j]] : null;
-                                if (v == null)
+                                if (!expectedValues[j].TryGetValue(doc.dims[j], out float? v) || v == null)
                                 {
                                     expectedValues[j][doc.dims[j]] = doc.value;
                                 }
diff --git a/src/Lucene.Net.Tests.Grouping/AllGroupHeadsCollectorTest.cs b/src/Lucene.Net.Tests.Grouping/AllGroupHeadsCollectorTest.cs
index a876658..3cfb23d 100644
--- a/src/Lucene.Net.Tests.Grouping/AllGroupHeadsCollectorTest.cs
+++ b/src/Lucene.Net.Tests.Grouping/AllGroupHeadsCollectorTest.cs
@@ -489,14 +489,14 @@ namespace Lucene.Net.Search.Grouping
                     continue;
                 }
 
-                if (!groupHeads.ContainsKey(groupDoc.group))
+                if (!groupHeads.TryGetValue(groupDoc.group, out List<GroupDoc> grouphead))
                 {
                     List<GroupDoc> list = new List<GroupDoc>();
                     list.Add(groupDoc);
                     groupHeads[groupDoc.group] = list;
                     continue;
                 }
-                groupHeads[groupDoc.group].Add(groupDoc);
+                grouphead.Add(groupDoc);
             }
 
             int[] allGroupHeads = new int[groupHeads.Count];
diff --git a/src/Lucene.Net.Tests.Grouping/GroupFacetCollectorTest.cs b/src/Lucene.Net.Tests.Grouping/GroupFacetCollectorTest.cs
index 154dc15..9715d0a 100644
--- a/src/Lucene.Net.Tests.Grouping/GroupFacetCollectorTest.cs
+++ b/src/Lucene.Net.Tests.Grouping/GroupFacetCollectorTest.cs
@@ -633,11 +633,10 @@ namespace Lucene.Net.Search.Grouping
                 }
 
                 string contentStr = contentBrs[random.nextInt(contentBrs.Length)];
-                if (!searchTermToFacetToGroups.ContainsKey(contentStr))
+                if (!searchTermToFacetToGroups.TryGetValue(contentStr, out HashMap<string, ISet<string>> facetToGroups))
                 {
-                    searchTermToFacetToGroups[contentStr] = new HashMap<string, ISet<string>>();
+                    searchTermToFacetToGroups[contentStr] = facetToGroups = new HashMap<string, ISet<string>>();
                 }
-                IDictionary<string, ISet<string>> facetToGroups = searchTermToFacetToGroups[contentStr];
 
                 List<string> facetVals = new List<string>();
                 if (useDv || random.nextInt(24) != 18)
@@ -646,11 +645,10 @@ namespace Lucene.Net.Search.Grouping
                     {
                         string facetValue = facetValues[random.nextInt(facetValues.size())];
                         uniqueFacetValues.Add(facetValue);
-                        if (!facetToGroups.ContainsKey(facetValue))
+                        if (!facetToGroups.TryGetValue(facetValue, out ISet<string> groupsInFacet))
                         {
-                            facetToGroups[facetValue] = new HashSet<string>();
+                            facetToGroups[facetValue] = groupsInFacet = new HashSet<string>();
                         }
-                        ISet<string> groupsInFacet = facetToGroups[facetValue];
                         groupsInFacet.add(groupValue);
                         if (groupsInFacet.size() > facetWithMostGroups)
                         {
@@ -666,11 +664,10 @@ namespace Lucene.Net.Search.Grouping
                         {
                             string facetValue = facetValues[random.nextInt(facetValues.size())];
                             uniqueFacetValues.Add(facetValue);
-                            if (!facetToGroups.ContainsKey(facetValue))
+                            if (!facetToGroups.TryGetValue(facetValue, out ISet<string> groupsInFacet))
                             {
-                                facetToGroups[facetValue] = new HashSet<string>();
+                                facetToGroups[facetValue] = groupsInFacet = new HashSet<string>();
                             }
-                            ISet<string> groupsInFacet = facetToGroups[facetValue];
                             groupsInFacet.add(groupValue);
                             if (groupsInFacet.size() > facetWithMostGroups)
                             {
@@ -684,11 +681,10 @@ namespace Lucene.Net.Search.Grouping
                 else
                 {
                     uniqueFacetValues.Add(null);
-                    if (!facetToGroups.ContainsKey(null))
+                    if (!facetToGroups.TryGetValue(null, out ISet<string> groupsInFacet))
                     {
-                        facetToGroups.Put(null, new HashSet<string>());
+                        facetToGroups[null] = groupsInFacet = new HashSet<string>();
                     }
-                    ISet<string> groupsInFacet = facetToGroups[null];
                     groupsInFacet.add(groupValue);
                     if (groupsInFacet.size() > facetWithMostGroups)
                     {
@@ -798,8 +794,7 @@ namespace Lucene.Net.Search.Grouping
                     continue;
                 }
 
-                ISet<string> groups = facetGroups.ContainsKey(facetValue) ? facetGroups[facetValue] : null;
-                int count = groups != null ? groups.size() : 0;
+                int count = facetGroups.TryGetValue(facetValue, out ISet<string> groups) && groups != null ? groups.size() : 0;
                 if (count >= minCount)
                 {
                     entries.Add(new TermGroupFacetCollector.FacetEntry(new BytesRef(facetValue), count));
diff --git a/src/Lucene.Net.Tests.Grouping/TestGrouping.cs b/src/Lucene.Net.Tests.Grouping/TestGrouping.cs
index 5ddd5ae..6647441 100644
--- a/src/Lucene.Net.Tests.Grouping/TestGrouping.cs
+++ b/src/Lucene.Net.Tests.Grouping/TestGrouping.cs
@@ -685,12 +685,12 @@ namespace Lucene.Net.Search.Grouping
 
             foreach (GroupDoc groupDoc in groupDocs)
             {
-                if (!groupMap.ContainsKey(groupDoc.group))
+                if (!groupMap.TryGetValue(groupDoc.group, out List<GroupDoc> docs))
                 {
                     groupValues.Add(groupDoc.group);
-                    groupMap.Put(groupDoc.group, new List<GroupDoc>());
+                    groupMap[groupDoc.group] = docs = new List<GroupDoc>();
                 }
-                groupMap[groupDoc.group].Add(groupDoc);
+                docs.Add(groupDoc);
             }
 
             RandomIndexWriter w = new RandomIndexWriter(
diff --git a/src/Lucene.Net.Tests.Highlighter/VectorHighlight/SimpleFragmentsBuilderTest.cs b/src/Lucene.Net.Tests.Highlighter/VectorHighlight/SimpleFragmentsBuilderTest.cs
index 52a44d1..9e36c2b 100644
--- a/src/Lucene.Net.Tests.Highlighter/VectorHighlight/SimpleFragmentsBuilderTest.cs
+++ b/src/Lucene.Net.Tests.Highlighter/VectorHighlight/SimpleFragmentsBuilderTest.cs
@@ -354,11 +354,11 @@ namespace Lucene.Net.Search.VectorHighlight
         private String getRandomValue(String[] randomValues, IDictionary<String, ISet<int>> valueToDocId, int docId)
         {
             String value = randomValues[Random.nextInt(randomValues.Length)];
-            if (!valueToDocId.ContainsKey(value))
+            if (!valueToDocId.TryGetValue(value, out ISet<int> docIds))
             {
-                valueToDocId.Put(value, new HashSet<int>());
+                valueToDocId[value] = docIds = new HashSet<int>();
             }
-            valueToDocId[value].Add(docId);
+            docIds.Add(docId);
             return value;
         }
 
diff --git a/src/Lucene.Net.Tests.Join/TestJoinUtil.cs b/src/Lucene.Net.Tests.Join/TestJoinUtil.cs
index af98042..f98e52d 100644
--- a/src/Lucene.Net.Tests.Join/TestJoinUtil.cs
+++ b/src/Lucene.Net.Tests.Join/TestJoinUtil.cs
@@ -616,32 +616,32 @@ namespace Lucene.Net.Tests.Join
                     docs[i].LinkValues.Add(linkValue);
                     if (from)
                     {
-                        if (!context.FromDocuments.ContainsKey(linkValue))
+                        if (!context.FromDocuments.TryGetValue(linkValue, out IList<RandomDoc> fromDocs))
                         {
-                            context.FromDocuments[linkValue] = new List<RandomDoc>();
+                            context.FromDocuments[linkValue] = fromDocs = new List<RandomDoc>();
                         }
-                        if (!context.RandomValueFromDocs.ContainsKey(value))
+                        if (!context.RandomValueFromDocs.TryGetValue(value, out IList<RandomDoc> randomValueFromDocs))
                         {
-                            context.RandomValueFromDocs[value] = new List<RandomDoc>();
+                            context.RandomValueFromDocs[value] = randomValueFromDocs = new List<RandomDoc>();
                         }
 
-                        context.FromDocuments[linkValue].Add(docs[i]);
-                        context.RandomValueFromDocs[value].Add(docs[i]);
+                        fromDocs.Add(docs[i]);
+                        randomValueFromDocs.Add(docs[i]);
                         document.Add(NewTextField(Random, "from", linkValue, Field.Store.NO));
                     }
                     else
                     {
-                        if (!context.ToDocuments.ContainsKey(linkValue))
+                        if (!context.ToDocuments.TryGetValue(linkValue, out IList<RandomDoc> toDocuments))
                         {
-                            context.ToDocuments[linkValue] = new List<RandomDoc>();
+                            context.ToDocuments[linkValue] = toDocuments = new List<RandomDoc>();
                         }
-                        if (!context.RandomValueToDocs.ContainsKey(value))
+                        if (!context.RandomValueToDocs.TryGetValue(value, out IList<RandomDoc> randomValueToDocs))
                         {
-                            context.RandomValueToDocs[value] = new List<RandomDoc>();
+                            context.RandomValueToDocs[value] = randomValueToDocs = new List<RandomDoc>();
                         }
 
-                        context.ToDocuments[linkValue].Add(docs[i]);
-                        context.RandomValueToDocs[value].Add(docs[i]);
+                        toDocuments.Add(docs[i]);
+                        randomValueToDocs.Add(docs[i]);
                         document.Add(NewTextField(Random, "to", linkValue, Field.Store.NO));
                     }
                 }
@@ -791,8 +791,7 @@ namespace Lucene.Net.Tests.Join
                 while ((ord = docTermOrds.NextOrd()) != SortedSetDocValues.NO_MORE_ORDS)
                 {
                     docTermOrds.LookupOrd(ord, joinValue);
-                    var joinScore = JoinValueToJoinScores.ContainsKey(joinValue) ? JoinValueToJoinScores[joinValue] : null;
-                    if (joinScore == null)
+                    if (!JoinValueToJoinScores.TryGetValue(joinValue, out JoinScore joinScore) || joinScore == null)
                     {
                         JoinValueToJoinScores[BytesRef.DeepCopyOf(joinValue)] = joinScore = new JoinScore();
                     }
@@ -850,8 +849,7 @@ namespace Lucene.Net.Tests.Join
                     return;
                 }
 
-                var joinScore = JoinValueToJoinScores.ContainsKey(joinValue) ? JoinValueToJoinScores[joinValue] : null;
-                if (joinScore == null)
+                if (!JoinValueToJoinScores.TryGetValue(joinValue, out JoinScore joinScore) || joinScore == null)
                 {
                     JoinValueToJoinScores[BytesRef.DeepCopyOf(joinValue)] = joinScore = new JoinScore();
                 }
@@ -904,8 +902,7 @@ namespace Lucene.Net.Tests.Join
                 while ((ord = docTermOrds.NextOrd()) != SortedSetDocValues.NO_MORE_ORDS)
                 {
                     docTermOrds.LookupOrd(ord, scratch);
-                    JoinScore joinScore = _joinValueToJoinScores.ContainsKey(scratch) ? _joinValueToJoinScores[scratch] : null;
-                    if (joinScore == null)
+                    if (!_joinValueToJoinScores.TryGetValue(scratch, out JoinScore joinScore) || joinScore == null)
                     {
                         continue;
                     }
@@ -961,8 +958,7 @@ namespace Lucene.Net.Tests.Join
             public virtual void Collect(int doc)
             {
                 terms.Get(doc, spare);
-                JoinScore joinScore = JoinValueToJoinScores.ContainsKey(spare) ? JoinValueToJoinScores[spare] : null;
-                if (joinScore == null)
+                if (!JoinValueToJoinScores.TryGetValue(spare, out JoinScore joinScore) || joinScore == null)
                 {
                     return;
                 }
@@ -1046,8 +1042,7 @@ namespace Lucene.Net.Tests.Join
             }
 
             FixedBitSet expectedResult = new FixedBitSet(topLevelReader.MaxDoc);
-            IList<RandomDoc> matchingDocs = randomValueDocs.ContainsKey(queryValue) ? randomValueDocs[queryValue] : null;
-            if (matchingDocs == null)
+            if (!randomValueDocs.TryGetValue(queryValue, out IList<RandomDoc> matchingDocs) || matchingDocs == null)
             {
                 return new FixedBitSet(topLevelReader.MaxDoc);
             }
@@ -1056,8 +1051,7 @@ namespace Lucene.Net.Tests.Join
             {
                 foreach (string linkValue in matchingDoc.LinkValues)
                 {
-                    IList<RandomDoc> otherMatchingDocs = linkValueDocuments.ContainsKey(linkValue) ? linkValueDocuments[linkValue] : null;
-                    if (otherMatchingDocs == null)
+                    if (!linkValueDocuments.TryGetValue(linkValue, out IList<RandomDoc> otherMatchingDocs) || otherMatchingDocs == null)
                     {
                         continue;
                     }
diff --git a/src/Lucene.Net.Tests.Misc/Document/TestLazyDocument.cs b/src/Lucene.Net.Tests.Misc/Document/TestLazyDocument.cs
index 10b0bfe..9b67986 100644
--- a/src/Lucene.Net.Tests.Misc/Document/TestLazyDocument.cs
+++ b/src/Lucene.Net.Tests.Misc/Document/TestLazyDocument.cs
@@ -128,8 +128,8 @@ namespace Lucene.Net.Documents
                     }
                     else
                     {
-                        int count = fieldValueCounts.ContainsKey(f.Name) ?
-                          fieldValueCounts[f.Name] : 0;
+                        if (!fieldValueCounts.TryGetValue(f.Name, out int count))
+                            count = 0;
                         count++;
                         fieldValueCounts.Put(f.Name, count);
                         assertTrue(f.Name + " is " + f.GetType(),
diff --git a/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/AnalyzingSuggesterTest.cs b/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/AnalyzingSuggesterTest.cs
index abac4aa..fe32ef8 100644
--- a/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/AnalyzingSuggesterTest.cs
+++ b/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/AnalyzingSuggesterTest.cs
@@ -152,9 +152,9 @@ namespace Lucene.Net.Search.Suggest.Analyzing
                 string title = nextDoc.GetField("title").GetStringValue();
                 int randomWeight = Random.nextInt(100);
                 keys.Add(new Input(title, randomWeight));
-                if (!mapping.ContainsKey(title) || mapping[title] < randomWeight)
+                if (!mapping.TryGetValue(title, out long titleValue) || titleValue < randomWeight)
                 {
-                    mapping.Put(title, Convert.ToInt64(randomWeight));
+                    mapping[title] = Convert.ToInt64(randomWeight);
                 }
             }
             AnalyzingSuggester analyzingSuggester = new AnalyzingSuggester(new MockAnalyzer(Random), new MockAnalyzer(Random),
diff --git a/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/TestFreeTextSuggester.cs b/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/TestFreeTextSuggester.cs
index 1f7d7dd..9b0e852 100644
--- a/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/TestFreeTextSuggester.cs
+++ b/src/Lucene.Net.Tests.Suggest/Suggest/Analyzing/TestFreeTextSuggester.cs
@@ -514,8 +514,7 @@ namespace Lucene.Net.Search.Suggest.Analyzing
                             b.append(doc[j]);
                         }
                         string token = b.toString();
-                        int? curCount = model.ContainsKey(token) ? model[token] : null;
-                        if (curCount == null)
+                        if (!model.TryGetValue(token, out int? curCount) || curCount == null)
                         {
                             model.Put(token, 1);
                         }
@@ -525,7 +524,7 @@ namespace Lucene.Net.Search.Suggest.Analyzing
                         }
                         if (VERBOSE)
                         {
-                            Console.WriteLine("  add '" + token + "' -> count=" + (model.ContainsKey(token) ? model[token].ToString() : ""));
+                            Console.WriteLine("  add '" + token + "' -> count=" + (model.TryGetValue(token, out int? count) ? (count.HasValue ? count.ToString() : "null") : ""));
                         }
                     }
                 }
@@ -630,8 +629,7 @@ namespace Lucene.Net.Search.Suggest.Analyzing
                     {
                         //int? count = gramCounts.get(i - 1).get(context);
                         var gramCount = gramCounts[i - 1];
-                        int? count = gramCount.ContainsKey(context) ? gramCount[context] : null;
-                        if (count == null)
+                        if (!gramCount.TryGetValue(context, out int? count) || count == null)
                         {
                             // We never saw this context:
                             backoff *= FreeTextSuggester.ALPHA;
@@ -673,8 +671,7 @@ namespace Lucene.Net.Search.Suggest.Analyzing
                             }
                             string ngram = (context + " " + term).Trim();
                             //Integer count = model.get(ngram);
-                            int? count = model.ContainsKey(ngram) ? model[ngram] : null;
-                            if (count != null)
+                            if (model.TryGetValue(ngram, out int? count) && count != null)
                             {
                                 // LUCENENET NOTE: We need to calculate this as decimal because when using double it can sometimes 
                                 // return numbers that are greater than long.MaxValue, which results in a negative long number.
diff --git a/src/Lucene.Net.Tests.Suggest/Suggest/DocumentDictionaryTest.cs b/src/Lucene.Net.Tests.Suggest/Suggest/DocumentDictionaryTest.cs
index c3b43fe..cac6615 100644
--- a/src/Lucene.Net.Tests.Suggest/Suggest/DocumentDictionaryTest.cs
+++ b/src/Lucene.Net.Tests.Suggest/Suggest/DocumentDictionaryTest.cs
@@ -157,7 +157,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 string field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 //Document doc = docs.Remove(f.Utf8ToString());
                 assertTrue(f.equals(new BytesRef(doc.Get(FIELD_NAME))));
@@ -201,7 +201,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 var field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 assertTrue(f.equals(new BytesRef(doc.Get(FIELD_NAME))));
                 IIndexableField weightField = doc.GetField(WEIGHT_FIELD_NAME);
@@ -246,7 +246,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 string field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 //Document doc = docs.remove(f.utf8ToString());
                 assertTrue(f.equals(new BytesRef(doc.Get(FIELD_NAME))));
@@ -325,7 +325,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 var field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 assertTrue(f.equals(new BytesRef(doc.Get(FIELD_NAME))));
                 IIndexableField weightField = doc.GetField(WEIGHT_FIELD_NAME);
diff --git a/src/Lucene.Net.Tests.Suggest/Suggest/DocumentValueSourceDictionaryTest.cs b/src/Lucene.Net.Tests.Suggest/Suggest/DocumentValueSourceDictionaryTest.cs
index 484e3ae..86866c7 100644
--- a/src/Lucene.Net.Tests.Suggest/Suggest/DocumentValueSourceDictionaryTest.cs
+++ b/src/Lucene.Net.Tests.Suggest/Suggest/DocumentValueSourceDictionaryTest.cs
@@ -116,7 +116,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 string field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 //Document doc = docs.remove(f.utf8ToString());
                 long w1 = doc.GetField(WEIGHT_FIELD_NAME_1).GetInt64ValueOrDefault();
@@ -154,7 +154,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 string field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 long w1 = doc.GetField(WEIGHT_FIELD_NAME_1).GetInt64ValueOrDefault();
                 long w2 = doc.GetField(WEIGHT_FIELD_NAME_2).GetInt64ValueOrDefault();
@@ -197,7 +197,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 string field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 long w1 = doc.GetField(WEIGHT_FIELD_NAME_1).GetInt64ValueOrDefault();
                 long w2 = doc.GetField(WEIGHT_FIELD_NAME_2).GetInt64ValueOrDefault();
@@ -262,7 +262,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 string field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 long w1 = doc.GetField(WEIGHT_FIELD_NAME_1).GetInt64ValueOrDefault();
                 long w2 = doc.GetField(WEIGHT_FIELD_NAME_2).GetInt64ValueOrDefault();
@@ -298,7 +298,7 @@ namespace Lucene.Net.Search.Suggest
             while ((f = inputIterator.Next()) != null)
             {
                 string field = f.Utf8ToString();
-                Document doc = docs.ContainsKey(field) ? docs[field] : null;
+                Document doc = docs[field];
                 docs.Remove(field);
                 assertTrue(f.equals(new BytesRef(doc.Get(FIELD_NAME))));
                 assertEquals(inputIterator.Weight, 10);
diff --git a/src/Lucene.Net.Tests/Index/TestMultiFields.cs b/src/Lucene.Net.Tests/Index/TestMultiFields.cs
index aecb631..79f2a95 100644
--- a/src/Lucene.Net.Tests/Index/TestMultiFields.cs
+++ b/src/Lucene.Net.Tests/Index/TestMultiFields.cs
@@ -79,11 +79,11 @@ namespace Lucene.Net.Index
                     {
                         string s = TestUtil.RandomUnicodeString(Random, 10);
                         BytesRef term = new BytesRef(s);
-                        if (!docs.ContainsKey(term))
+                        if (!docs.TryGetValue(term, out IList<int?> docsTerm))
                         {
-                            docs[term] = new List<int?>();
+                            docs[term] = docsTerm = new List<int?>();
                         }
-                        docs[term].Add(i);
+                        docsTerm.Add(i);
                         terms.Add(term);
                         uniqueTerms.Add(term);
                         f.SetStringValue(s);
diff --git a/src/Lucene.Net.Tests/Index/TestPostingsOffsets.cs b/src/Lucene.Net.Tests/Index/TestPostingsOffsets.cs
index 26187dc..982eed2 100644
--- a/src/Lucene.Net.Tests/Index/TestPostingsOffsets.cs
+++ b/src/Lucene.Net.Tests/Index/TestPostingsOffsets.cs
@@ -297,16 +297,15 @@ namespace Lucene.Net.Index
                     int tokenOffset = Random.Next(5);
 
                     Token token = MakeToken(text, posIncr, offset + offIncr, offset + offIncr + tokenOffset);
-                    if (!actualTokens.ContainsKey(text))
+                    if (!actualTokens.TryGetValue(text, out IDictionary<int?, IList<Token>> postingsByDoc))
                     {
-                        actualTokens[text] = new Dictionary<int?, IList<Token>>();
+                        actualTokens[text] = postingsByDoc = new Dictionary<int?, IList<Token>>();
                     }
-                    IDictionary<int?, IList<Token>> postingsByDoc = actualTokens[text];
-                    if (!postingsByDoc.ContainsKey(docCount))
+                    if (!postingsByDoc.TryGetValue(docCount, out IList<Token> postings))
                     {
-                        postingsByDoc[docCount] = new List<Token>();
+                        postingsByDoc[docCount] = postings = new List<Token>();
                     }
-                    postingsByDoc[docCount].Add(token);
+                    postings.Add(token);
                     tokens.Add(token);
                     pos += posIncr;
                     // stuff abs position into type:
diff --git a/src/Lucene.Net.Tests/Search/TestCustomSearcherSort.cs b/src/Lucene.Net.Tests/Search/TestCustomSearcherSort.cs
index 1676be5..ebb5f9c 100644
--- a/src/Lucene.Net.Tests/Search/TestCustomSearcherSort.cs
+++ b/src/Lucene.Net.Tests/Search/TestCustomSearcherSort.cs
@@ -180,13 +180,13 @@ namespace Lucene.Net.Search
                     int? luceneId = null;
 
                     luceneId = Convert.ToInt32(hits[docnum].Doc);
-                    if (idMap.ContainsKey(luceneId))
+                    if (idMap.TryGetValue(luceneId, out int? value))
                     {
                         StringBuilder message = new StringBuilder(prefix);
                         message.Append("Duplicate key for hit index = ");
                         message.Append(docnum);
                         message.Append(", previous index = ");
-                        message.Append((idMap[luceneId]).ToString());
+                        message.Append(value.ToString());
                         message.Append(", Lucene ID = ");
                         message.Append(luceneId);
                         Log(message.ToString());
diff --git a/src/Lucene.Net/Codecs/PerField/PerFieldDocValuesFormat.cs b/src/Lucene.Net/Codecs/PerField/PerFieldDocValuesFormat.cs
index 5b9cc74..e66d972 100644
--- a/src/Lucene.Net/Codecs/PerField/PerFieldDocValuesFormat.cs
+++ b/src/Lucene.Net/Codecs/PerField/PerFieldDocValuesFormat.cs
@@ -266,11 +266,12 @@ namespace Lucene.Net.Codecs.PerField
                                 Debug.Assert(suffix != null);
                                 DocValuesFormat format = DocValuesFormat.ForName(formatName);
                                 string segmentSuffix = GetFullSegmentSuffix(readState.SegmentSuffix, GetSuffix(formatName, suffix));
-                                if (!formats.ContainsKey(segmentSuffix))
+                                // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+                                if (!formats.TryGetValue(segmentSuffix, out DocValuesProducer field))
                                 {
-                                    formats[segmentSuffix] = format.FieldsProducer(new SegmentReadState(readState, segmentSuffix));
+                                    formats[segmentSuffix] = field = format.FieldsProducer(new SegmentReadState(readState, segmentSuffix));
                                 }
-                                fields[fieldName] = formats[segmentSuffix];
+                                fields[fieldName] = field;
                             }
                         }
                     }
diff --git a/src/Lucene.Net/Codecs/PerField/PerFieldPostingsFormat.cs b/src/Lucene.Net/Codecs/PerField/PerFieldPostingsFormat.cs
index 0b0be1a..2bf9307 100644
--- a/src/Lucene.Net/Codecs/PerField/PerFieldPostingsFormat.cs
+++ b/src/Lucene.Net/Codecs/PerField/PerFieldPostingsFormat.cs
@@ -220,11 +220,12 @@ namespace Lucene.Net.Codecs.PerField
                                 Debug.Assert(suffix != null);
                                 PostingsFormat format = PostingsFormat.ForName(formatName);
                                 string segmentSuffix = GetSuffix(formatName, suffix);
-                                if (!formats.ContainsKey(segmentSuffix))
+                                // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+                                if (!formats.TryGetValue(segmentSuffix, out Codecs.FieldsProducer field))
                                 {
-                                    formats[segmentSuffix] = format.FieldsProducer(new SegmentReadState(readState, segmentSuffix));
+                                    formats[segmentSuffix] = field = format.FieldsProducer(new SegmentReadState(readState, segmentSuffix));
                                 }
-                                fields[fieldName] = formats[segmentSuffix];
+                                fields[fieldName] = field;
                             }
                         }
                     }
diff --git a/src/Lucene.Net/Index/IndexFileDeleter.cs b/src/Lucene.Net/Index/IndexFileDeleter.cs
index 3f1eb20..504983d 100644
--- a/src/Lucene.Net/Index/IndexFileDeleter.cs
+++ b/src/Lucene.Net/Index/IndexFileDeleter.cs
@@ -658,29 +658,19 @@ namespace Lucene.Net.Index
         public bool Exists(string fileName)
         {
             Debug.Assert(IsLocked);
-            if (!refCounts.ContainsKey(fileName))
-            {
-                return false;
-            }
-            else
-            {
-                return GetRefCount(fileName).count > 0;
-            }
+            // LUCENENET: Using TryGetValue to eliminate extra lookup
+            return refCounts.TryGetValue(fileName, out RefCount value) ? value.count > 0 : false;
         }
 
         private RefCount GetRefCount(string fileName)
         {
             Debug.Assert(IsLocked);
-            RefCount rc;
-            if (!refCounts.ContainsKey(fileName))
+            // LUCENENET: Using TryGetValue to eliminate extra lookup
+            if (!refCounts.TryGetValue(fileName, out RefCount rc))
             {
                 rc = new RefCount(fileName);
                 refCounts[fileName] = rc;
             }
-            else
-            {
-                rc = refCounts[fileName];
-            }
             return rc;
         }
 
@@ -708,7 +698,10 @@ namespace Lucene.Net.Index
                 // of unref'd files, and then you add new docs / do
                 // merging, and it reuses that segment name.
                 // TestCrash.testCrashAfterReopen can hit this:
-                if (!refCounts.ContainsKey(fileName) || refCounts[fileName].count == 0)
+
+                // LUCENENET: Using TryGetValue to eliminate extra lookup
+                bool got = refCounts.TryGetValue(fileName, out RefCount refCount);
+                if (!got || got && refCount.count == 0)
                 {
                     if (infoStream.IsEnabled("IFD"))
                     {
diff --git a/src/Lucene.Net/Index/IndexWriter.cs b/src/Lucene.Net/Index/IndexWriter.cs
index e4f8847..b422691 100644
--- a/src/Lucene.Net/Index/IndexWriter.cs
+++ b/src/Lucene.Net/Index/IndexWriter.cs
@@ -3338,12 +3338,8 @@ namespace Lucene.Net.Index
             // just want to update the DS name of this SegmentInfo.
             string dsName = Lucene3xSegmentInfoFormat.GetDocStoreSegment(info.Info);
             Debug.Assert(dsName != null);
-            string newDsName;
-            if (dsNames.ContainsKey(dsName))
-            {
-                newDsName = dsNames[dsName];
-            }
-            else
+            // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+            if (!dsNames.TryGetValue(dsName, out string newDsName))
             {
                 dsNames[dsName] = segName;
                 newDsName = segName;
diff --git a/src/Lucene.Net/Util/FieldCacheSanityChecker.cs b/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
index c0bd042..eac78a4 100644
--- a/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
+++ b/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
@@ -232,12 +232,13 @@ namespace Lucene.Net.Util
                 {
                     ReaderField kid = new ReaderField(kidKey, rf.FieldName);
 
-                    if (badChildren.ContainsKey(kid))
+                    // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+                    if (badChildren.TryGetValue(kid, out ISet<ReaderField> badKid))
                     {
                         // we've already process this kid as RF and found other problems
                         // track those problems as our own
                         badKids.Put(rf, kid);
-                        badKids.PutAll(rf, badChildren[kid]);
+                        badKids.PutAll(rf, badKid);
                         badChildren.Remove(kid);
                     }
                     else if (rfToValIdSets.ContainsKey(kid))
diff --git a/src/Lucene.Net/Util/MapOfSets.cs b/src/Lucene.Net/Util/MapOfSets.cs
index b8e83e4..5859e9c 100644
--- a/src/Lucene.Net/Util/MapOfSets.cs
+++ b/src/Lucene.Net/Util/MapOfSets.cs
@@ -50,15 +50,10 @@ namespace Lucene.Net.Util
         /// <returns> The size of the <see cref="ISet{T}"/> associated with key once val is added to it. </returns>
         public virtual int Put(TKey key, TValue val)
         {
-            ISet<TValue> theSet;
-            if (theMap.ContainsKey(key))
+            // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+            if (!theMap.TryGetValue(key, out ISet<TValue> theSet))
             {
-                theSet = theMap[key];
-            }
-            else
-            {
-                theSet = new HashSet<TValue>();
-                theMap[key] = theSet;
+                theMap[key] = theSet = new HashSet<TValue>();
             }
             theSet.Add(val);
             return theSet.Count;
@@ -71,15 +66,10 @@ namespace Lucene.Net.Util
         /// <returns> The size of the <see cref="ISet{T}"/> associated with key once val is added to it. </returns>
         public virtual int PutAll(TKey key, IEnumerable<TValue> vals)
         {
-            ISet<TValue> theSet;
-            if (theMap.ContainsKey(key))
-            {
-                theSet = theMap[key];
-            }
-            else
+            // LUCENENET: Eliminated extra lookup by using TryGetValue instead of ContainsKey
+            if (!theMap.TryGetValue(key, out ISet<TValue> theSet))
             {
-                theSet = new HashSet<TValue>();
-                theMap[key] = theSet;
+                theMap[key] = theSet = new HashSet<TValue>();
             }
             theSet.UnionWith(vals);
             return theSet.Count;


[lucenenet] 05/06: Lucene.Net.Index.BaseCompositeReader: Eliminated unnecessary O(n + n) operation and cast

Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit 6a7b255eb8f81c771bd7885bcf041f3c76b82b5c
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Tue Jan 7 21:49:21 2020 +0700

    Lucene.Net.Index.BaseCompositeReader: Eliminated unnecessary O(n + n) operation and cast
---
 src/Lucene.Net/Index/BaseCompositeReader.cs | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/Lucene.Net/Index/BaseCompositeReader.cs b/src/Lucene.Net/Index/BaseCompositeReader.cs
index 90da6c8..ff6ef78 100644
--- a/src/Lucene.Net/Index/BaseCompositeReader.cs
+++ b/src/Lucene.Net/Index/BaseCompositeReader.cs
@@ -1,6 +1,6 @@
+using J2N.Collections;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 
 namespace Lucene.Net.Index
 {
@@ -59,7 +59,7 @@ namespace Lucene.Net.Index
         /// List view solely for <see cref="GetSequentialSubReaders()"/>,
         /// for effectiveness the array is used internally.
         /// </summary>
-        private readonly IList<R> subReadersList;
+        private readonly IList<IndexReader> subReadersList; // LUCENENET: Changed from IList<R> to IList<IndexReader> to eliminate casting
 
         /// <summary>
         /// Constructs a <see cref="BaseCompositeReader{R}"/> on the given <paramref name="subReaders"/>. </summary>
@@ -71,7 +71,13 @@ namespace Lucene.Net.Index
         protected BaseCompositeReader(R[] subReaders)
         {
             this.subReaders = subReaders;
-            this.subReadersList = subReaders.ToList();// Collections.unmodifiableList(Arrays.asList(subReaders));
+
+            // LUCENENET: To eliminate casting, we create the list explicitly
+            var subReadersList = new List<IndexReader>(subReaders.Length);
+            for (int i = 0; i < subReaders.Length; i++)
+                subReadersList.Add(subReaders[i]);
+            this.subReadersList = subReadersList.ToUnmodifiableList();
+
             starts = new int[subReaders.Length + 1]; // build starts array
             int maxDoc = 0, numDocs = 0;
             for (int i = 0; i < subReaders.Length; i++)
@@ -222,7 +228,7 @@ namespace Lucene.Net.Index
 
         protected internal override sealed IList<IndexReader> GetSequentialSubReaders()
         {
-            return subReadersList.Cast<IndexReader>().ToList();
+            return subReadersList;
         }
     }
 }
\ No newline at end of file


[lucenenet] 04/06: Lucene.Net.Index.FilterDirectoryReader: Eliminated unnecessary O(n + n) operation

Posted by ni...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit c08eb10d0cc6efa6ccf7205dff0b1ed080f83a01
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Tue Jan 7 21:31:32 2020 +0700

    Lucene.Net.Index.FilterDirectoryReader: Eliminated unnecessary O(n + n) operation
---
 src/Lucene.Net/Index/FilterDirectoryReader.cs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/Lucene.Net/Index/FilterDirectoryReader.cs b/src/Lucene.Net/Index/FilterDirectoryReader.cs
index f53dd85..d0262cf 100644
--- a/src/Lucene.Net/Index/FilterDirectoryReader.cs
+++ b/src/Lucene.Net/Index/FilterDirectoryReader.cs
@@ -41,12 +41,12 @@ namespace Lucene.Net.Index
         /// </summary>
         public abstract class SubReaderWrapper
         {
-            internal virtual AtomicReader[] Wrap(IList<AtomicReader> readers)
+            internal virtual AtomicReader[] Wrap(IList<IndexReader> readers) // LUCENENET specific: Changed from IList<AtomicReader> to IList<IndexReader> to eliminate cast in calling method
             {
                 AtomicReader[] wrapped = new AtomicReader[readers.Count];
                 for (int i = 0; i < readers.Count; i++)
                 {
-                    wrapped[i] = Wrap(readers[i]);
+                    wrapped[i] = Wrap((AtomicReader)readers[i]);
                 }
                 return wrapped;
             }
@@ -100,7 +100,7 @@ namespace Lucene.Net.Index
         /// <param name="input"> the <see cref="DirectoryReader"/> to filter </param>
         /// <param name="wrapper"> the <see cref="SubReaderWrapper"/> to use to wrap subreaders </param>
         public FilterDirectoryReader(DirectoryReader input, SubReaderWrapper wrapper)
-            : base(input.Directory, wrapper.Wrap(input.GetSequentialSubReaders().OfType<AtomicReader>().ToList()))
+            : base(input.Directory, wrapper.Wrap(input.GetSequentialSubReaders()))
         {
             this.m_input = input;
         }