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 c5c1dc09661da4f2fd3c6caf59044c4b1db8071c
Author: Shad Storhaug <[email protected]>
AuthorDate: Fri Mar 12 17:30:48 2021 +0700

    Lucene.Net.Spatial.Util.ShapeFieldCacheProvider: Fixed atomicity issue with 
loading the cache by using Lazy<T>. Fixes #319. Also see #417.
---
 src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs 
b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
index 4bbb278..3c9f011 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
@@ -1,7 +1,8 @@
-using Lucene.Net.Index;
+using Lucene.Net.Index;
 using Lucene.Net.Search;
 using Lucene.Net.Util;
 using Spatial4n.Core.Shapes;
+using System;
 using System.Runtime.CompilerServices;
 
 namespace Lucene.Net.Spatial.Util
@@ -39,8 +40,10 @@ namespace Lucene.Net.Spatial.Util
     {
         //private Logger log = Logger.GetLogger(GetType().FullName);
 
-        private readonly ConditionalWeakTable<IndexReader, ShapeFieldCache<T>> 
sidx =
-            new ConditionalWeakTable<IndexReader, ShapeFieldCache<T>>();
+        // LUCENENET specific - use Lazy<T> to ensure only 1 thread can call 
the createValueCallback at a time,
+        // since the default behavior is not atomic. See 
https://github.com/apache/lucenenet/issues/417.
+        private readonly ConditionalWeakTable<IndexReader, 
Lazy<ShapeFieldCache<T>>> sidx =
+            new ConditionalWeakTable<IndexReader, Lazy<ShapeFieldCache<T>>>();
 
         protected internal readonly int m_defaultSize;
         protected internal readonly string m_shapeField;
@@ -56,8 +59,9 @@ namespace Lucene.Net.Spatial.Util
 
         public virtual ShapeFieldCache<T> GetCache(AtomicReader reader)
         {
-            // LUCENENET: ConditionalWeakTable allows us to simplify and 
remove locks
-            return sidx.GetValue(reader, (key) =>
+            // LUCENENET: ConditionalWeakTable allows us to simplify and 
remove locks on the
+            // read operation. For the create case, we use Lazy<T> to ensure 
atomicity.
+            return sidx.GetValue(reader, (key) => new 
Lazy<ShapeFieldCache<T>>(() =>
             {
                 /*long startTime = Runtime.CurrentTimeMillis();
                 log.Fine("Building Cache [" + reader.MaxDoc() + "]");*/
@@ -88,7 +92,7 @@ namespace Lucene.Net.Spatial.Util
                 /*long elapsed = Runtime.CurrentTimeMillis() - startTime;
                 log.Fine("Cached: [" + count + " in " + elapsed + "ms] " + 
idx);*/
                 return idx;
-            });
+            })).Value;
         }
     }
 }

Reply via email to