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