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 2021/03/14 12:48:03 UTC

[lucenenet] 02/04: Lucene.Net.Spatial.Util.ShapeFieldCacheProvider: Fixed atomicity issue with loading the cache by using Lazy. Fixes #319. Also see #417.

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 <sh...@shadstorhaug.com>
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;
         }
     }
 }