Skip to content

Commit

Permalink
Lucene.Net.Spatial.Util.ShapeFieldCacheProvider: Fixed atomicity issu…
Browse files Browse the repository at this point in the history
…e with loading the cache by using Lazy<T>. Fixes #319. Also see #417.
  • Loading branch information
NightOwl888 committed Mar 14, 2021
1 parent b69b025 commit c5c1dc0
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -39,8 +40,10 @@ public abstract class ShapeFieldCacheProvider<T>
{
//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;
Expand All @@ -56,8 +59,9 @@ protected ShapeFieldCacheProvider(string shapeField, int defaultSize) // LUCENEN

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() + "]");*/
Expand Down Expand Up @@ -88,7 +92,7 @@ public virtual ShapeFieldCache<T> GetCache(AtomicReader reader)
/*long elapsed = Runtime.CurrentTimeMillis() - startTime;
log.Fine("Cached: [" + count + " in " + elapsed + "ms] " + idx);*/
return idx;
});
})).Value;
}
}
}

0 comments on commit c5c1dc0

Please sign in to comment.