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; } } }
