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/15 21:09:43 UTC
[lucenenet] 02/02: Lucene.Net.Search.FieldCacheImpl: Reverted
ConcurrentDictionary to Dictionary,
since we are using explicit locks to synchronize the dictionary contents.
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 4e74a91bb0f07e2b1b2a6d2e6cbae1411e3fa974
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Wed Mar 10 01:29:18 2021 +0700
Lucene.Net.Search.FieldCacheImpl: Reverted ConcurrentDictionary to Dictionary, since we are using explicit locks to synchronize the dictionary contents.
---
src/Lucene.Net/Search/FieldCacheImpl.cs | 42 ++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/src/Lucene.Net/Search/FieldCacheImpl.cs b/src/Lucene.Net/Search/FieldCacheImpl.cs
index 8f8666d..681f097 100644
--- a/src/Lucene.Net/Search/FieldCacheImpl.cs
+++ b/src/Lucene.Net/Search/FieldCacheImpl.cs
@@ -4,7 +4,6 @@ using Lucene.Net.Index;
using Lucene.Net.Support;
using Lucene.Net.Support.IO;
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
@@ -235,9 +234,9 @@ namespace Lucene.Net.Search
internal readonly FieldCacheImpl wrapper;
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
- internal ConditionalWeakTable<object, ConcurrentDictionary<TKey, object>> readerCache = new ConditionalWeakTable<object, ConcurrentDictionary<TKey, object>>();
+ internal ConditionalWeakTable<object, IDictionary<TKey, object>> readerCache = new ConditionalWeakTable<object, IDictionary<TKey, object>>();
#else
- internal WeakDictionary<object, ConcurrentDictionary<TKey, object>> readerCache = new WeakDictionary<object, ConcurrentDictionary<TKey, object>>();
+ internal WeakDictionary<object, IDictionary<TKey, object>> readerCache = new WeakDictionary<object, IDictionary<TKey, object>>();
#endif
protected abstract TValue CreateValue(AtomicReader reader, TKey key, bool setDocsWithField);
@@ -256,7 +255,7 @@ namespace Lucene.Net.Search
/// </summary>
public virtual void Put(AtomicReader reader, TKey key, TValue value)
{
- ConcurrentDictionary<TKey, object> innerCache;
+ IDictionary<TKey, object> innerCache;
object readerKey = reader.CoreCacheKey;
lock (readerCache)
{
@@ -266,7 +265,7 @@ namespace Lucene.Net.Search
{
// First time this reader is using FieldCache
wrapper.InitReader(reader);
- return new ConcurrentDictionary<TKey, object>
+ return new Dictionary<TKey, object>
{
[key] = value
};
@@ -275,7 +274,7 @@ namespace Lucene.Net.Search
if (!readerCache.TryGetValue(readerKey, out innerCache) || innerCache is null)
{
// First time this reader is using FieldCache
- innerCache = new ConcurrentDictionary<TKey, object>
+ innerCache = new Dictionary<TKey, object>
{
[key] = value
};
@@ -283,15 +282,16 @@ namespace Lucene.Net.Search
wrapper.InitReader(reader);
}
#endif
+ if (innerCache.TryGetValue(key, out object temp) || temp is null)
+ innerCache[key] = value;
+ // else if another thread beat us to it, leave the current value
}
-
- // If another thread beat us to it, leave the current value
- innerCache.TryAdd(key, value);
}
public virtual TValue Get(AtomicReader reader, TKey key, bool setDocsWithField)
{
- ConcurrentDictionary<TKey, object> innerCache;
+ IDictionary<TKey, object> innerCache;
+ object value = null;
object readerKey = reader.CoreCacheKey;
lock (readerCache)
{
@@ -300,25 +300,33 @@ namespace Lucene.Net.Search
{
// First time this reader is using FieldCache
wrapper.InitReader(reader);
- return new ConcurrentDictionary<TKey, object>
+ return new Dictionary<TKey, object>
{
- [key] = new FieldCache.CreationPlaceholder<TValue>()
+ [key] = value = new FieldCache.CreationPlaceholder<TValue>()
};
});
#else
if (!readerCache.TryGetValue(readerKey, out innerCache) || innerCache is null)
{
// First time this reader is using FieldCache
- innerCache = new ConcurrentDictionary<TKey, object>
+ innerCache = new Dictionary<TKey, object>
{
- [key] = new FieldCache.CreationPlaceholder<TValue>()
+ [key] = value = new FieldCache.CreationPlaceholder<TValue>()
};
readerCache[readerKey] = innerCache;
wrapper.InitReader(reader);
}
#endif
+ // LUCENENET: The creation steps above will ensure the placehoder already exists by
+ // this point only in the case where the dictionary is being added.
+ // But we need to cover 1) the case where the cache already has a dictionary but no value and
+ // 2) the case where the cache already has a dictionary and a value so we diverge a little from Lucene here.
+ if (value is null)
+ {
+ if (!innerCache.TryGetValue(key, out value) || value is null)
+ innerCache[key] = value = new FieldCache.CreationPlaceholder<TValue>();
+ }
}
- object value = innerCache.GetOrAdd(key, (cacheKey) => new FieldCache.CreationPlaceholder<TValue>());
if (value is FieldCache.CreationPlaceholder<TValue> progress)
{
lock (value)
@@ -328,7 +336,7 @@ namespace Lucene.Net.Search
progress.Value = CreateValue(reader, key, setDocsWithField);
lock (readerCache)
{
- innerCache.TryUpdate(key, progress.Value, value);
+ innerCache[key] = progress.Value;
}
// Only check if key.custom (the parser) is
// non-null; else, we check twice for a single
@@ -336,7 +344,7 @@ namespace Lucene.Net.Search
if (!(key.Custom is null) && !(wrapper is null))
{
TextWriter infoStream = wrapper.InfoStream;
- if (infoStream != null)
+ if (!(infoStream is null))
{
PrintNewInsanity(infoStream, progress.Value);
}