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:41 UTC

[lucenenet] branch master updated (2731bfd -> 4e74a91)

This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git.


    from 2731bfd  BUG: Lucene.Net.Benchmark.ByTask.Feeds.SpatialDocMaker: Since Dictionary this[key] is not marked virtual in .NET, subclassing Dictionary<string, string> is not a valid approach. So we implement IDictionary<string, string> instead.
     new 24d802c  Lucene.Net.Search.FieldCacheImpl: Restored readerCache locks to the state of Lucene 4.8.0 (closes #272)
     new 4e74a91  Lucene.Net.Search.FieldCacheImpl: Reverted ConcurrentDictionary to Dictionary, since we are using explicit locks to synchronize the dictionary contents.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/Lucene.Net/Search/FieldCacheImpl.cs | 104 +++++++++++++++++---------------
 1 file changed, 55 insertions(+), 49 deletions(-)


[lucenenet] 01/02: Lucene.Net.Search.FieldCacheImpl: Restored readerCache locks to the state of Lucene 4.8.0 (closes #272)

Posted by ni...@apache.org.
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 24d802cbdcec2bb2148b52680dfe9b872c487b76
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sun Mar 7 22:54:37 2021 +0700

    Lucene.Net.Search.FieldCacheImpl: Restored readerCache locks to the state of Lucene 4.8.0 (closes #272)
---
 src/Lucene.Net/Search/FieldCacheImpl.cs | 74 ++++++++++++++++-----------------
 1 file changed, 36 insertions(+), 38 deletions(-)

diff --git a/src/Lucene.Net/Search/FieldCacheImpl.cs b/src/Lucene.Net/Search/FieldCacheImpl.cs
index 64f2d97..8f8666d 100644
--- a/src/Lucene.Net/Search/FieldCacheImpl.cs
+++ b/src/Lucene.Net/Search/FieldCacheImpl.cs
@@ -1,4 +1,4 @@
-using J2N.Collections.Generic.Extensions;
+using J2N.Collections.Generic.Extensions;
 using Lucene.Net.Diagnostics;
 using Lucene.Net.Index;
 using Lucene.Net.Support;
@@ -144,9 +144,7 @@ namespace Lucene.Net.Search
 
         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)
-#endif
             {
                 foreach (var readerCacheEntry in cache.readerCache)
                 {
@@ -248,9 +246,7 @@ namespace Lucene.Net.Search
             /// Remove this reader from the cache, if present. </summary>
             public virtual void PurgeByCacheKey(object coreCacheKey)
             {
-#if !FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
                 lock (readerCache)
-#endif
                     readerCache.Remove(coreCacheKey);
             }
 
@@ -262,19 +258,20 @@ namespace Lucene.Net.Search
             {
                 ConcurrentDictionary<TKey, object> innerCache;
                 object readerKey = reader.CoreCacheKey;
-#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
-                innerCache = readerCache.GetValue(readerKey, (readerKey) =>
+                lock (readerCache)
                 {
-                    // First time this reader is using FieldCache
-                    wrapper.InitReader(reader);
-                    return new ConcurrentDictionary<TKey, object>
+#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
+
+                    innerCache = readerCache.GetValue(readerKey, (readerKey) =>
                     {
-                        [key] = value
-                    };
-                });
+                        // First time this reader is using FieldCache
+                        wrapper.InitReader(reader);
+                        return new ConcurrentDictionary<TKey, object>
+                        {
+                            [key] = value
+                        };
+                    });
 #else
-                lock (readerCache)
-                {
                     if (!readerCache.TryGetValue(readerKey, out innerCache) || innerCache is null)
                     {
                         // First time this reader is using FieldCache
@@ -285,8 +282,9 @@ namespace Lucene.Net.Search
                         readerCache.Add(readerKey, innerCache);
                         wrapper.InitReader(reader);
                     }
-                }
 #endif
+                }
+
                 // If another thread beat us to it, leave the current value
                 innerCache.TryAdd(key, value);
             }
@@ -295,20 +293,19 @@ namespace Lucene.Net.Search
             {
                 ConcurrentDictionary<TKey, object> innerCache;
                 object readerKey = reader.CoreCacheKey;
-#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
-                innerCache = readerCache.GetValue(readerKey, (readerKey) =>
+                lock (readerCache)
                 {
-                    // First time this reader is using FieldCache
-                    wrapper.InitReader(reader);
-                    return new ConcurrentDictionary<TKey, object>
+#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
+                    innerCache = readerCache.GetValue(readerKey, (readerKey) =>
                     {
-                        [key] = new FieldCache.CreationPlaceholder<TValue>()
-                    };
-                });
-
+                        // First time this reader is using FieldCache
+                        wrapper.InitReader(reader);
+                        return new ConcurrentDictionary<TKey, object>
+                        {
+                            [key] = new FieldCache.CreationPlaceholder<TValue>()
+                        };
+                    });
 #else
-                lock (readerCache)
-                {
                     if (!readerCache.TryGetValue(readerKey, out innerCache) || innerCache is null)
                     {
                         // First time this reader is using FieldCache
@@ -319,8 +316,8 @@ namespace Lucene.Net.Search
                         readerCache[readerKey] = innerCache;
                         wrapper.InitReader(reader);
                     }
-                }
 #endif
+                }
                 object value = innerCache.GetOrAdd(key, (cacheKey) => new FieldCache.CreationPlaceholder<TValue>());
                 if (value is FieldCache.CreationPlaceholder<TValue> progress)
                 {
@@ -329,18 +326,19 @@ namespace Lucene.Net.Search
                         if (progress.Value is null)
                         {
                             progress.Value = CreateValue(reader, key, setDocsWithField);
-                            if (innerCache.TryUpdate(key, progress.Value, value))
+                            lock (readerCache)
+                            {
+                                innerCache.TryUpdate(key, progress.Value, value);
+                            }
+                            // 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 is null))
                             {
-                                // 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 is null))
+                                TextWriter infoStream = wrapper.InfoStream;
+                                if (infoStream != null)
                                 {
-                                    TextWriter infoStream = wrapper.InfoStream;
-                                    if (infoStream != null)
-                                    {
-                                        PrintNewInsanity(infoStream, progress.Value);
-                                    }
+                                    PrintNewInsanity(infoStream, progress.Value);
                                 }
                             }
                         }


[lucenenet] 02/02: Lucene.Net.Search.FieldCacheImpl: Reverted ConcurrentDictionary to Dictionary, since we are using explicit locks to synchronize the dictionary contents.

Posted by ni...@apache.org.
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);
                                 }