BREAKING: Lucene.Net.Search.FieldCache: Added interface ICreationPlaceholder and changed CreationPlaceholder to CreationPlaceholder<TValue>. Changed FieldCacheImpl.Cache to use <TKey, TValue> to reduce casting.
diff --git a/src/Lucene.Net/Search/FieldCache.cs b/src/Lucene.Net/Search/FieldCache.cs
index 27931f7..fbd3737 100644
--- a/src/Lucene.Net/Search/FieldCache.cs
+++ b/src/Lucene.Net/Search/FieldCache.cs
@@ -579,11 +579,17 @@
}
/// <summary>
+ /// Interface used to identify a <see cref="CreationPlaceholder{TValue}"/> without
+ /// referencing its generic closing type.
+ /// </summary>
+ public interface ICreationPlaceholder { }
+
+ /// <summary>
/// Placeholder indicating creation of this cache is currently in-progress.
/// </summary>
- public sealed class CreationPlaceholder
+ public sealed class CreationPlaceholder<TValue> : ICreationPlaceholder
{
- internal object Value { get; set; }
+ internal TValue Value { get; set; }
}
/// <summary>
diff --git a/src/Lucene.Net/Search/FieldCacheImpl.cs b/src/Lucene.Net/Search/FieldCacheImpl.cs
index 08d933a..49b53e4 100644
--- a/src/Lucene.Net/Search/FieldCacheImpl.cs
+++ b/src/Lucene.Net/Search/FieldCacheImpl.cs
@@ -142,7 +142,7 @@
return result.ToArray();
}
- private void AddCacheEntries<TCacheKey>(IList<FieldCache.CacheEntry> result, Type cacheType, Cache<TCacheKey> cache) where TCacheKey : CacheKey
+ private void AddCacheEntries<TKey, TValue>(IList<FieldCache.CacheEntry> result, Type cacheType, Cache<TKey, TValue> cache) where TKey : CacheKey
{
#if !FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
lock (cache.readerCache)
@@ -155,10 +155,10 @@
{
continue;
}
- IDictionary<TCacheKey, object> innerCache = readerCacheEntry.Value;
- foreach (KeyValuePair<TCacheKey, object> mapEntry in innerCache)
+ IDictionary<TKey, object> innerCache = readerCacheEntry.Value;
+ foreach (KeyValuePair<TKey, object> mapEntry in innerCache)
{
- TCacheKey entry = mapEntry.Key;
+ TKey entry = mapEntry.Key;
result.Add(new FieldCache.CacheEntry(readerKey, entry.field, cacheType, entry.Custom, mapEntry.Value));
}
}
@@ -204,7 +204,9 @@
private void InitReader(AtomicReader reader)
{
+#pragma warning disable IDE0038 // Use pattern matching
if (reader is SegmentReader)
+#pragma warning restore IDE0038 // Use pattern matching
{
((SegmentReader)reader).AddCoreDisposedListener(purgeCore);
}
@@ -213,7 +215,9 @@
// we have a slow reader of some sort, try to register a purge event
// rather than relying on gc:
object key = reader.CoreCacheKey;
+#pragma warning disable IDE0038 // Use pattern matching
if (key is AtomicReader)
+#pragma warning restore IDE0038 // Use pattern matching
{
((AtomicReader)key).AddReaderClosedListener(purgeReader);
}
@@ -227,7 +231,7 @@
/// <summary>
/// Expert: Internal cache. </summary>
- internal abstract class Cache<TCacheKey> where TCacheKey : CacheKey
+ internal abstract class Cache<TKey, TValue> where TKey : CacheKey
{
internal Cache(FieldCacheImpl wrapper)
{
@@ -237,12 +241,12 @@
internal readonly FieldCacheImpl wrapper;
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
- internal ConditionalWeakTable<object, ConcurrentDictionary<TCacheKey, object>> readerCache = new ConditionalWeakTable<object, ConcurrentDictionary<TCacheKey, object>>();
+ internal ConditionalWeakTable<object, ConcurrentDictionary<TKey, object>> readerCache = new ConditionalWeakTable<object, ConcurrentDictionary<TKey, object>>();
#else
- internal WeakDictionary<object, ConcurrentDictionary<TCacheKey, object>> readerCache = new WeakDictionary<object, ConcurrentDictionary<TCacheKey, object>>();
+ internal WeakDictionary<object, ConcurrentDictionary<TKey, object>> readerCache = new WeakDictionary<object, ConcurrentDictionary<TKey, object>>();
#endif
- protected abstract object CreateValue(AtomicReader reader, TCacheKey key, bool setDocsWithField);
+ protected abstract TValue CreateValue(AtomicReader reader, TKey key, bool setDocsWithField);
/// <summary>
/// Remove this reader from the cache, if present. </summary>
@@ -258,16 +262,16 @@
/// Sets the key to the value for the provided reader;
/// if the key is already set then this doesn't change it.
/// </summary>
- public virtual void Put(AtomicReader reader, TCacheKey key, object value)
+ public virtual void Put(AtomicReader reader, TKey key, TValue value)
{
- ConcurrentDictionary<TCacheKey, object> innerCache;
+ ConcurrentDictionary<TKey, object> innerCache;
object readerKey = reader.CoreCacheKey;
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
innerCache = readerCache.GetValue(readerKey, (readerKey) =>
{
// First time this reader is using FieldCache
wrapper.InitReader(reader);
- return new ConcurrentDictionary<TCacheKey, object>
+ return new ConcurrentDictionary<TKey, object>
{
[key] = value
};
@@ -278,7 +282,7 @@
if (!readerCache.TryGetValue(readerKey, out innerCache) || innerCache == null)
{
// First time this reader is using FieldCache
- innerCache = new ConcurrentDictionary<TCacheKey, object>
+ innerCache = new ConcurrentDictionary<TKey, object>
{
[key] = value
};
@@ -291,18 +295,18 @@
innerCache.TryAdd(key, value);
}
- public virtual object Get(AtomicReader reader, TCacheKey key, bool setDocsWithField)
+ public virtual TValue Get(AtomicReader reader, TKey key, bool setDocsWithField)
{
- ConcurrentDictionary<TCacheKey, object> innerCache;
+ ConcurrentDictionary<TKey, object> innerCache;
object readerKey = reader.CoreCacheKey;
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
innerCache = readerCache.GetValue(readerKey, (readerKey) =>
{
// First time this reader is using FieldCache
wrapper.InitReader(reader);
- return new ConcurrentDictionary<TCacheKey, object>
+ return new ConcurrentDictionary<TKey, object>
{
- [key] = new FieldCache.CreationPlaceholder()
+ [key] = new FieldCache.CreationPlaceholder<TValue>()
};
});
@@ -312,21 +316,24 @@
if (!readerCache.TryGetValue(readerKey, out innerCache) || innerCache == null)
{
// First time this reader is using FieldCache
- innerCache = new ConcurrentDictionary<TCacheKey, object>
+ innerCache = new ConcurrentDictionary<TKey, object>
{
- [key] = new FieldCache.CreationPlaceholder()
+ [key] = new FieldCache.CreationPlaceholder<TValue>()
};
readerCache[readerKey] = innerCache;
wrapper.InitReader(reader);
}
}
#endif
- object value = innerCache.GetOrAdd(key, (cacheKey) => new FieldCache.CreationPlaceholder());
- if (value is FieldCache.CreationPlaceholder progress)
+ object value = innerCache.GetOrAdd(key, (cacheKey) => new FieldCache.CreationPlaceholder<TValue>());
+#pragma warning disable IDE0038 // Use pattern matching
+ if (value is FieldCache.CreationPlaceholder<TValue>)
+#pragma warning restore IDE0038 // Use pattern matching
{
lock (value)
{
- if (progress.Value == null)
+ var progress = (FieldCache.CreationPlaceholder<TValue>)value;
+ if (progress.Value is null)
{
progress.Value = CreateValue(reader, key, setDocsWithField);
if (innerCache.TryUpdate(key, progress.Value, value))
@@ -334,7 +341,7 @@
// Only check if key.custom (the parser) is
// non-null; else, we check twice for a single
// call to FieldCache.getXXX
- if (!(key.Custom is null) && wrapper != null)
+ if (!(key.Custom is null) && !(wrapper is null))
{
TextWriter infoStream = wrapper.InfoStream;
if (infoStream != null)
@@ -347,7 +354,7 @@
return progress.Value;
}
}
- return value;
+ return (TValue)value;
}
private void PrintNewInsanity(TextWriter infoStream, object value)
@@ -608,7 +615,7 @@
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
#pragma warning disable CS0612 // Type or member is obsolete
- return (FieldCache.Bytes)caches_typeof_sbyte.Get(reader, new CacheKey<FieldCache.IByteParser>(field, parser), setDocsWithField);
+ return caches_typeof_sbyte.Get(reader, new CacheKey<FieldCache.IByteParser>(field, parser), setDocsWithField);
#pragma warning restore CS0612 // Type or member is obsolete
}
}
@@ -629,7 +636,7 @@
}
#pragma warning disable CS0612 // Type or member is obsolete
- internal sealed class ByteCache : Cache<CacheKey<FieldCache.IByteParser>>
+ internal sealed class ByteCache : Cache<CacheKey<FieldCache.IByteParser>, FieldCache.Bytes>
#pragma warning restore CS0612 // Type or member is obsolete
{
internal ByteCache(FieldCacheImpl wrapper)
@@ -638,7 +645,7 @@
}
#pragma warning disable CS0612 // Type or member is obsolete
- protected override object CreateValue(AtomicReader reader, CacheKey<FieldCache.IByteParser> key, bool setDocsWithField)
+ protected override FieldCache.Bytes CreateValue(AtomicReader reader, CacheKey<FieldCache.IByteParser> key, bool setDocsWithField)
#pragma warning restore CS0612 // Type or member is obsolete
{
int maxDoc = reader.MaxDoc;
@@ -765,7 +772,7 @@
return FieldCache.Int16s.EMPTY;
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- return (FieldCache.Int16s)caches_typeof_short.Get(reader, new CacheKey<FieldCache.IInt16Parser>(field, parser), setDocsWithField);
+ return caches_typeof_short.Get(reader, new CacheKey<FieldCache.IInt16Parser>(field, parser), setDocsWithField);
}
}
@@ -791,7 +798,7 @@
/// NOTE: This was ShortCache in Lucene
/// </summary>
#pragma warning disable CS0612 // Type or member is obsolete
- internal sealed class Int16Cache : Cache<CacheKey<FieldCache.IInt16Parser>>
+ internal sealed class Int16Cache : Cache<CacheKey<FieldCache.IInt16Parser>, FieldCache.Int16s>
#pragma warning restore CS0612 // Type or member is obsolete
{
internal Int16Cache(FieldCacheImpl wrapper)
@@ -800,7 +807,7 @@
}
#pragma warning disable CS0612 // Type or member is obsolete
- protected override object CreateValue(AtomicReader reader, CacheKey<FieldCache.IInt16Parser> key, bool setDocsWithField)
+ protected override FieldCache.Int16s CreateValue(AtomicReader reader, CacheKey<FieldCache.IInt16Parser> key, bool setDocsWithField)
#pragma warning restore CS0612 // Type or member is obsolete
{
int maxDoc = reader.MaxDoc;
@@ -925,7 +932,7 @@
return FieldCache.Int32s.EMPTY;
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- return (FieldCache.Int32s)caches_typeof_int.Get(reader, new CacheKey<FieldCache.IInt32Parser>(field, parser), setDocsWithField);
+ return caches_typeof_int.Get(reader, new CacheKey<FieldCache.IInt32Parser>(field, parser), setDocsWithField);
}
}
@@ -981,14 +988,14 @@
/// <summary>
/// NOTE: This was IntCache in Lucene
/// </summary>
- internal sealed class Int32Cache : Cache<CacheKey<FieldCache.IInt32Parser>>
+ internal sealed class Int32Cache : Cache<CacheKey<FieldCache.IInt32Parser>, FieldCache.Int32s>
{
internal Int32Cache(FieldCacheImpl wrapper)
: base(wrapper)
{
}
- protected override object CreateValue(AtomicReader reader, CacheKey<FieldCache.IInt32Parser> key, bool setDocsWithField)
+ protected override FieldCache.Int32s CreateValue(AtomicReader reader, CacheKey<FieldCache.IInt32Parser> key, bool setDocsWithField)
{
FieldCache.IInt32Parser parser = key.custom;
if (parser == null)
@@ -1107,17 +1114,17 @@
return new Lucene.Net.Util.Bits.MatchNoBits(reader.MaxDoc);
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- return (IBits)caches_typeof_DocsWithFieldCache.Get(reader, new CacheKey(field), false);
+ return caches_typeof_DocsWithFieldCache.Get(reader, new CacheKey(field), false);
}
- internal sealed class DocsWithFieldCache : Cache<CacheKey>
+ internal sealed class DocsWithFieldCache : Cache<CacheKey, IBits>
{
internal DocsWithFieldCache(FieldCacheImpl wrapper)
: base(wrapper)
{
}
- protected override object CreateValue(AtomicReader reader, CacheKey key, bool setDocsWithField) // ignored
+ protected override IBits CreateValue(AtomicReader reader, CacheKey key, bool setDocsWithField) // ignored
{
string field = key.field;
int maxDoc = reader.MaxDoc;
@@ -1208,7 +1215,7 @@
return FieldCache.Singles.EMPTY;
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- return (FieldCache.Singles)caches_typeof_float.Get(reader, new CacheKey<FieldCache.ISingleParser>(field, parser), setDocsWithField);
+ return caches_typeof_float.Get(reader, new CacheKey<FieldCache.ISingleParser>(field, parser), setDocsWithField);
}
}
@@ -1233,14 +1240,14 @@
/// <summary>
/// NOTE: This was FloatCache in Lucene
/// </summary>
- internal sealed class SingleCache : Cache<CacheKey<FieldCache.ISingleParser>>
+ internal sealed class SingleCache : Cache<CacheKey<FieldCache.ISingleParser>, FieldCache.Singles>
{
internal SingleCache(FieldCacheImpl wrapper)
: base(wrapper)
{
}
- protected override object CreateValue(AtomicReader reader, CacheKey<FieldCache.ISingleParser> key, bool setDocsWithField)
+ protected override FieldCache.Singles CreateValue(AtomicReader reader, CacheKey<FieldCache.ISingleParser> key, bool setDocsWithField)
{
FieldCache.ISingleParser parser = key.custom;
if (parser == null)
@@ -1362,7 +1369,7 @@
return FieldCache.Int64s.EMPTY;
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- return (FieldCache.Int64s)caches_typeof_long.Get(reader, new CacheKey<FieldCache.IInt64Parser>(field, parser), setDocsWithField);
+ return caches_typeof_long.Get(reader, new CacheKey<FieldCache.IInt64Parser>(field, parser), setDocsWithField);
}
}
@@ -1389,14 +1396,14 @@
/// <summary>
/// NOTE: This was LongCache in Lucene
/// </summary>
- internal sealed class Int64Cache : Cache<CacheKey<FieldCache.IInt64Parser>>
+ internal sealed class Int64Cache : Cache<CacheKey<FieldCache.IInt64Parser>, FieldCache.Int64s>
{
internal Int64Cache(FieldCacheImpl wrapper)
: base(wrapper)
{
}
- protected override object CreateValue(AtomicReader reader, CacheKey<FieldCache.IInt64Parser> key, bool setDocsWithField)
+ protected override FieldCache.Int64s CreateValue(AtomicReader reader, CacheKey<FieldCache.IInt64Parser> key, bool setDocsWithField)
{
FieldCache.IInt64Parser parser = key.custom;
if (parser == null)
@@ -1528,7 +1535,7 @@
return FieldCache.Doubles.EMPTY;
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- return (FieldCache.Doubles)caches_typeof_double.Get(reader, new CacheKey<FieldCache.IDoubleParser>(field, parser), setDocsWithField);
+ return caches_typeof_double.Get(reader, new CacheKey<FieldCache.IDoubleParser>(field, parser), setDocsWithField);
}
}
@@ -1547,14 +1554,14 @@
}
}
- internal sealed class DoubleCache : Cache<CacheKey<FieldCache.IDoubleParser>>
+ internal sealed class DoubleCache : Cache<CacheKey<FieldCache.IDoubleParser>, FieldCache.Doubles>
{
internal DoubleCache(FieldCacheImpl wrapper)
: base(wrapper)
{
}
- protected override object CreateValue(AtomicReader reader, CacheKey<FieldCache.IDoubleParser> key, bool setDocsWithField)
+ protected override FieldCache.Doubles CreateValue(AtomicReader reader, CacheKey<FieldCache.IDoubleParser> key, bool setDocsWithField)
{
FieldCache.IDoubleParser parser = key.custom;
if (parser == null)
@@ -1706,18 +1713,18 @@
return DocValues.EMPTY_SORTED;
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- return (SortedDocValues)caches_typeof_SortedDocValues.Get(reader, new CacheKey<FieldCache.AcceptableOverheadRatio>(field, new FieldCache.AcceptableOverheadRatio(acceptableOverheadRatio)), false);
+ return caches_typeof_SortedDocValues.Get(reader, new CacheKey<FieldCache.AcceptableOverheadRatio>(field, new FieldCache.AcceptableOverheadRatio(acceptableOverheadRatio)), false);
}
}
- internal class SortedDocValuesCache : Cache<CacheKey<FieldCache.AcceptableOverheadRatio>>
+ internal class SortedDocValuesCache : Cache<CacheKey<FieldCache.AcceptableOverheadRatio>, SortedDocValues>
{
internal SortedDocValuesCache(FieldCacheImpl wrapper)
: base(wrapper)
{
}
- protected override object CreateValue(AtomicReader reader, CacheKey<FieldCache.AcceptableOverheadRatio> key, bool setDocsWithField) // ignored
+ protected override SortedDocValues CreateValue(AtomicReader reader, CacheKey<FieldCache.AcceptableOverheadRatio> key, bool setDocsWithField) // ignored
{
int maxDoc = reader.MaxDoc;
@@ -1873,17 +1880,17 @@
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- return (BinaryDocValues)caches_typeof_BinaryDocValues.Get(reader, new CacheKey<FieldCache.AcceptableOverheadRatio>(field, new FieldCache.AcceptableOverheadRatio(acceptableOverheadRatio)), setDocsWithField);
+ return caches_typeof_BinaryDocValues.Get(reader, new CacheKey<FieldCache.AcceptableOverheadRatio>(field, new FieldCache.AcceptableOverheadRatio(acceptableOverheadRatio)), setDocsWithField);
}
- internal sealed class BinaryDocValuesCache : Cache<CacheKey<FieldCache.AcceptableOverheadRatio>>
+ internal sealed class BinaryDocValuesCache : Cache<CacheKey<FieldCache.AcceptableOverheadRatio>, BinaryDocValues>
{
internal BinaryDocValuesCache(FieldCacheImpl wrapper)
: base(wrapper)
{
}
- protected override object CreateValue(AtomicReader reader, CacheKey<FieldCache.AcceptableOverheadRatio> key, bool setDocsWithField)
+ protected override BinaryDocValues CreateValue(AtomicReader reader, CacheKey<FieldCache.AcceptableOverheadRatio> key, bool setDocsWithField)
{
// TODO: would be nice to first check if DocTermsIndex
// was already cached for this field and then return
@@ -2026,18 +2033,18 @@
}
// LUCENENET specific - eliminated unnecessary Dictionary lookup by declaring each cache as a member variable
- DocTermOrds dto = (DocTermOrds)caches_typeof_DocTermOrds.Get(reader, new CacheKey(field), false);
+ DocTermOrds dto = caches_typeof_DocTermOrds.Get(reader, new CacheKey(field), false);
return dto.GetIterator(reader);
}
- internal sealed class DocTermOrdsCache : Cache<CacheKey>
+ internal sealed class DocTermOrdsCache : Cache<CacheKey, DocTermOrds>
{
internal DocTermOrdsCache(FieldCacheImpl wrapper)
: base(wrapper)
{
}
- protected override object CreateValue(AtomicReader reader, CacheKey key, bool setDocsWithField) // ignored
+ protected override DocTermOrds CreateValue(AtomicReader reader, CacheKey key, bool setDocsWithField) // ignored
{
return new DocTermOrds(reader, null, key.field);
}
diff --git a/src/Lucene.Net/Util/FieldCacheSanityChecker.cs b/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
index 8eee017..8295b6b 100644
--- a/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
+++ b/src/Lucene.Net/Util/FieldCacheSanityChecker.cs
@@ -140,7 +140,7 @@
continue;
}
- if (val is FieldCache.CreationPlaceholder)
+ if (val is FieldCache.ICreationPlaceholder)
{
continue;
}