Skip to content

Commit

Permalink
Lucene.Net.Facet.Taxonomy.CachedOrdinalsReader: Fixed synchronization…
Browse files Browse the repository at this point in the history
… issues with adding new items to the cache and reading RamBytesUsed() method (see apache#417)
  • Loading branch information
NightOwl888 committed Mar 12, 2021
1 parent 9a6e49b commit 73534c5
Showing 1 changed file with 16 additions and 40 deletions.
56 changes: 16 additions & 40 deletions src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,10 @@ public class CachedOrdinalsReader : OrdinalsReader, IAccountable

#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
private readonly ConditionalWeakTable<object, CachedOrds> ordsCache = new ConditionalWeakTable<object, CachedOrds>();
private readonly object ordsCacheLock = new object();
#else
private readonly WeakDictionary<object, CachedOrds> ordsCache = new WeakDictionary<object, CachedOrds>();
private readonly ReaderWriterLockSlim syncLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
#endif
private readonly object syncLock = new object();

/// <summary>
/// Sole constructor. </summary>
Expand All @@ -81,35 +80,23 @@ public CachedOrdinalsReader(OrdinalsReader source)

private CachedOrds GetCachedOrds(AtomicReaderContext context)
{
object cacheKey = context.Reader.CoreCacheKey;
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
return ordsCache.GetValue(cacheKey, (cacheKey) => new CachedOrds(source.GetReader(context), context.Reader.MaxDoc));
#else
CachedOrds ords;
syncLock.EnterReadLock();
try
// LUCENENET NOTE: Since ConditionalWeakTable doesn't synchronize on enumeration in the RamBytesUsed() method,
// the lock is still required here despite it being a threadsafe collection.
lock (syncLock)
{
if (ordsCache.TryGetValue(cacheKey, out ords))
return ords;
}
finally
{
syncLock.ExitReadLock();
}
object cacheKey = context.Reader.CoreCacheKey;
if (!ordsCache.TryGetValue(cacheKey, out CachedOrds ords))
{
ords = new CachedOrds(source.GetReader(context), context.Reader.MaxDoc);

ords = new CachedOrds(source.GetReader(context), context.Reader.MaxDoc);
syncLock.EnterWriteLock();
try
{
ordsCache[cacheKey] = ords;
}
finally
{
syncLock.ExitWriteLock();
// LUCENENET specific: Since this is the only thread that can modify ordsCache
// and we just checked that the value doesn't exist above, we can simplify this to Add()
// which also means we don't need conditional compilation because ConditionalWeakTable
// doesn't support this[index].
ordsCache.Add(cacheKey, ords);
}
return ords;
}

return ords;
#endif
}

public override string IndexFieldName => source.IndexFieldName;
Expand Down Expand Up @@ -211,12 +198,7 @@ public long RamBytesUsed()

public virtual long RamBytesUsed()
{
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
lock (ordsCacheLock)
#else
syncLock.EnterReadLock();
try
#endif
lock (syncLock)
{
long bytes = 0;
foreach (var pair in ordsCache)
Expand All @@ -226,12 +208,6 @@ public virtual long RamBytesUsed()

return bytes;
}
#if !FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
finally
{
syncLock.ExitReadLock();
}
#endif
}
}
}

0 comments on commit 73534c5

Please sign in to comment.