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 2018/06/14 23:59:50 UTC
[1/2] lucenenet git commit: BUG: Fixed list comparison to include a
check for count (without it an empty list on one side returns true)
Repository: lucenenet
Updated Branches:
refs/heads/master a3a12967b -> 199fab066
BUG: Fixed list comparison to include a check for count (without it an empty list on one side returns true)
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/a66190d8
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/a66190d8
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/a66190d8
Branch: refs/heads/master
Commit: a66190d8a3b9694b6f0dab3946bebcd920c415c5
Parents: a3a1296
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Sun Nov 26 03:04:32 2017 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Sun Nov 26 03:11:18 2017 +0700
----------------------------------------------------------------------
src/Lucene.Net/Support/Collections.cs | 4 ++++
1 file changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/a66190d8/src/Lucene.Net/Support/Collections.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/Collections.cs b/src/Lucene.Net/Support/Collections.cs
index 3ded8e3..76adb23 100644
--- a/src/Lucene.Net/Support/Collections.cs
+++ b/src/Lucene.Net/Support/Collections.cs
@@ -279,6 +279,10 @@ namespace Lucene.Net.Support
return false;
}
+ if (listA.Count != listB.Count)
+ {
+ return false;
+ }
using (IEnumerator<T> eA = listA.GetEnumerator())
{
[2/2] lucenenet git commit: BUG: LUCENENET-602. Added
Lucene.Net.Support.EqualityComparer implementation to fix incomplete
support for value types with generics on MONO AOT platforms. Added missing
constructor overload to Lucene.Net.Facet.Taxonomy.LRU
Posted by ni...@apache.org.
BUG: LUCENENET-602. Added Lucene.Net.Support.EqualityComparer<T> implementation to fix incomplete support for value types with generics on MONO AOT platforms. Added missing constructor overload to Lucene.Net.Facet.Taxonomy.LRUHashMap so the issue can be worked around using a custom IEqualityComparer<T> implementation if desired. Fixed inconsistencies with optimized C5 EqualityComparer, which was not being used in all of the C5-derived classes.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/199fab06
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/199fab06
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/199fab06
Branch: refs/heads/master
Commit: 199fab0660b9a20508e6f1b86882441f0ec654e8
Parents: a66190d
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Fri Jun 15 06:43:37 2018 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Fri Jun 15 06:43:37 2018 +0700
----------------------------------------------------------------------
.../Analysis/Util/CharArrayMap.cs | 2 +-
.../Directory/DirectoryTaxonomyReader.cs | 8 +-
src/Lucene.Net.Facet/Taxonomy/LRUHashMap.cs | 32 ++++-
src/Lucene.Net.Tests/Support/C5/Events.cs | 2 +-
src/Lucene.Net.Tests/Support/C5/HashBag.cs | 2 +-
src/Lucene.Net.Tests/Support/TestLurchTable.cs | 18 +--
src/Lucene.Net.Tests/Support/TestTreeSet.cs | 14 +--
src/Lucene.Net/Search/LiveFieldValues.cs | 9 +-
src/Lucene.Net/Support/C5.Support.cs | 4 +-
.../Compatibility/ConcurrentDictionary.cs | 2 +-
src/Lucene.Net/Support/EqualityComparer.cs | 124 +++++++++++++++++++
src/Lucene.Net/Support/HashMap.cs | 7 +-
src/Lucene.Net/Support/LinkedHashMap.cs | 2 +-
src/Lucene.Net/Support/LurchTable.cs | 43 ++++---
src/Lucene.Net/Support/TreeDictionary.cs | 2 +-
src/Lucene.Net/Support/TreeSet.cs | 2 +-
src/Lucene.Net/Util/Fst/FST.cs | 8 +-
src/Lucene.Net/Util/PriorityQueue.cs | 2 +-
18 files changed, 225 insertions(+), 58 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
index cfe5625..c642bc8 100644
--- a/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
+++ b/src/Lucene.Net.Analysis.Common/Analysis/Util/CharArrayMap.cs
@@ -764,7 +764,7 @@ namespace Lucene.Net.Analysis.Util
if (!this.ContainsKey(iter.Current.Key))
return false;
- if (!EqualityComparer<TValue>.Default.Equals(this[iter.Current.Key], iter.Current.Value))
+ if (!Support.EqualityComparer<TValue>.Default.Equals(this[iter.Current.Key], iter.Current.Value))
return false;
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs b/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs
index 994b644..13a5feb 100644
--- a/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/Directory/DirectoryTaxonomyReader.cs
@@ -1,4 +1,5 @@
-using System;
+using Lucene.Net.Support;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -22,7 +23,6 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
* limitations under the License.
*/
- using Lucene.Net.Facet.Taxonomy;
using BytesRef = Lucene.Net.Util.BytesRef;
using Directory = Lucene.Net.Store.Directory;
using DirectoryReader = Lucene.Net.Index.DirectoryReader;
@@ -83,8 +83,8 @@ namespace Lucene.Net.Facet.Taxonomy.Directory
this.taxoEpoch = taxoWriter == null ? -1 : taxoWriter.TaxonomyEpoch;
// use the same instance of the cache, note the protective code in getOrdinal and getPath
- this.ordinalCache = ordinalCache == null ? new LRUHashMap<FacetLabel, Int32Class>(DEFAULT_CACHE_VALUE) : ordinalCache;
- this.categoryCache = categoryCache == null ? new LRUHashMap<int, FacetLabel>(DEFAULT_CACHE_VALUE) : categoryCache;
+ this.ordinalCache = ordinalCache ?? new LRUHashMap<FacetLabel, Int32Class>(DEFAULT_CACHE_VALUE);
+ this.categoryCache = categoryCache ?? new LRUHashMap<int, FacetLabel>(DEFAULT_CACHE_VALUE);
this.taxoArrays = taxoArrays != null ? new TaxonomyIndexArrays(indexReader, taxoArrays) : null;
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net.Facet/Taxonomy/LRUHashMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Facet/Taxonomy/LRUHashMap.cs b/src/Lucene.Net.Facet/Taxonomy/LRUHashMap.cs
index f38c8d2..bd449b9 100644
--- a/src/Lucene.Net.Facet/Taxonomy/LRUHashMap.cs
+++ b/src/Lucene.Net.Facet/Taxonomy/LRUHashMap.cs
@@ -50,7 +50,7 @@ namespace Lucene.Net.Facet.Taxonomy
/// The maximum size (in number of entries) to which the map can grow
/// before the least recently used entries start being removed.
/// <para/>
- /// Setting maxSize to a very large value, like <see cref="int.MaxValue"/>
+ /// Setting <paramref name="limit"/> to a very large value, like <see cref="int.MaxValue"/>
/// is allowed, but is less efficient than
/// using <see cref="Support.HashMap{TKey, TValue}"/> or
/// <see cref="Dictionary{TKey, TValue}"/> because our class needs
@@ -59,8 +59,36 @@ namespace Lucene.Net.Facet.Taxonomy
/// maximum size.
/// </param>
public LRUHashMap(int limit)
+ : this(limit, null)
{
- cache = new LurchTable<TKey, TValue>(LurchTableOrder.Access, limit);
+ }
+
+ /// <summary>
+ /// Create a new hash map with a bounded size and with least recently
+ /// used entries removed.
+ /// <para/>
+ /// LUCENENET specific overload to allow passing in custom <see cref="IEqualityComparer{T}"/>.
+ /// See LUCENENET-602.
+ /// </summary>
+ /// <param name="limit">
+ /// The maximum size (in number of entries) to which the map can grow
+ /// before the least recently used entries start being removed.
+ /// <para/>
+ /// Setting <paramref name="limit"/> to a very large value, like <see cref="int.MaxValue"/>
+ /// is allowed, but is less efficient than
+ /// using <see cref="Support.HashMap{TKey, TValue}"/> or
+ /// <see cref="Dictionary{TKey, TValue}"/> because our class needs
+ /// to keep track of the use order (via an additional doubly-linked
+ /// list) which is not used when the map's size is always below the
+ /// maximum size.
+ /// </param>
+ /// <param name="comparer">
+ /// The <see cref="IEqualityComparer{TKey}"/> implementation to use when comparing keys,
+ /// or <c>null</c> to use the default <see cref="IEqualityComparer{TKey}"/> for the type of the key.
+ /// </param>
+ public LRUHashMap(int limit, IEqualityComparer<TKey> comparer)
+ {
+ cache = new LurchTable<TKey, TValue>(LurchTableOrder.Access, limit, comparer);
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net.Tests/Support/C5/Events.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Support/C5/Events.cs b/src/Lucene.Net.Tests/Support/C5/Events.cs
index f0f5082..c3e982d 100644
--- a/src/Lucene.Net.Tests/Support/C5/Events.cs
+++ b/src/Lucene.Net.Tests/Support/C5/Events.cs
@@ -38,7 +38,7 @@ namespace Lucene.Net.Support.Templates.Events
{
this.collection = list;
listenTo = testSpec;
- seen = new CollectionEventList<TItem>(EqualityComparer<TItem>.Default, memoryType);
+ seen = new CollectionEventList<TItem>(C5.EqualityComparer<TItem>.Default, memoryType);
}
public SCG.IEnumerable<EventTypeEnum> SpecsBasic
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net.Tests/Support/C5/HashBag.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Support/C5/HashBag.cs b/src/Lucene.Net.Tests/Support/C5/HashBag.cs
index 288198a..9b46e63 100644
--- a/src/Lucene.Net.Tests/Support/C5/HashBag.cs
+++ b/src/Lucene.Net.Tests/Support/C5/HashBag.cs
@@ -50,7 +50,7 @@ namespace Lucene.Net.Support.C5
/// <summary>
/// Create a hash bag with the default item equalityComparer.
/// </summary>
- public HashBag(MemoryType memoryType = MemoryType.Normal) : this(EqualityComparer<T>.Default, memoryType) { }
+ public HashBag(MemoryType memoryType = MemoryType.Normal) : this(C5.EqualityComparer<T>.Default, memoryType) { }
/// <summary>
/// Create a hash bag with an external item equalityComparer.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net.Tests/Support/TestLurchTable.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Support/TestLurchTable.cs b/src/Lucene.Net.Tests/Support/TestLurchTable.cs
index 47c22a7..af38e5c 100644
--- a/src/Lucene.Net.Tests/Support/TestLurchTable.cs
+++ b/src/Lucene.Net.Tests/Support/TestLurchTable.cs
@@ -180,7 +180,7 @@ namespace Lucene.Net.Support
{
//multiple of prime will produce hash collision, thus testing removal of non-first elements
const int prime = 1103;
- var test = new LurchTable<int, string>(LurchTableOrder.Access, 3, prime, 10, 10, EqualityComparer<int>.Default);
+ var test = new LurchTable<int, string>(LurchTableOrder.Access, 3, prime, 10, 10, Support.EqualityComparer<int>.Default);
test[1 * prime] = "a";
test[2 * prime] = "b";
test[3 * prime] = "c";
@@ -207,7 +207,7 @@ namespace Lucene.Net.Support
public void TestCrudEvents()
{
var recorder = new RecordEvents<int, string>();
- var test = new LurchTable<int, string>(LurchTableOrder.Access, 3, 1103, 10, 10, EqualityComparer<int>.Default);
+ var test = new LurchTable<int, string>(LurchTableOrder.Access, 3, 1103, 10, 10, Support.EqualityComparer<int>.Default);
test.ItemAdded += recorder.ItemAdded;
test.ItemUpdated += recorder.ItemUpdated;
test.ItemRemoved += recorder.ItemRemoved;
@@ -247,7 +247,7 @@ namespace Lucene.Net.Support
{
//multiple of prime will produce hash collision, thus testing removal of non-first elements
const int prime = 1103;
- var test = new LurchTable<int, string>(LurchTableOrder.Access, 10, prime, 10, 10, EqualityComparer<int>.Default);
+ var test = new LurchTable<int, string>(LurchTableOrder.Access, 10, prime, 10, 10, Support.EqualityComparer<int>.Default);
test[1 * prime] = "a";
test[2 * prime] = "b";
test[3 * prime] = "c";
@@ -487,8 +487,8 @@ namespace Lucene.Net.Support
var keys = new List<int>();
foreach (var kv in sample)
keys.Add(kv.Key);
- VerifyCollection(EqualityComparer<int>.Default, keys.AsReadOnly(), items.Keys);
- VerifyCollection(EqualityComparer<int>.Default, keys.AsReadOnly(), dict.Keys);
+ VerifyCollection(Support.EqualityComparer<int>.Default, keys.AsReadOnly(), items.Keys);
+ VerifyCollection(Support.EqualityComparer<int>.Default, keys.AsReadOnly(), dict.Keys);
}
[Test, LuceneNetSpecific]
@@ -500,8 +500,8 @@ namespace Lucene.Net.Support
var values = new List<string>();
foreach (var kv in sample)
values.Add(kv.Value);
- VerifyCollection(EqualityComparer<string>.Default, values.AsReadOnly(), items.Values);
- VerifyCollection(EqualityComparer<string>.Default, values.AsReadOnly(), dict.Values);
+ VerifyCollection(Support.EqualityComparer<string>.Default, values.AsReadOnly(), items.Values);
+ VerifyCollection(Support.EqualityComparer<string>.Default, values.AsReadOnly(), dict.Values);
}
[Test]
@@ -518,8 +518,8 @@ namespace Lucene.Net.Support
class KeyValueEquality<TKey, TValue> : IEqualityComparer<KeyValuePair<TKey, TValue>>
{
- IEqualityComparer<TKey> KeyComparer = EqualityComparer<TKey>.Default;
- IEqualityComparer<TValue> ValueComparer = EqualityComparer<TValue>.Default;
+ IEqualityComparer<TKey> KeyComparer = Support.EqualityComparer<TKey>.Default;
+ IEqualityComparer<TValue> ValueComparer = Support.EqualityComparer<TValue>.Default;
public bool Equals(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
{
return KeyComparer.Equals(x.Key, y.Key) && ValueComparer.Equals(x.Value, y.Value);
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net.Tests/Support/TestTreeSet.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests/Support/TestTreeSet.cs b/src/Lucene.Net.Tests/Support/TestTreeSet.cs
index 448e27c..56f88cf 100644
--- a/src/Lucene.Net.Tests/Support/TestTreeSet.cs
+++ b/src/Lucene.Net.Tests/Support/TestTreeSet.cs
@@ -416,7 +416,7 @@ namespace Lucene.Net.Support.RBTreeSet
[Test, LuceneNetSpecific]
public void NullEqualityComparerinConstructor3()
{
- Assert.Throws<NullReferenceException>(() => new TreeSet<int>(null, EqualityComparer<int>.Default));
+ Assert.Throws<NullReferenceException>(() => new TreeSet<int>(null, Support.EqualityComparer<int>.Default));
}
[Test, LuceneNetSpecific]
@@ -2784,9 +2784,9 @@ namespace Lucene.Net.Support.RBTreeSet
[SetUp]
public void Init()
{
- dit = new TreeSet<int>(SCG.Comparer<int>.Default, EqualityComparer<int>.Default);
- dat = new TreeSet<int>(SCG.Comparer<int>.Default, EqualityComparer<int>.Default);
- dut = new TreeSet<int>(new RevIC(), EqualityComparer<int>.Default);
+ dit = new TreeSet<int>(SCG.Comparer<int>.Default, Support.EqualityComparer<int>.Default);
+ dat = new TreeSet<int>(SCG.Comparer<int>.Default, Support.EqualityComparer<int>.Default);
+ dut = new TreeSet<int>(new RevIC(), Support.EqualityComparer<int>.Default);
}
@@ -2880,9 +2880,9 @@ namespace Lucene.Net.Support.RBTreeSet
[SetUp]
public void Init()
{
- dit = new TreeSet<int>(SCG.Comparer<int>.Default, EqualityComparer<int>.Default);
- dat = new TreeSet<int>(SCG.Comparer<int>.Default, EqualityComparer<int>.Default);
- dut = new TreeSet<int>(new RevIC(), EqualityComparer<int>.Default);
+ dit = new TreeSet<int>(SCG.Comparer<int>.Default, Support.EqualityComparer<int>.Default);
+ dat = new TreeSet<int>(SCG.Comparer<int>.Default, Support.EqualityComparer<int>.Default);
+ dut = new TreeSet<int>(new RevIC(), Support.EqualityComparer<int>.Default);
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Search/LiveFieldValues.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Search/LiveFieldValues.cs b/src/Lucene.Net/Search/LiveFieldValues.cs
index 6f2ab6f..43603a3 100644
--- a/src/Lucene.Net/Search/LiveFieldValues.cs
+++ b/src/Lucene.Net/Search/LiveFieldValues.cs
@@ -114,26 +114,27 @@ namespace Lucene.Net.Search
// First try to get the "live" value:
T value;
current.TryGetValue(id, out value);
- if (EqualityComparer<T>.Default.Equals(value, missingValue))
+ var comparer = Support.EqualityComparer<T>.Default;
+ if (comparer.Equals(value, missingValue))
{
// Deleted but the deletion is not yet reflected in
// the reader:
return default(T);
}
- else if (!EqualityComparer<T>.Default.Equals(value, default(T)))
+ else if (!comparer.Equals(value, default(T)))
{
return value;
}
else
{
old.TryGetValue(id, out value);
- if (EqualityComparer<T>.Default.Equals(value, missingValue))
+ if (comparer.Equals(value, missingValue))
{
// Deleted but the deletion is not yet reflected in
// the reader:
return default(T);
}
- else if (!EqualityComparer<T>.Default.Equals(value, default(T)))
+ else if (!comparer.Equals(value, default(T)))
{
return value;
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Support/C5.Support.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/C5.Support.cs b/src/Lucene.Net/Support/C5.Support.cs
index fc80bbc..9789d88 100644
--- a/src/Lucene.Net/Support/C5.Support.cs
+++ b/src/Lucene.Net/Support/C5.Support.cs
@@ -3967,7 +3967,7 @@ namespace Lucene.Net.Support.C5
/// <item><description>If the actual generic argument T implements
/// <see cref="T:C5.ICollection`1"/> for some value W of its generic parameter T,
/// the equalityComparer will be <see cref="T:C5.UnsequencedCollectionEqualityComparer`2"/></description></item>
- /// <item><description>Otherwise the SCG.EqualityComparer<T>.Default is returned</description></item>
+ /// <item><description>Otherwise the Support.EqualityComparer<T>.Default is returned</description></item>
/// </list>
/// </summary>
/// <value>The comparer</value>
@@ -4005,7 +4005,7 @@ namespace Lucene.Net.Support.C5
return CreateAndCache(UnsequencedCollectionEqualityComparer.MakeGenericType(new[] { type, icollection.GetGenericArguments()[0] }));
}
- return _default = SCG.EqualityComparer<T>.Default;
+ return _default = Support.EqualityComparer<T>.Default;
}
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Support/Compatibility/ConcurrentDictionary.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/Compatibility/ConcurrentDictionary.cs b/src/Lucene.Net/Support/Compatibility/ConcurrentDictionary.cs
index 58f6dd8..22f1531 100644
--- a/src/Lucene.Net/Support/Compatibility/ConcurrentDictionary.cs
+++ b/src/Lucene.Net/Support/Compatibility/ConcurrentDictionary.cs
@@ -45,7 +45,7 @@ namespace System.Collections.Concurrent
{ }
public ConcurrentDictionary(int capacity)
- : this(capacity, EqualityComparer<TKey>.Default)
+ : this(capacity, Support.EqualityComparer<TKey>.Default)
{ }
public ConcurrentDictionary(int capacity, IEqualityComparer<TKey> comparer)
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Support/EqualityComparer.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/EqualityComparer.cs b/src/Lucene.Net/Support/EqualityComparer.cs
new file mode 100644
index 0000000..6ea40cb
--- /dev/null
+++ b/src/Lucene.Net/Support/EqualityComparer.cs
@@ -0,0 +1,124 @@
+using System.Collections.Generic;
+using System.Reflection;
+
+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.
+ */
+
+ /// <summary>
+ /// <see cref="IEqualityComparer{T}"/> to patch value type support for generics in MONO AOT.
+ /// Value types for generics in this environment at the time of this writing is
+ /// not supported, but is currently under development and eventually should be.
+ /// <para/>
+ /// This class can be used to patch the behavior when using MONO AOT, at the cost
+ /// of throwing an exception to reliably detect when generic types are not supported.
+ /// See <a href=""></a>
+ /// <para/>
+ /// See LUCENENET-602.
+ /// </summary>
+ /// <typeparam name="T">The type of objects to compare.</typeparam>
+ public sealed class EqualityComparer<T>
+ {
+ private static readonly bool IsValueType = typeof(T).GetTypeInfo().IsValueType;
+
+ /// <summary>
+ /// Returns a default equality comparer for the type specified by the generic argument.
+ /// <para/>
+ /// LUCENENET specific constant that is used for the comparer
+ /// rather than creating a custom <see cref="IEqualityComparer{T}"/> for value types.
+ /// See LUCENENET-602.
+ /// </summary>
+ public static System.Collections.Generic.EqualityComparer<T> Default { get; } = CreateComparer();
+
+ private static System.Collections.Generic.EqualityComparer<T> CreateComparer()
+ {
+ if (!EqualityComparerConstants.ValueTypesSupported.HasValue)
+ {
+ if (EqualityComparerConstants.ValueTypesSupported == true)
+ {
+ return System.Collections.Generic.EqualityComparer<T>.Default;
+ }
+ else
+ {
+ return IsValueType ?
+ new ValueTypeEqualityComparer() :
+ System.Collections.Generic.EqualityComparer<T>.Default;
+ }
+ }
+
+ // We test for an exception the first time this is called on this runtime instance,
+ // and store it in the ValueTypesSupported property (called once for any value type).
+ // This is not currently supported under MONO AOT compilation, but is under development,
+ // so eventually the catch path will be unreachable.
+ try
+ {
+ var result = System.Collections.Generic.EqualityComparer<T>.Default;
+ EqualityComparerConstants.ValueTypesSupported = true;
+ return result;
+ }
+ catch when (IsValueType)
+ {
+ EqualityComparerConstants.ValueTypesSupported = false;
+ return new ValueTypeEqualityComparer();
+ }
+ }
+
+ /// <summary>
+ /// Comparer for any .NET value type.
+ /// <para/>
+ /// In some platforms, such as Xamarin iOS, the implementation of <see cref="System.Collections.Generic.EqualityComparer{T}.Default"/> doesn't
+ /// work for value types. This class is used to provide equality comparers in cases where value types are required.
+ /// </summary>
+ internal class ValueTypeEqualityComparer : System.Collections.Generic.EqualityComparer<T> // where T : struct
+ {
+ /// <summary>
+ /// Determines whether two objects of type T are equal.
+ /// </summary>
+ /// <param name="x">The first value type to compare.</param>
+ /// <param name="y">The second value type to compare.</param>
+ /// <returns><c>true</c> if the specified objects are equal; otherwise, <c>false</c>.</returns>
+ public override bool Equals(T x, T y)
+ {
+ if (x != null)
+ {
+ if (y != null) return x.Equals(y);
+ return false;
+ }
+ if (y != null) return false;
+ return true;
+ }
+
+ /// <summary>
+ /// Serves as the default hash function.
+ /// <para/>
+ /// This is the same as calling obj.GetHashCode().
+ /// </summary>
+ /// <param name="obj">The object for which to get a hash code.</param>
+ /// <returns>A hash code for the specified object.</returns>
+ public override int GetHashCode(T obj)
+ {
+ return obj == null ? 0 : obj.GetHashCode();
+ }
+ }
+ }
+
+ internal class EqualityComparerConstants
+ {
+ public static bool? ValueTypesSupported { get; set; } = null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Support/HashMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/HashMap.cs b/src/Lucene.Net/Support/HashMap.cs
index 6a293c3..65ba883 100644
--- a/src/Lucene.Net/Support/HashMap.cs
+++ b/src/Lucene.Net/Support/HashMap.cs
@@ -95,7 +95,7 @@ namespace Lucene.Net.Support
}
public HashMap(int initialCapacity)
- : this(initialCapacity, EqualityComparer<TKey>.Default)
+ : this(initialCapacity, Support.EqualityComparer<TKey>.Default)
{
}
@@ -115,7 +115,8 @@ namespace Lucene.Net.Support
internal HashMap(IDictionary<TKey, TValue> wrappedDict, IEqualityComparer<TKey> comparer)
{
- _comparer = EqualityComparer<TKey>.Default;
+ // LUCENENET TODO: Is this a bug? Shouldn't we be using the passed in comparer if non-null?
+ _comparer = /* comparer ?? */ Support.EqualityComparer<TKey>.Default;
_dict = wrappedDict;
_hasNullValue = false;
@@ -260,7 +261,7 @@ namespace Lucene.Net.Support
{
if (!_isValueType && _comparer.Equals(item.Key, default(TKey)))
{
- return _hasNullValue && EqualityComparer<TValue>.Default.Equals(item.Value, _nullValue);
+ return _hasNullValue && Support.EqualityComparer<TValue>.Default.Equals(item.Value, _nullValue);
}
return _dict.Contains(item);
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Support/LinkedHashMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/LinkedHashMap.cs b/src/Lucene.Net/Support/LinkedHashMap.cs
index e3d9c94..dbc5d3b 100644
--- a/src/Lucene.Net/Support/LinkedHashMap.cs
+++ b/src/Lucene.Net/Support/LinkedHashMap.cs
@@ -199,7 +199,7 @@ namespace Lucene.Net.Support
private bool TryGetNode(TKey key, TValue value, out LinkedListNode<KeyValuePair<TKey, TValue>> node)
{
LinkedListNode<KeyValuePair<TKey, TValue>> n;
- if (dict.TryGetValue(key, out n) && EqualityComparer<TValue>.Default.Equals(value, n.Value.Value))
+ if (dict.TryGetValue(key, out n) && Support.EqualityComparer<TValue>.Default.Equals(value, n.Value.Value))
{
node = n;
return true;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Support/LurchTable.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/LurchTable.cs b/src/Lucene.Net/Support/LurchTable.cs
index 71379c8..47d251f 100644
--- a/src/Lucene.Net/Support/LurchTable.cs
+++ b/src/Lucene.Net/Support/LurchTable.cs
@@ -75,35 +75,48 @@ namespace Lucene.Net.Support
private int _used, _count;
private int _allocNext, _freeVersion;
- /// <summary>Creates a LurchTable that can store up to (capacity) items efficiently.</summary>
+
+
+ /// <summary>Creates a LurchTable that can store up to <paramref name="capacity"/> items efficiently.</summary>
+ /// <param name="capacity">The initial allowable number of items before allocation of more memory</param>
public LurchTable(int capacity)
- : this(LurchTableOrder.None, int.MaxValue, capacity >> 1, capacity >> 4, capacity >> 8, EqualityComparer<TKey>.Default) { }
+ : this(LurchTableOrder.None, int.MaxValue, capacity >> 1, capacity >> 4, capacity >> 8, null) { }
- /// <summary>Creates a LurchTable that can store up to (capacity) items efficiently.</summary>
+ /// <summary>Creates a LurchTable that can store up to <paramref name="capacity"/> items efficiently.</summary>
+ /// <param name="capacity">The initial allowable number of items before allocation of more memory</param>
+ /// <param name="ordering">The type of linking for the items</param>
public LurchTable(int capacity, LurchTableOrder ordering)
- : this(ordering, int.MaxValue, capacity >> 1, capacity >> 4, capacity >> 8, EqualityComparer<TKey>.Default) { }
+ : this(ordering, int.MaxValue, capacity >> 1, capacity >> 4, capacity >> 8, null) { }
- /// <summary>Creates a LurchTable that can store up to (capacity) items efficiently.</summary>
+ /// <summary>Creates a LurchTable that can store up to <paramref name="capacity"/> items efficiently.</summary>
+ /// <param name="capacity">The initial allowable number of items before allocation of more memory</param>
+ /// <param name="ordering">The type of linking for the items</param>
+ /// <param name="comparer">The element hash generator for keys, or <c>null</c> to use <see cref="Support.EqualityComparer{TKey}.Default"/></param>
public LurchTable(int capacity, LurchTableOrder ordering, IEqualityComparer<TKey> comparer)
: this(ordering, int.MaxValue, capacity >> 1, capacity >> 4, capacity >> 8, comparer) { }
- /// <summary>Creates a LurchTable that orders items by (ordering) and removes items once the specified (limit) is reached.</summary>
+ /// <summary>Creates a LurchTable that orders items by <paramref name="ordering"/> and removes items once the specified <paramref name="limit"/> is reached.</summary>
+ /// <param name="ordering">The type of linking for the items</param>
+ /// <param name="limit">The maximum allowable number of items, or int.MaxValue for unlimited</param>
public LurchTable(LurchTableOrder ordering, int limit)
- : this(ordering, limit, limit >> 1, limit >> 4, limit >> 8, EqualityComparer<TKey>.Default) { }
+ : this(ordering, limit, limit >> 1, limit >> 4, limit >> 8, null) { }
- /// <summary>Creates a LurchTable that orders items by (ordering) and removes items once the specified (limit) is reached.</summary>
+ /// <summary>Creates a LurchTable that orders items by <paramref name="ordering"/> and removes items once the specified <paramref name="limit"/> is reached.</summary>
+ /// <param name="ordering">The type of linking for the items</param>
+ /// <param name="limit">The maximum allowable number of items, or int.MaxValue for unlimited</param>
+ /// <param name="comparer">The element hash generator for keys, or <c>null</c> to use <see cref="Support.EqualityComparer{TKey}.Default"/></param>
public LurchTable(LurchTableOrder ordering, int limit, IEqualityComparer<TKey> comparer)
: this(ordering, limit, limit >> 1, limit >> 4, limit >> 8, comparer) { }
/// <summary>
- /// Creates a LurchTable that orders items by (ordering) and removes items once the specified (limit) is reached.
+ /// Creates a LurchTable that orders items by <paramref name="ordering"/> and removes items once the specified <paramref name="limit"/> is reached.
/// </summary>
/// <param name="ordering">The type of linking for the items</param>
/// <param name="limit">The maximum allowable number of items, or int.MaxValue for unlimited</param>
/// <param name="hashSize">The number of hash buckets to use for the collection, usually 1/2 estimated capacity</param>
/// <param name="allocSize">The number of entries to allocate at a time, usually 1/16 estimated capacity</param>
/// <param name="lockSize">The number of concurrency locks to preallocate, usually 1/256 estimated capacity</param>
- /// <param name="comparer">The element hash generator for keys</param>
+ /// <param name="comparer">The element hash generator for keys, or <c>null</c> to use <see cref="Support.EqualityComparer{TKey}.Default"/></param>
public LurchTable(LurchTableOrder ordering, int limit, int hashSize, int allocSize, int lockSize, IEqualityComparer<TKey> comparer)
{
if (limit <= 0)
@@ -112,7 +125,7 @@ namespace Lucene.Net.Support
throw new ArgumentOutOfRangeException("ordering");
_limit = limit <= 0 ? int.MaxValue : limit;
- _comparer = comparer;
+ _comparer = comparer ?? Support.EqualityComparer<TKey>.Default;
_ordering = ordering;
allocSize = (int)Math.Min((long)allocSize + OverAlloc, 0x3fffffff);
@@ -457,7 +470,7 @@ namespace Lucene.Net.Support
{
TValue test;
if (TryGetValue(item.Key, out test))
- return EqualityComparer<TValue>.Default.Equals(item.Value, test);
+ return Support.EqualityComparer<TValue>.Default.Equals(item.Value, test);
return false;
}
@@ -754,7 +767,7 @@ namespace Lucene.Net.Support
/// </summary>
public bool Contains(TValue value)
{
- var comparer = EqualityComparer<TValue>.Default;
+ var comparer = Support.EqualityComparer<TValue>.Default;
foreach (var item in _owner)
{
if (comparer.Equals(item.Value, value))
@@ -1413,7 +1426,7 @@ namespace Lucene.Net.Support
{
Value = value;
- if (_hasTestValue && !EqualityComparer<TValue>.Default.Equals(_testValue, value))
+ if (_hasTestValue && !Support.EqualityComparer<TValue>.Default.Equals(_testValue, value))
return false;
if (Condition != null && !Condition(key, value))
return false;
@@ -1508,7 +1521,7 @@ namespace Lucene.Net.Support
}
public bool UpdateValue(TKey key, ref TValue value)
{
- if (_hasTestValue && !EqualityComparer<TValue>.Default.Equals(_testValue, value))
+ if (_hasTestValue && !Support.EqualityComparer<TValue>.Default.Equals(_testValue, value))
return false;
value = Value;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Support/TreeDictionary.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/TreeDictionary.cs b/src/Lucene.Net/Support/TreeDictionary.cs
index f1b50f1..fe43a57 100644
--- a/src/Lucene.Net/Support/TreeDictionary.cs
+++ b/src/Lucene.Net/Support/TreeDictionary.cs
@@ -40,7 +40,7 @@ namespace Lucene.Net.Support
/// Create a red-black tree dictionary using the natural comparer for keys.
/// <exception cref="ArgumentException"/> if the key type K is not comparable.
/// </summary>
- public TreeDictionary(MemoryType memoryType = MemoryType.Normal) : this(SCG.Comparer<K>.Default, EqualityComparer<K>.Default, memoryType) { }
+ public TreeDictionary(MemoryType memoryType = MemoryType.Normal) : this(SCG.Comparer<K>.Default, C5.EqualityComparer<K>.Default, memoryType) { }
/// <summary>
/// Create a red-black tree dictionary using an external comparer for keys.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Support/TreeSet.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/TreeSet.cs b/src/Lucene.Net/Support/TreeSet.cs
index 559477f..f0d78c7 100644
--- a/src/Lucene.Net/Support/TreeSet.cs
+++ b/src/Lucene.Net/Support/TreeSet.cs
@@ -228,7 +228,7 @@ namespace Lucene.Net.Support
/// </summary>
/// <exception cref="NotComparableException">If <code>T</code> is not comparable.
/// </exception>
- public TreeSet(MemoryType memoryType = MemoryType.Normal) : this(SCG.Comparer<T>.Default, EqualityComparer<T>.Default, memoryType) { }
+ public TreeSet(MemoryType memoryType = MemoryType.Normal) : this(SCG.Comparer<T>.Default, C5.EqualityComparer<T>.Default, memoryType) { }
/// <summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Util/Fst/FST.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Util/Fst/FST.cs b/src/Lucene.Net/Util/Fst/FST.cs
index 8982395..c4053fd 100644
--- a/src/Lucene.Net/Util/Fst/FST.cs
+++ b/src/Lucene.Net/Util/Fst/FST.cs
@@ -362,7 +362,7 @@ namespace Lucene.Net.Util.Fst
{
throw new InvalidOperationException("already finished");
}
- if (newStartNode == FST.FINAL_END_NODE && !EqualityComparer<T>.Default.Equals(emptyOutput, default(T)))
+ if (newStartNode == FST.FINAL_END_NODE && !Support.EqualityComparer<T>.Default.Equals(emptyOutput, default(T)))
{
newStartNode = 0;
}
@@ -514,7 +514,7 @@ namespace Lucene.Net.Util.Fst
}
// TODO: really we should encode this as an arc, arriving
// to the root node, instead of special casing here:
- if (!EqualityComparer<T>.Default.Equals(emptyOutput, default(T)))
+ if (!Support.EqualityComparer<T>.Default.Equals(emptyOutput, default(T)))
{
// Accepts empty string
@out.WriteByte(1);
@@ -875,7 +875,7 @@ namespace Lucene.Net.Util.Fst
/// </summary>
public FST.Arc<T> GetFirstArc(FST.Arc<T> arc)
{
- if (!EqualityComparer<T>.Default.Equals(emptyOutput, default(T)))
+ if (!Support.EqualityComparer<T>.Default.Equals(emptyOutput, default(T)))
{
arc.Flags = FST.BIT_FINAL_ARC | FST.BIT_LAST_ARC;
arc.NextFinalOutput = emptyOutput;
@@ -2053,7 +2053,7 @@ namespace Lucene.Net.Util.Fst
fst.startNode = newNodeAddress.Get((int)startNode);
//System.out.println("new startNode=" + fst.startNode + " old startNode=" + startNode);
- if (!EqualityComparer<T>.Default.Equals(emptyOutput, default(T)))
+ if (!Support.EqualityComparer<T>.Default.Equals(emptyOutput, default(T)))
{
fst.EmptyOutput = emptyOutput;
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/199fab06/src/Lucene.Net/Util/PriorityQueue.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Util/PriorityQueue.cs b/src/Lucene.Net/Util/PriorityQueue.cs
index 36d5be5..391dd4f 100644
--- a/src/Lucene.Net/Util/PriorityQueue.cs
+++ b/src/Lucene.Net/Util/PriorityQueue.cs
@@ -88,7 +88,7 @@ namespace Lucene.Net.Util
{
// If sentinel objects are supported, populate the queue with them
T sentinel = GetSentinelObject();
- if (!EqualityComparer<T>.Default.Equals(sentinel, default(T)))
+ if (!Support.EqualityComparer<T>.Default.Equals(sentinel, default(T)))
{
heap[1] = sentinel;
for (int i = 2; i < heap.Length; i++)