You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2016/10/02 10:17:16 UTC
[45/49] lucenenet git commit: Moved common code from
Core.Util.Fst.FST and TestFramework.Util.Fst.FSTTester into the support
namespace.
Moved common code from Core.Util.Fst.FST and TestFramework.Util.Fst.FSTTester into the support namespace.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/979f4e9d
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/979f4e9d
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/979f4e9d
Branch: refs/heads/master
Commit: 979f4e9d43e393ed1e312145f726666d9e333a56
Parents: b9ba938
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Sat Sep 17 21:38:37 2016 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Sat Sep 17 22:40:51 2016 +0700
----------------------------------------------------------------------
src/Lucene.Net.Core/Lucene.Net.csproj | 1 +
src/Lucene.Net.Core/Support/HashCodeMerge.cs | 37 ++++++++++
src/Lucene.Net.Core/Support/ObjectExtensions.cs | 56 +++++++++++++++
src/Lucene.Net.Core/Util/Fst/FST.cs | 18 ++---
src/Lucene.Net.Core/Util/Fst/NodeHash.cs | 71 +++++++-------------
.../Util/fst/FSTTester.cs | 18 +----
6 files changed, 125 insertions(+), 76 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/979f4e9d/src/Lucene.Net.Core/Lucene.Net.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Lucene.Net.csproj b/src/Lucene.Net.Core/Lucene.Net.csproj
index 9dbcd4c..4740604 100644
--- a/src/Lucene.Net.Core/Lucene.Net.csproj
+++ b/src/Lucene.Net.Core/Lucene.Net.csproj
@@ -638,6 +638,7 @@
<Compile Include="Support\ListExtensions.cs" />
<Compile Include="Support\MathExtension.cs" />
<Compile Include="Support\MemoryMappedFileByteBuffer.cs" />
+ <Compile Include="Support\ObjectExtensions.cs" />
<Compile Include="Support\PriorityQueue.cs" />
<Compile Include="Support\ReentrantLock.cs" />
<Compile Include="Support\SetExtensions.cs" />
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/979f4e9d/src/Lucene.Net.Core/Support/HashCodeMerge.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Support/HashCodeMerge.cs b/src/Lucene.Net.Core/Support/HashCodeMerge.cs
index ebac0ba..5268a43 100644
--- a/src/Lucene.Net.Core/Support/HashCodeMerge.cs
+++ b/src/Lucene.Net.Core/Support/HashCodeMerge.cs
@@ -6,6 +6,7 @@
//-----------------------------------------------------------------------
using System;
+using System.Collections;
namespace Lucene.Net.Support
{
@@ -86,5 +87,41 @@ namespace Lucene.Net.Support
return (int)crc32Value;
}
+
+ /// <summary>
+ /// Gets a hash code for the valueOrEnumerable. If the valueOrEnumerable implements
+ /// IEnumerable, it enumerates the values and makes a combined hash code representing
+ /// all of the values in the order they occur in the set. The types of IEnumerable must also be
+ /// the same, so for example a <see cref="int[]"/> and a <see cref="List{Int32}"/> containing
+ /// the same values will have different hash codes.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="valueOrEnumerable">Any value type, reference type or IEnumerable type.</param>
+ /// <returns>A combined hash code of the value and, if IEnumerable, any values it contains.</returns>
+ public static int GetValueHashCode<T>(this T valueOrEnumerable)
+ {
+ if (valueOrEnumerable == null)
+ return 0; // 0 for null
+
+ if (!(valueOrEnumerable is IEnumerable) || valueOrEnumerable is string)
+ {
+ return valueOrEnumerable.GetHashCode();
+ }
+
+ int hashCode = valueOrEnumerable.GetType().GetHashCode();
+ foreach (object value in valueOrEnumerable as IEnumerable)
+ {
+ if (value != null)
+ {
+ hashCode = CombineHashCodes(hashCode, value.GetHashCode());
+ }
+ else
+ {
+ hashCode = CombineHashCodes(hashCode, 0 /* 0 for null */);
+ }
+ }
+
+ return hashCode;
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/979f4e9d/src/Lucene.Net.Core/Support/ObjectExtensions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Support/ObjectExtensions.cs b/src/Lucene.Net.Core/Support/ObjectExtensions.cs
new file mode 100644
index 0000000..37ef70b
--- /dev/null
+++ b/src/Lucene.Net.Core/Support/ObjectExtensions.cs
@@ -0,0 +1,56 @@
+\ufeffusing System.Collections;
+
+namespace Lucene.Net.Support
+{
+ public static class ObjectExtensions
+ {
+ /// <summary>
+ /// Compares the current value against the other value to determine if
+ /// the values are equal. If the values implement IEnumerable (and are
+ /// not strings), then it will enumerate over the values and compare them
+ /// in the same order.
+ ///
+ /// This differs from most SetEquals implementations in that they usually
+ /// don't check the order of the elements in the IEnumerable, but this one does.
+ /// It also does the check in a safe manner in case the IEnumerable type is nullable,
+ /// so that null == null.
+ ///
+ /// The values that are provided don't necessarily have to implement IEnumerable
+ /// to check their values for equality.
+ ///
+ /// This method is most useful for assertions and testing, but it may
+ /// also be useful in other scenarios. Do note the IEnumerable values are cast to
+ /// object before comparing, so it may not be ideal for production scenarios
+ /// if the values are not reference types.
+ /// </summary>
+ /// <typeparam name="T">The type of object</typeparam>
+ /// <param name="a">This object</param>
+ /// <param name="b">The object that this object will be compared against</param>
+ /// <returns><c>true</c> if the values are equal; otherwise <c>false</c></returns>
+ public static bool ValueEquals<T>(this T a, T b)
+ {
+ if (a is IEnumerable && b is IEnumerable)
+ {
+ var iter = (b as IEnumerable).GetEnumerator();
+ foreach (object value in a as IEnumerable)
+ {
+ iter.MoveNext();
+ if (!object.Equals(value, iter.Current))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return a.Equals(b);
+ }
+
+ // Special case: strings are IEnumerable, but the default Equals works fine
+ // for testing value equality
+ public static bool ValueEquals(this string a, string b)
+ {
+ return a.Equals(b);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/979f4e9d/src/Lucene.Net.Core/Util/Fst/FST.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/Fst/FST.cs b/src/Lucene.Net.Core/Util/Fst/FST.cs
index 99be83d..c38f658 100644
--- a/src/Lucene.Net.Core/Util/Fst/FST.cs
+++ b/src/Lucene.Net.Core/Util/Fst/FST.cs
@@ -1,3 +1,4 @@
+using Lucene.Net.Support;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -440,22 +441,11 @@ namespace Lucene.Net.Util.Fst
Debug.Assert(root.Flags == asserting.Flags);
Debug.Assert(root.Label == asserting.Label);
Debug.Assert(root.NextArc == asserting.NextArc);
+
// LUCENENET NOTE: In .NET, IEnumerable will not equal another identical IEnumerable
// because it checks for reference equality, not that the list contents
- // are the same.
- if (root.NextFinalOutput is IEnumerable && asserting.NextFinalOutput is IEnumerable)
- {
- var iter = (asserting.NextFinalOutput as IEnumerable).GetEnumerator();
- foreach (object value in root.NextFinalOutput as IEnumerable)
- {
- iter.MoveNext();
- Debug.Assert(object.Equals(value, iter.Current));
- }
- }
- else
- {
- Debug.Assert(root.NextFinalOutput.Equals(asserting.NextFinalOutput));
- }
+ // are the same. ValueEquals (a custom extension method) will make that check.
+ Debug.Assert(root.NextFinalOutput.ValueEquals(asserting.NextFinalOutput));
Debug.Assert(root.Node == asserting.Node);
Debug.Assert(root.NumArcs == asserting.NumArcs);
Debug.Assert(root.Output.Equals(asserting.Output));
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/979f4e9d/src/Lucene.Net.Core/Util/Fst/NodeHash.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/Fst/NodeHash.cs b/src/Lucene.Net.Core/Util/Fst/NodeHash.cs
index 95b6115..5198fe7 100644
--- a/src/Lucene.Net.Core/Util/Fst/NodeHash.cs
+++ b/src/Lucene.Net.Core/Util/Fst/NodeHash.cs
@@ -2,6 +2,7 @@ using System.Diagnostics;
namespace Lucene.Net.Util.Fst
{
+ using Support;
using System.Collections;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -88,29 +89,7 @@ namespace Lucene.Net.Util.Fst
long n = ((Builder<T>.CompiledNode)arc.Target).Node;
h = PRIME * h + (int)(n ^ (n >> 32));
h = PRIME * h + arc.Output.GetHashCode();
-
- // LUCENENET: Since lists do not compare values by default in .NET,
- // we need this workaround to get the hashcode of the type + all of the
- // values.
- if (arc.NextFinalOutput is IEnumerable)
- {
- h = PRIME * h + arc.NextFinalOutput.GetType().GetHashCode();
- foreach (object value in arc.NextFinalOutput as IEnumerable)
- {
- if (value != null)
- {
- h = PRIME * h + value.GetHashCode();
- }
- else
- {
- h = PRIME * h + 0; // 0 for null
- }
- }
- }
- else
- {
- h = PRIME * h + arc.NextFinalOutput.GetHashCode();
- }
+ h = PRIME * h + arc.NextFinalOutput.GetValueHashCode();
if (arc.IsFinal)
{
h += 17;
@@ -133,29 +112,29 @@ namespace Lucene.Net.Util.Fst
h = PRIME * h + scratchArc.Label;
h = PRIME * h + (int)(scratchArc.Target ^ (scratchArc.Target >> 32));
h = PRIME * h + scratchArc.Output.GetHashCode();
-
- // LUCENENET: Since lists do not compare values by default in .NET,
- // we need this workaround to get the hashcode of the type + all of the
- // values.
- if (scratchArc.NextFinalOutput is IEnumerable)
- {
- h = PRIME * h + scratchArc.NextFinalOutput.GetType().GetHashCode();
- foreach (object value in scratchArc.NextFinalOutput as IEnumerable)
- {
- if (value != null)
- {
- h = PRIME * h + value.GetHashCode();
- }
- else
- {
- h = PRIME * h + 0; // 0 for null
- }
- }
- }
- else
- {
- h = PRIME * h + scratchArc.NextFinalOutput.GetHashCode();
- }
+ h = PRIME * h + scratchArc.NextFinalOutput.GetValueHashCode();
+ //// LUCENENET: Since lists do not compare values by default in .NET,
+ //// we need this workaround to get the hashcode of the type + all of the
+ //// values.
+ //if (scratchArc.NextFinalOutput is IEnumerable)
+ //{
+ // h = PRIME * h + scratchArc.NextFinalOutput.GetType().GetHashCode();
+ // foreach (object value in scratchArc.NextFinalOutput as IEnumerable)
+ // {
+ // if (value != null)
+ // {
+ // h = PRIME * h + value.GetHashCode();
+ // }
+ // else
+ // {
+ // h = PRIME * h + 0; // 0 for null
+ // }
+ // }
+ //}
+ //else
+ //{
+ // h = PRIME * h + scratchArc.NextFinalOutput.GetHashCode();
+ //}
if (scratchArc.IsFinal)
{
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/979f4e9d/src/Lucene.Net.TestFramework/Util/fst/FSTTester.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.TestFramework/Util/fst/FSTTester.cs b/src/Lucene.Net.TestFramework/Util/fst/FSTTester.cs
index 9bcccb9..fc3d75a 100644
--- a/src/Lucene.Net.TestFramework/Util/fst/FSTTester.cs
+++ b/src/Lucene.Net.TestFramework/Util/fst/FSTTester.cs
@@ -407,25 +407,11 @@ namespace Lucene.Net.Util.Fst
protected internal virtual bool OutputsEqual(T a, T b)
{
- // LUCENENET: In .NET, lists do not automatically test to ensure
+ // LUCENENET: In .NET, IEnumerables do not automatically test to ensure
// their values are equal, so we need to do that manually.
// Note that we are testing the values without regard to whether
// the enumerable type is nullable.
- if (a is IEnumerable && b is IEnumerable)
- {
- var iter = (b as IEnumerable).GetEnumerator();
- foreach (object value in a as IEnumerable)
- {
- iter.MoveNext();
- if (!object.Equals(value, iter.Current))
- {
- return false;
- }
- }
- return true;
- }
-
- return a.Equals(b);
+ return a.ValueEquals(b);
}
// FST is complete