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 fa7c385994d0f0f23a866735a87c95c9989c29d6
Author: Shad Storhaug <[email protected]>
AuthorDate: Fri Jul 17 15:08:23 2020 +0700

    Lucene.Net.Facet: Optimized DirectoryTaxonomyReader by eliminating locking, 
removing unnecessary casts, and using LazyInitializer for the taxonomy array 
initialization
---
 .../Taxonomy/Directory/DirectoryTaxonomyReader.cs  | 62 +++++++++-------------
 .../Taxonomy/WriterCache/TestCharBlockArray.cs     |  1 -
 2 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs 
b/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs
index 3e68f0a..7ad61ac 100644
--- a/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs
@@ -1,8 +1,8 @@
 using System;
 using System.Collections.Generic;
-using System.Globalization;
 using System.IO;
 using System.Text;
+using System.Threading;
 
 namespace Lucene.Net.Facet.Taxonomy.Directory
 {
@@ -55,7 +55,15 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
             /// <summary>
             /// NOTE: This was intItem (field) in Lucene
             /// </summary>
-            public int Value { get; set; }
+            public int Value { get; private set; }
+
+            public Int32Class(int value)
+            {
+                Value = value;
+            }
+
+            public static implicit operator int(Int32Class integer) => 
integer.Value;
+            public static implicit operator Int32Class(int integer) => new 
Int32Class(integer);
         }
         private const int DEFAULT_CACHE_VALUE = 4000;
 
@@ -67,7 +75,7 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
         private LRUHashMap<FacetLabel, Int32Class> ordinalCache;
         private LRUHashMap<int, FacetLabel> categoryCache;
 
-        private volatile TaxonomyIndexArrays taxoArrays;
+        private /*volatile*/ TaxonomyIndexArrays taxoArrays; // LUCENENET 
specific: LazyInitalizer negates the need for volatile
 
         /// <summary>
         /// Called only from <see cref="DoOpenIfChanged()"/>. If the taxonomy 
has been
@@ -128,20 +136,7 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
             categoryCache = new LRUHashMap<int, 
FacetLabel>(DEFAULT_CACHE_VALUE);
         }
 
-        private void InitTaxoArrays()
-        {
-            lock (this)
-            {
-                if (taxoArrays == null)
-                {
-                    // according to Java Concurrency in Practice, this might 
perform better on
-                    // some JVMs, because the array initialization doesn't 
happen on the
-                    // volatile member.
-                    TaxonomyIndexArrays tmpArrays = new 
TaxonomyIndexArrays(indexReader);
-                    taxoArrays = tmpArrays;
-                }
-            }
-        }
+        // LUCENENET specific - eliminated the InitTaxoArrays() method in 
favor of LazyInitializer
 
         protected internal override void DoClose()
         {
@@ -267,10 +262,11 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
             get
             {
                 EnsureOpen();
-                if (taxoArrays == null)
-                {
-                    InitTaxoArrays();
-                }
+
+                // LUCENENET specific - eliminated the InitTaxoArrays() method 
in favor of LazyInitializer
+                if (null == taxoArrays)
+                    return LazyInitializer.EnsureInitialized(ref taxoArrays, 
() => new TaxonomyIndexArrays(indexReader));
+
                 return taxoArrays;
             }
         }
@@ -296,15 +292,14 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
 
             // LUCENENET: Lock was removed here because the underlying cache 
is thread-safe,
             // and removing the lock seems to make the performance better.
-            Int32Class res = ordinalCache.Get(cp);
-            if (res != null)
+            if (ordinalCache.TryGetValue(cp, out Int32Class res) && res != 
null)
             {
-                if ((int)res.Value < indexReader.MaxDoc)
+                if (res < indexReader.MaxDoc)
                 {
                     // Since the cache is shared with DTR instances allocated 
from
                     // doOpenIfChanged, we need to ensure that the ordinal is 
one that
                     // this DTR instance recognizes.
-                    return (int)res.Value;
+                    return res;
                 }
                 else
                 {
@@ -332,7 +327,7 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
 
                 // LUCENENET: Lock was removed here because the underlying 
cache is thread-safe,
                 // and removing the lock seems to make the performance better.
-                ordinalCache.Put(cp, new Int32Class { Value = 
Convert.ToInt32(ret, CultureInfo.InvariantCulture) });
+                ordinalCache.Put(cp, ret);
             }
 
             return ret;
@@ -355,10 +350,9 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
             // wrapped as LRU?
 
             // LUCENENET NOTE: We don't need to convert ordinal from int to 
int here as was done in Java.
-            FacetLabel res;
             // LUCENENET: Lock was removed here because the underlying cache 
is thread-safe,
             // and removing the lock seems to make the performance better.
-            if (categoryCache.TryGetValue(ordinal, out res))
+            if (categoryCache.TryGetValue(ordinal, out FacetLabel res))
             {
                 return res;
             }
@@ -392,14 +386,10 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
         public virtual void SetCacheSize(int size)
         {
             EnsureOpen();
-            lock (categoryCache)
-            {
-                categoryCache.Limit = size;
-            }
-            lock (ordinalCache)
-            {
-                ordinalCache.Limit = size;
-            }
+            // LUCENENET specific - removed locking here because these 
collections
+            // internally use Interlocked.Exchange
+            categoryCache.Limit = size;
+            ordinalCache.Limit = size;
         }
 
         /// <summary>
diff --git 
a/src/Lucene.Net.Tests.Facet/Taxonomy/WriterCache/TestCharBlockArray.cs 
b/src/Lucene.Net.Tests.Facet/Taxonomy/WriterCache/TestCharBlockArray.cs
index 9ab5ae7..c487c5f 100644
--- a/src/Lucene.Net.Tests.Facet/Taxonomy/WriterCache/TestCharBlockArray.cs
+++ b/src/Lucene.Net.Tests.Facet/Taxonomy/WriterCache/TestCharBlockArray.cs
@@ -26,7 +26,6 @@ namespace Lucene.Net.Facet.Taxonomy.WriterCache
     public class TestCharBlockArray : FacetTestCase
     {
         [Test]
-        [Slow]
         public virtual void TestArray()
         {
             CharBlockArray array = new CharBlockArray();

Reply via email to