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 2020/01/30 08:15:49 UTC
[lucenenet] branch master updated (b50b42e -> b0b2b23)
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 b50b42e Updated README
new 01ddd63 Lucene.Net.Spatial.Util.ShapeFieldCacheProvider: Simplified cache value creation by using ConditionalWeakTable<TKey, TValue>.GetValue(), and removed dependency on WeakDictionary (See LUCENENET-610, LUCENENET-640).
new e73e44b Lucene.Net.TestFramework.Search.AssertingScorer: Reverted back to using WeakReference for the value, since values are strongly referenced in ConditionalWeakTable
new 6366760 Lucene.Net.Support.WeakDictionary: Removed unnecessary cast, marked class internal
new b4e6f0f Lucene.Net.Search.FieldCacheImpl: Switched to ConcurrentDictionary for the innerCache to try to reduce locking (LUCENENET-610)
new c867278 Lucene.Net.Facet.Taxonomy.CachedOrdinalsReader: Removed locking for ordsCache when using ConditionalWeakTable (See LUCENENET-610, LUCENENET-640, LUCENENET-630)
new bb873f4 Lucene.Net.Support: Renamed ConcurrentHashMapWrapper > ConcurrentDictionaryWrapper, marked internal, and added DictionaryExtensions.AsConcurrent() extension method to make usage simpler
new a3f18b4 Lucene.Net.Support: Added compatibility for nullable attributes, which are not supported prior to .NET Standard 2.1
new f1c1629 Fix duplicate FragNum value on Highlight.TextFragment
new b0b2b23 Merge remote-tracking branch 'segovia/master'
The 9 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:
.../Taxonomy/CachedOrdinalsReader.cs | 30 ++---
src/Lucene.Net.Facet/TopOrdAndFloatQueue.cs | 2 +-
src/Lucene.Net.Facet/TopOrdAndIntQueue.cs | 2 +-
.../Highlight/TextFragment.cs | 6 +-
.../Util/ShapeFieldCacheProvider.cs | 24 +---
.../Index/ThreadedIndexingAndSearchingTestCase.cs | 3 +-
.../Search/AssertingScorer.cs | 13 +-
src/Lucene.Net/Properties/AssemblyInfo.cs | 3 +-
src/Lucene.Net/Search/CachingWrapperFilter.cs | 3 +-
src/Lucene.Net/Search/FieldCacheImpl.cs | 112 +++++++++--------
.../Support/Compatibility/NullableAttributes.cs | 140 +++++++++++++++++++++
...apWrapper.cs => ConcurrentDictionaryWrapper.cs} | 36 +++---
src/Lucene.Net/Support/DictionaryExtensions.cs | 51 +++++---
src/Lucene.Net/Support/WeakDictionary.cs | 6 +-
14 files changed, 289 insertions(+), 142 deletions(-)
create mode 100644 src/Lucene.Net/Support/Compatibility/NullableAttributes.cs
rename src/Lucene.Net/Support/{ConcurrentHashMapWrapper.cs => ConcurrentDictionaryWrapper.cs} (83%)
[lucenenet] 08/09: Lucene.Net.Support: Added compatibility for
nullable attributes, which are not supported prior to .NET Standard 2.1
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 a3f18b4ac03a62dcda50f9555fbed57146a7f730
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Tue Jan 28 00:21:45 2020 +0700
Lucene.Net.Support: Added compatibility for nullable attributes, which are not supported prior to .NET Standard 2.1
---
.../Support/Compatibility/NullableAttributes.cs | 140 +++++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/src/Lucene.Net/Support/Compatibility/NullableAttributes.cs b/src/Lucene.Net/Support/Compatibility/NullableAttributes.cs
new file mode 100644
index 0000000..fbfb4b9
--- /dev/null
+++ b/src/Lucene.Net/Support/Compatibility/NullableAttributes.cs
@@ -0,0 +1,140 @@
+#pragma warning disable MA0048 // File name must match type name
+#define INTERNAL_NULLABLE_ATTRIBUTES
+#if NETSTANDARD1_6 || NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET6 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48
+
+// https://github.com/dotnet/corefx/blob/48363ac826ccf66fbe31a5dcb1dc2aab9a7dd768/src/Common/src/CoreLib/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
+
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ /// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class AllowNullAttribute : Attribute
+ { }
+
+ /// <summary>Specifies that null is disallowed as an input even if the corresponding type allows it.</summary>
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class DisallowNullAttribute : Attribute
+ { }
+
+ /// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class MaybeNullAttribute : Attribute
+ { }
+
+ /// <summary>Specifies that an output will not be null even if the corresponding type allows it.</summary>
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class NotNullAttribute : Attribute
+ { }
+
+ /// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding type disallows it.</summary>
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class MaybeNullWhenAttribute : Attribute
+ {
+ /// <summary>Initializes the attribute with the specified return value condition.</summary>
+ /// <param name="returnValue">
+ /// The return value condition. If the method returns this value, the associated parameter may be null.
+ /// </param>
+ public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ /// <summary>Gets the return value condition.</summary>
+ public bool ReturnValue { get; }
+ }
+
+ /// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the corresponding type allows it.</summary>
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class NotNullWhenAttribute : Attribute
+ {
+ /// <summary>Initializes the attribute with the specified return value condition.</summary>
+ /// <param name="returnValue">
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ /// </param>
+ public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ /// <summary>Gets the return value condition.</summary>
+ public bool ReturnValue { get; }
+ }
+
+ /// <summary>Specifies that the output will be non-null if the named parameter is non-null.</summary>
+ [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class NotNullIfNotNullAttribute : Attribute
+ {
+ /// <summary>Initializes the attribute with the associated parameter name.</summary>
+ /// <param name="parameterName">
+ /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
+ /// </param>
+ public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
+
+ /// <summary>Gets the associated parameter name.</summary>
+ public string ParameterName { get; }
+ }
+
+ /// <summary>Applied to a method that will never return under any circumstance.</summary>
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class DoesNotReturnAttribute : Attribute
+ { }
+
+ /// <summary>Specifies that the method will not return if the associated Boolean parameter is passed the specified value.</summary>
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class DoesNotReturnIfAttribute : Attribute
+ {
+ /// <summary>Initializes the attribute with the specified parameter value.</summary>
+ /// <param name="parameterValue">
+ /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
+ /// the associated parameter matches this value.
+ /// </param>
+ public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
+
+ /// <summary>Gets the condition parameter value.</summary>
+ public bool ParameterValue { get; }
+ }
+}
+#endif
\ No newline at end of file
[lucenenet] 06/09: Lucene.Net.Support: Renamed
ConcurrentHashMapWrapper > ConcurrentDictionaryWrapper, marked internal,
and added DictionaryExtensions.AsConcurrent() extension method to make usage
simpler
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 bb873f48ea6217ff573c9d632bd176f760a41286
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Mon Jan 27 05:44:13 2020 +0700
Lucene.Net.Support: Renamed ConcurrentHashMapWrapper > ConcurrentDictionaryWrapper, marked internal, and added DictionaryExtensions.AsConcurrent() extension method to make usage simpler
---
.../Index/ThreadedIndexingAndSearchingTestCase.cs | 3 +-
.../Search/AssertingScorer.cs | 2 +-
src/Lucene.Net/Search/CachingWrapperFilter.cs | 3 +-
...apWrapper.cs => ConcurrentDictionaryWrapper.cs} | 36 +++++++--------
src/Lucene.Net/Support/DictionaryExtensions.cs | 51 +++++++++++++++-------
5 files changed, 57 insertions(+), 38 deletions(-)
diff --git a/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs b/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
index 2dddef4..bade91d 100644
--- a/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
@@ -549,8 +549,7 @@ namespace Lucene.Net.Index
#if FEATURE_CONDITIONALWEAKTABLE_ADDORUPDATE
private readonly ConditionalWeakTable<SegmentCoreReaders, BooleanRef> warmed = new ConditionalWeakTable<SegmentCoreReaders, BooleanRef>();
#else
- private readonly IDictionary<SegmentCoreReaders, BooleanRef> warmed = new ConcurrentHashMapWrapper<SegmentCoreReaders, BooleanRef>(new WeakDictionary<SegmentCoreReaders, BooleanRef>());
- // Collections.synchronizedMap(new WeakHashMap<SegmentCoreReaders, BooleanRef>());
+ private readonly IDictionary<SegmentCoreReaders, BooleanRef> warmed = new WeakDictionary<SegmentCoreReaders, BooleanRef>().AsConcurrent();
#endif
public virtual void RunTest(string testName)
diff --git a/src/Lucene.Net.TestFramework/Search/AssertingScorer.cs b/src/Lucene.Net.TestFramework/Search/AssertingScorer.cs
index 023378e..df19e58 100644
--- a/src/Lucene.Net.TestFramework/Search/AssertingScorer.cs
+++ b/src/Lucene.Net.TestFramework/Search/AssertingScorer.cs
@@ -36,7 +36,7 @@ namespace Lucene.Net.Search
new ConditionalWeakTable<Scorer, WeakReference<AssertingScorer>>();
#else
private static readonly IDictionary<Scorer, WeakReference<AssertingScorer>> ASSERTING_INSTANCES =
- new ConcurrentHashMapWrapper<Scorer, WeakReference<AssertingScorer>>(new WeakDictionary<Scorer, WeakReference<AssertingScorer>>());
+ new WeakDictionary<Scorer, WeakReference<AssertingScorer>>().AsConcurrent();
#endif
public static Scorer Wrap(Random random, Scorer other)
diff --git a/src/Lucene.Net/Search/CachingWrapperFilter.cs b/src/Lucene.Net/Search/CachingWrapperFilter.cs
index af4175e..b933d55 100644
--- a/src/Lucene.Net/Search/CachingWrapperFilter.cs
+++ b/src/Lucene.Net/Search/CachingWrapperFilter.cs
@@ -41,8 +41,7 @@ namespace Lucene.Net.Search
#if FEATURE_CONDITIONALWEAKTABLE_ADDORUPDATE
private readonly ConditionalWeakTable<object, DocIdSet> _cache = new ConditionalWeakTable<object, DocIdSet>();
#else
- //private readonly IDictionary<object, DocIdSet> Cache = Collections.synchronizedMap(new WeakHashMap<object, DocIdSet>());
- private readonly IDictionary<object, DocIdSet> _cache = new ConcurrentHashMapWrapper<object, DocIdSet>(new WeakDictionary<object, DocIdSet>());
+ private readonly IDictionary<object, DocIdSet> _cache = new WeakDictionary<object, DocIdSet>().AsConcurrent();
#endif
/// <summary>
diff --git a/src/Lucene.Net/Support/ConcurrentHashMapWrapper.cs b/src/Lucene.Net/Support/ConcurrentDictionaryWrapper.cs
similarity index 83%
rename from src/Lucene.Net/Support/ConcurrentHashMapWrapper.cs
rename to src/Lucene.Net/Support/ConcurrentDictionaryWrapper.cs
index b257082..94e3a34 100644
--- a/src/Lucene.Net/Support/ConcurrentHashMapWrapper.cs
+++ b/src/Lucene.Net/Support/ConcurrentDictionaryWrapper.cs
@@ -7,28 +7,28 @@ using System.Threading;
namespace Lucene.Net.Support
{
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- public class ConcurrentHashMapWrapper<TKey, TValue> : IDictionary<TKey, TValue>
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ internal class ConcurrentDictionaryWrapper<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private readonly IDictionary<TKey, TValue> _dict;
- public ConcurrentHashMapWrapper(IDictionary<TKey, TValue> wrapped)
+ public ConcurrentDictionaryWrapper(IDictionary<TKey, TValue> wrapped)
{
this._dict = wrapped;
}
diff --git a/src/Lucene.Net/Support/DictionaryExtensions.cs b/src/Lucene.Net/Support/DictionaryExtensions.cs
index d9365c2..e3e60ac 100644
--- a/src/Lucene.Net/Support/DictionaryExtensions.cs
+++ b/src/Lucene.Net/Support/DictionaryExtensions.cs
@@ -5,21 +5,21 @@ using System.IO;
namespace Lucene.Net.Support
{
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
public static class DictionaryExtensions
{
@@ -42,6 +42,27 @@ namespace Lucene.Net.Support
}
/// <summary>
+ /// Returns a concurrent wrapper for the current <see cref="IDictionary{TKey, TValue}"/>.
+ /// </summary>
+ /// <typeparam name="TKey">The type of keys in the dictionary.</typeparam>
+ /// <typeparam name="TValue">The type of values in the dictionary.</typeparam>
+ /// <param name="dictionary">The collection to make concurrent (thread-safe).</param>
+ /// <returns>An object that acts as a read-only wrapper around the current <see cref="ISet{T}"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="dictionary"/> is <c>null</c>.</exception>
+ /// <remarks>
+ /// To synchronize any modifications to the <see cref="ISet{T}"/> object, expose it only through this wrapper.
+ /// <para/>
+ /// The set returned uses simple locking and may not be the most performant solution, but it provides a quick
+ /// way to make any set thread-safe.
+ /// <para/>
+ /// This method is an O(1) operation.
+ /// </remarks>
+ internal static IDictionary<TKey, TValue> AsConcurrent<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
+ {
+ return new ConcurrentDictionaryWrapper<TKey, TValue>(dictionary);
+ }
+
+ /// <summary>
/// Loads properties from the specified <see cref="Stream"/>. The encoding is
/// ISO8859-1.
/// </summary>
[lucenenet] 01/09: Lucene.Net.Spatial.Util.ShapeFieldCacheProvider:
Simplified cache value creation by using ConditionalWeakTable.GetValue(),
and removed dependency on WeakDictionary (See LUCENENET-610, LUCENENET-640).
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 01ddd63fb9350c14ddf3e94a198618bfc6754595
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sun Jan 26 19:41:42 2020 +0700
Lucene.Net.Spatial.Util.ShapeFieldCacheProvider: Simplified cache value creation by using ConditionalWeakTable<TKey, TValue>.GetValue(), and removed dependency on WeakDictionary (See LUCENENET-610, LUCENENET-640).
---
.../Util/ShapeFieldCacheProvider.cs | 24 +++++-----------------
1 file changed, 5 insertions(+), 19 deletions(-)
diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
index 55c076f..e36490f 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
@@ -1,6 +1,5 @@
using Lucene.Net.Index;
using Lucene.Net.Search;
-using Lucene.Net.Support;
using Lucene.Net.Util;
using Spatial4n.Core.Shapes;
using System.Runtime.CompilerServices;
@@ -40,13 +39,8 @@ namespace Lucene.Net.Spatial.Util
{
//private Logger log = Logger.GetLogger(GetType().FullName);
-#if FEATURE_CONDITIONALWEAKTABLE_ADDORUPDATE
private readonly ConditionalWeakTable<IndexReader, ShapeFieldCache<T>> sidx =
new ConditionalWeakTable<IndexReader, ShapeFieldCache<T>>();
-#else
- private readonly WeakDictionary<IndexReader, ShapeFieldCache<T>> sidx =
- new WeakDictionary<IndexReader, ShapeFieldCache<T>>();
-#endif
protected internal readonly int m_defaultSize;
protected internal readonly string m_shapeField;
@@ -60,23 +54,17 @@ namespace Lucene.Net.Spatial.Util
protected internal abstract T ReadShape(BytesRef term);
- private readonly object locker = new object();
-
public virtual ShapeFieldCache<T> GetCache(AtomicReader reader)
{
- lock (locker)
+ // LUCENENET: ConditionalWeakTable allows us to simplify and remove locks
+ return sidx.GetValue(reader, (key) =>
{
- ShapeFieldCache<T> idx;
- if (sidx.TryGetValue(reader, out idx) && idx != null)
- {
- return idx;
- }
/*long startTime = Runtime.CurrentTimeMillis();
log.Fine("Building Cache [" + reader.MaxDoc() + "]");*/
- idx = new ShapeFieldCache<T>(reader.MaxDoc, m_defaultSize);
+ ShapeFieldCache<T> idx = new ShapeFieldCache<T>(key.MaxDoc, m_defaultSize);
int count = 0;
DocsEnum docs = null;
- Terms terms = reader.GetTerms(m_shapeField);
+ Terms terms = ((AtomicReader)key).GetTerms(m_shapeField);
TermsEnum te = null;
if (terms != null)
{
@@ -99,12 +87,10 @@ namespace Lucene.Net.Spatial.Util
term = te.Next();
}
}
- sidx.AddOrUpdate(reader, idx);
-
/*long elapsed = Runtime.CurrentTimeMillis() - startTime;
log.Fine("Cached: [" + count + " in " + elapsed + "ms] " + idx);*/
return idx;
- }
+ });
}
}
}
[lucenenet] 04/09: Lucene.Net.Search.FieldCacheImpl: Switched to
ConcurrentDictionary for the innerCache to try to reduce locking
(LUCENENET-610)
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 b4e6f0fa994797f9e743ec23b191d43a06942b86
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Mon Jan 27 03:35:31 2020 +0700
Lucene.Net.Search.FieldCacheImpl: Switched to ConcurrentDictionary for the innerCache to try to reduce locking (LUCENENET-610)
---
src/Lucene.Net/Search/FieldCacheImpl.cs | 112 ++++++++++++++++++--------------
1 file changed, 63 insertions(+), 49 deletions(-)
diff --git a/src/Lucene.Net/Search/FieldCacheImpl.cs b/src/Lucene.Net/Search/FieldCacheImpl.cs
index eaa158e..87e6a95 100644
--- a/src/Lucene.Net/Search/FieldCacheImpl.cs
+++ b/src/Lucene.Net/Search/FieldCacheImpl.cs
@@ -2,11 +2,13 @@ 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.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
+using System.Threading;
namespace Lucene.Net.Search
{
@@ -114,9 +116,11 @@ namespace Lucene.Net.Search
{
Cache cache = cacheEntry.Value;
Type cacheType = cacheEntry.Key;
+#if !FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
lock (cache.readerCache)
{
- foreach (KeyValuePair<object, IDictionary<CacheKey, object>> readerCacheEntry in cache.readerCache)
+#endif
+ foreach (var readerCacheEntry in cache.readerCache)
{
object readerKey = readerCacheEntry.Key;
if (readerKey == null)
@@ -130,7 +134,9 @@ namespace Lucene.Net.Search
result.Add(new FieldCache.CacheEntry(readerKey, entry.field, cacheType, entry.custom, mapEntry.Value));
}
}
+#if !FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
}
+#endif
}
return result.ToArray();
}
@@ -208,9 +214,9 @@ namespace Lucene.Net.Search
internal readonly FieldCacheImpl wrapper;
#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
- internal ConditionalWeakTable<object, IDictionary<CacheKey, object>> readerCache = new ConditionalWeakTable<object, IDictionary<CacheKey, object>>();
+ internal ConditionalWeakTable<object, ConcurrentDictionary<CacheKey, object>> readerCache = new ConditionalWeakTable<object, ConcurrentDictionary<CacheKey, object>>();
#else
- internal WeakDictionary<object, IDictionary<CacheKey, object>> readerCache = new WeakDictionary<object, IDictionary<CacheKey, object>>();
+ internal WeakDictionary<object, ConcurrentDictionary<CacheKey, object>> readerCache = new WeakDictionary<object, ConcurrentDictionary<CacheKey, object>>();
#endif
protected abstract object CreateValue(AtomicReader reader, CacheKey key, bool setDocsWithField);
@@ -219,10 +225,10 @@ 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);
- }
}
/// <summary>
@@ -231,79 +237,87 @@ namespace Lucene.Net.Search
/// </summary>
public virtual void Put(AtomicReader reader, CacheKey key, object value)
{
+ ConcurrentDictionary<CacheKey, 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<CacheKey, object>
+ {
+ [key] = value
+ };
+ });
+#else
lock (readerCache)
{
- if (!readerCache.TryGetValue(readerKey, out IDictionary<CacheKey, object> innerCache) || innerCache == null)
+ if (!readerCache.TryGetValue(readerKey, out innerCache) || innerCache == null)
{
// First time this reader is using FieldCache
- innerCache = new Dictionary<CacheKey, object>();
- readerCache.AddOrUpdate(readerKey, innerCache);
+ innerCache = new ConcurrentDictionary<CacheKey, object>
+ {
+ [key] = value
+ };
+ readerCache.Add(readerKey, innerCache);
wrapper.InitReader(reader);
}
- // LUCENENET NOTE: We declare a temp variable here so we
- // don't overwrite value variable with the null
- // that will result when this if block succeeds; otherwise
- // we won't have a value to put in the cache.
- if (!innerCache.TryGetValue(key, out object temp))
- {
- innerCache[key] = value;
- }
- else
- {
- // Another thread beat us to it; leave the current
- // value
- }
}
+#endif
+ // If another thread beat us to it, leave the current value
+ innerCache.TryAdd(key, value);
}
public virtual object Get(AtomicReader reader, CacheKey key, bool setDocsWithField)
{
- IDictionary<CacheKey, object> innerCache;
- object value;
+ ConcurrentDictionary<CacheKey, 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<CacheKey, object>
+ {
+ [key] = new FieldCache.CreationPlaceholder()
+ };
+ });
+
+#else
lock (readerCache)
{
if (!readerCache.TryGetValue(readerKey, out innerCache) || innerCache == null)
{
// First time this reader is using FieldCache
- innerCache = new Dictionary<CacheKey, object>();
- readerCache.AddOrUpdate(readerKey, innerCache);
+ innerCache = new ConcurrentDictionary<CacheKey, object>
+ {
+ [key] = new FieldCache.CreationPlaceholder()
+ };
+ readerCache[readerKey] = innerCache;
wrapper.InitReader(reader);
- value = null;
- }
- else
- {
- innerCache.TryGetValue(key, out value);
- }
- if (value == null)
- {
- value = new FieldCache.CreationPlaceholder();
- innerCache[key] = value;
}
}
- if (value is FieldCache.CreationPlaceholder)
+#endif
+ object value = innerCache.GetOrAdd(key, (cacheKey) => new FieldCache.CreationPlaceholder());
+ if (value is FieldCache.CreationPlaceholder progress)
{
lock (value)
{
- FieldCache.CreationPlaceholder progress = (FieldCache.CreationPlaceholder)value;
if (progress.Value == null)
{
progress.Value = CreateValue(reader, key, setDocsWithField);
- lock (readerCache)
- {
- innerCache[key] = progress.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 != null && wrapper != null)
+ if (innerCache.TryUpdate(key, progress.Value, value))
{
- TextWriter infoStream = wrapper.InfoStream;
- if (infoStream != 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 != null && wrapper != null)
{
- PrintNewInsanity(infoStream, progress.Value);
+ TextWriter infoStream = wrapper.InfoStream;
+ if (infoStream != null)
+ {
+ PrintNewInsanity(infoStream, progress.Value);
+ }
}
}
}
[lucenenet] 02/09: Lucene.Net.TestFramework.Search.AssertingScorer:
Reverted back to using WeakReference for the value,
since values are strongly referenced in ConditionalWeakTable
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 e73e44b977a2863f1cdabe372c389d7f837bf525
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sun Jan 26 20:15:27 2020 +0700
Lucene.Net.TestFramework.Search.AssertingScorer: Reverted back to using WeakReference for the value, since values are strongly referenced in ConditionalWeakTable
---
src/Lucene.Net.TestFramework/Search/AssertingScorer.cs | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/src/Lucene.Net.TestFramework/Search/AssertingScorer.cs b/src/Lucene.Net.TestFramework/Search/AssertingScorer.cs
index e15df60..023378e 100644
--- a/src/Lucene.Net.TestFramework/Search/AssertingScorer.cs
+++ b/src/Lucene.Net.TestFramework/Search/AssertingScorer.cs
@@ -32,8 +32,8 @@ namespace Lucene.Net.Search
// could loose references because of eg.
// AssertingScorer.Score(Collector) which needs to delegate to work correctly
#if FEATURE_CONDITIONALWEAKTABLE_ADDORUPDATE
- private static readonly ConditionalWeakTable<Scorer, AssertingScorer> ASSERTING_INSTANCES =
- new ConditionalWeakTable<Scorer, AssertingScorer>();
+ private static readonly ConditionalWeakTable<Scorer, WeakReference<AssertingScorer>> ASSERTING_INSTANCES =
+ new ConditionalWeakTable<Scorer, WeakReference<AssertingScorer>>();
#else
private static readonly IDictionary<Scorer, WeakReference<AssertingScorer>> ASSERTING_INSTANCES =
new ConcurrentHashMapWrapper<Scorer, WeakReference<AssertingScorer>>(new WeakDictionary<Scorer, WeakReference<AssertingScorer>>());
@@ -47,7 +47,7 @@ namespace Lucene.Net.Search
}
AssertingScorer assertScorer = new AssertingScorer(random, other);
#if FEATURE_CONDITIONALWEAKTABLE_ADDORUPDATE
- ASSERTING_INSTANCES.AddOrUpdate(other, assertScorer);
+ ASSERTING_INSTANCES.AddOrUpdate(other, new WeakReference<AssertingScorer>(assertScorer));
#else
ASSERTING_INSTANCES[other] = new WeakReference<AssertingScorer>(assertScorer);
#endif
@@ -61,13 +61,8 @@ namespace Lucene.Net.Search
{
return other;
}
-
-#if FEATURE_CONDITIONALWEAKTABLE_ADDORUPDATE
- if (!ASSERTING_INSTANCES.TryGetValue(other, out AssertingScorer assertingScorer) || assertingScorer == null)
-#else
if (!ASSERTING_INSTANCES.TryGetValue(other, out WeakReference<AssertingScorer> assertingScorerRef) || assertingScorerRef == null ||
!assertingScorerRef.TryGetTarget(out AssertingScorer assertingScorer) || assertingScorer == null)
-#endif
{
// can happen in case of memory pressure or if
// scorer1.Score(collector) calls
[lucenenet] 09/09: Merge remote-tracking branch 'segovia/master'
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 b0b2b23bd3e163224c3af3bd0b332bab20bbb144
Merge: a3f18b4 f1c1629
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Thu Jan 30 10:23:28 2020 +0700
Merge remote-tracking branch 'segovia/master'
src/Lucene.Net.Highlighter/Highlight/TextFragment.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
[lucenenet] 05/09: Lucene.Net.Facet.Taxonomy.CachedOrdinalsReader:
Removed locking for ordsCache when using ConditionalWeakTable (See
LUCENENET-610, LUCENENET-640, LUCENENET-630)
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 c867278bc317fe808615a2fe17acc20b5e161a23
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Mon Jan 27 05:03:10 2020 +0700
Lucene.Net.Facet.Taxonomy.CachedOrdinalsReader: Removed locking for ordsCache when using ConditionalWeakTable (See LUCENENET-610, LUCENENET-640, LUCENENET-630)
---
.../Taxonomy/CachedOrdinalsReader.cs | 30 ++++++++--------------
1 file changed, 10 insertions(+), 20 deletions(-)
diff --git a/src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs b/src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs
index 92909f7..d67b7ff 100644
--- a/src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/CachedOrdinalsReader.cs
@@ -1,6 +1,7 @@
using Lucene.Net.Support;
using System;
using System.Diagnostics.CodeAnalysis;
+using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
@@ -78,26 +79,24 @@ namespace Lucene.Net.Facet.Taxonomy
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
lock (this)
{
- object cacheKey = context.Reader.CoreCacheKey;
if (!ordsCache.TryGetValue(cacheKey, out CachedOrds ords) || ords == null)
{
ords = new CachedOrds(source.GetReader(context), context.Reader.MaxDoc);
- ordsCache.AddOrUpdate(cacheKey, ords);
+ ordsCache[cacheKey] = ords;
}
return ords;
}
+#endif
}
- public override string IndexFieldName
- {
- get
- {
- return source.IndexFieldName;
- }
- }
+ public override string IndexFieldName => source.IndexFieldName;
public override OrdinalsSegmentReader GetReader(AtomicReaderContext context)
{
@@ -199,19 +198,10 @@ namespace Lucene.Net.Facet.Taxonomy
public virtual long RamBytesUsed()
{
+#if !FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
lock (this)
- {
- long bytes = 0;
-#if FEATURE_CONDITIONALWEAKTABLE_ENUMERATOR
- foreach (var pair in ordsCache)
- bytes += pair.Value.RamBytesUsed();
-#else
- foreach (CachedOrds ords in ordsCache.Values)
- bytes += ords.RamBytesUsed();
#endif
-
- return bytes;
- }
+ return ordsCache.Sum(pair => pair.Value.RamBytesUsed());
}
}
}
\ No newline at end of file
[lucenenet] 07/09: Fix duplicate FragNum value on
Highlight.TextFragment
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 f1c1629d627bcbe5546bc43a5c7623439bce391e
Author: Gustavo Segovia <gu...@ti8m.ch>
AuthorDate: Wed Jan 29 10:57:38 2020 +0100
Fix duplicate FragNum value on Highlight.TextFragment
---
src/Lucene.Net.Highlighter/Highlight/TextFragment.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/Lucene.Net.Highlighter/Highlight/TextFragment.cs b/src/Lucene.Net.Highlighter/Highlight/TextFragment.cs
index d4a97ad..3edd11e 100644
--- a/src/Lucene.Net.Highlighter/Highlight/TextFragment.cs
+++ b/src/Lucene.Net.Highlighter/Highlight/TextFragment.cs
@@ -50,7 +50,11 @@ namespace Lucene.Net.Search.Highlight
/// <summary>
/// the fragment sequence number
/// </summary>
- public virtual int FragNum { get; protected internal set; }
+ public virtual int FragNum
+ {
+ get { return fragNum; }
+ protected internal set { fragNum = value; }
+ }
/// <param name="frag2">Fragment to be merged into this one</param>
public virtual void Merge(TextFragment frag2)
[lucenenet] 03/09: Lucene.Net.Support.WeakDictionary: Removed
unnecessary cast, marked class internal
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 6366760dae8a0a46ee59fc044875f3ee0423a82f
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Mon Jan 27 03:15:23 2020 +0700
Lucene.Net.Support.WeakDictionary: Removed unnecessary cast, marked class internal
---
src/Lucene.Net.Facet/TopOrdAndFloatQueue.cs | 2 +-
src/Lucene.Net.Facet/TopOrdAndIntQueue.cs | 2 +-
src/Lucene.Net/Properties/AssemblyInfo.cs | 3 ++-
src/Lucene.Net/Support/WeakDictionary.cs | 6 ++----
4 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/src/Lucene.Net.Facet/TopOrdAndFloatQueue.cs b/src/Lucene.Net.Facet/TopOrdAndFloatQueue.cs
index 62fb389..72db2d8 100644
--- a/src/Lucene.Net.Facet/TopOrdAndFloatQueue.cs
+++ b/src/Lucene.Net.Facet/TopOrdAndFloatQueue.cs
@@ -55,7 +55,7 @@ namespace Lucene.Net.Facet
{
}
- protected override bool LessThan(OrdAndValue a, OrdAndValue b)
+ protected internal override bool LessThan(OrdAndValue a, OrdAndValue b)
{
if (a.Value < b.Value)
{
diff --git a/src/Lucene.Net.Facet/TopOrdAndIntQueue.cs b/src/Lucene.Net.Facet/TopOrdAndIntQueue.cs
index cb78b69..4f93a10 100644
--- a/src/Lucene.Net.Facet/TopOrdAndIntQueue.cs
+++ b/src/Lucene.Net.Facet/TopOrdAndIntQueue.cs
@@ -56,7 +56,7 @@ namespace Lucene.Net.Facet
{
}
- protected override bool LessThan(OrdAndValue a, OrdAndValue b)
+ protected internal override bool LessThan(OrdAndValue a, OrdAndValue b)
{
if (a.Value < b.Value)
{
diff --git a/src/Lucene.Net/Properties/AssemblyInfo.cs b/src/Lucene.Net/Properties/AssemblyInfo.cs
index f6c7729..f4ead0d 100644
--- a/src/Lucene.Net/Properties/AssemblyInfo.cs
+++ b/src/Lucene.Net/Properties/AssemblyInfo.cs
@@ -33,6 +33,8 @@ using System.Runtime.CompilerServices;
// We need InternalsVisibleTo in order to prevent making everything public just for the sake of testing.
// This has broad implications because many methods are marked "protected internal", which means other assemblies
// must update overridden methods to match.
+[assembly: InternalsVisibleTo("Lucene.Net.Facet, PublicKey=" + AssemblyKeys.PublicKey)]
+[assembly: InternalsVisibleTo("Lucene.Net.Misc, PublicKey=" + AssemblyKeys.PublicKey)]
[assembly: InternalsVisibleTo("Lucene.Net.Tests._A-D, PublicKey=" + AssemblyKeys.PublicKey)]
[assembly: InternalsVisibleTo("Lucene.Net.Tests._E-I, PublicKey=" + AssemblyKeys.PublicKey)]
[assembly: InternalsVisibleTo("Lucene.Net.Tests._J-S, PublicKey=" + AssemblyKeys.PublicKey)]
@@ -42,7 +44,6 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Lucene.Net.TestFramework.MSTest, PublicKey=" + AssemblyKeys.PublicKey)]
[assembly: InternalsVisibleTo("Lucene.Net.TestFramework.NUnit, PublicKey=" + AssemblyKeys.PublicKey)]
[assembly: InternalsVisibleTo("Lucene.Net.TestFramework.xUnit, PublicKey=" + AssemblyKeys.PublicKey)]
-[assembly: InternalsVisibleTo("Lucene.Net.Misc, PublicKey=" + AssemblyKeys.PublicKey)]
[assembly: InternalsVisibleTo("Lucene.Net.Tests.ICU, PublicKey=" + AssemblyKeys.PublicKey)] // For Analysis.Util.TestSegmentingTokenizerBase
[assembly: InternalsVisibleTo("Lucene.Net.Tests.Misc, PublicKey=" + AssemblyKeys.PublicKey)]
[assembly: InternalsVisibleTo("Lucene.Net.Tests.QueryParser, PublicKey=" + AssemblyKeys.PublicKey)]
diff --git a/src/Lucene.Net/Support/WeakDictionary.cs b/src/Lucene.Net/Support/WeakDictionary.cs
index 2aa467f..b4abc18 100644
--- a/src/Lucene.Net/Support/WeakDictionary.cs
+++ b/src/Lucene.Net/Support/WeakDictionary.cs
@@ -32,7 +32,7 @@ namespace Lucene.Net.Support
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
- public sealed class WeakDictionary<TKey, TValue> : IDictionary<TKey, TValue> where TKey : class
+ internal sealed class WeakDictionary<TKey, TValue> : IDictionary<TKey, TValue> where TKey : class
{
private IDictionary<WeakKey<TKey>, TValue> _hm;
private int _gcCollections = 0;
@@ -287,10 +287,8 @@ namespace Lucene.Net.Support
return true;
}
- if (obj is WeakKey<T>)
+ if (obj is WeakKey<T> other)
{
- var other = (WeakKey<T>)obj;
-
var referenceTarget = reference.Target; // Careful: can be null in the mean time...
return referenceTarget != null && referenceTarget.Equals(other.Target);
}