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 2015/03/01 23:32:02 UTC
[1/3] lucenenet git commit: Fix for
TestDirectoryReaderReopen.TestThreadSafety
Repository: lucenenet
Updated Branches:
refs/heads/master bdf4ec7b0 -> 9ff490365
Fix for TestDirectoryReaderReopen.TestThreadSafety
The java version uses a concurrent hash map so I updated VirtualMethod to use that.
After that change, we no longer needed the lock on the Reap() function.
Next the Get() needed to use a tryGet() and return the default if there was nothing in the collection.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/9b57fca6
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/9b57fca6
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/9b57fca6
Branch: refs/heads/master
Commit: 9b57fca6a6961905204f41bef1b5fe784741a58b
Parents: ac8fa48
Author: Chand2048 <Ch...@Microsoft.com>
Authored: Wed Feb 25 14:21:16 2015 -0800
Committer: Chand2048 <Ch...@Microsoft.com>
Committed: Wed Feb 25 14:21:16 2015 -0800
----------------------------------------------------------------------
src/Lucene.Net.Core/Util/VirtualMethod.cs | 2 +-
src/Lucene.Net.Core/Util/WeakIdentityMap.cs | 33 +++++++++++++-----------
2 files changed, 19 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9b57fca6/src/Lucene.Net.Core/Util/VirtualMethod.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/VirtualMethod.cs b/src/Lucene.Net.Core/Util/VirtualMethod.cs
index faa5a70..e21c253 100644
--- a/src/Lucene.Net.Core/Util/VirtualMethod.cs
+++ b/src/Lucene.Net.Core/Util/VirtualMethod.cs
@@ -64,7 +64,7 @@ namespace Lucene.Net.Util
private readonly Type BaseClass;
private readonly string Method;
private readonly Type[] Parameters;
- private readonly WeakIdentityMap<Type, int> Cache = WeakIdentityMap<Type, int>.NewHashMap(false);
+ private readonly WeakIdentityMap<Type, int> Cache = WeakIdentityMap<Type, int>.NewConcurrentHashMap(false);
/// <summary>
/// Creates a new instance for the given {@code baseClass} and method declaration. </summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9b57fca6/src/Lucene.Net.Core/Util/WeakIdentityMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/WeakIdentityMap.cs b/src/Lucene.Net.Core/Util/WeakIdentityMap.cs
index ee792be..e556a28 100644
--- a/src/Lucene.Net.Core/Util/WeakIdentityMap.cs
+++ b/src/Lucene.Net.Core/Util/WeakIdentityMap.cs
@@ -135,7 +135,16 @@ namespace Lucene.Net.Util
{
Reap();
}
- return BackingStore[new IdentityWeakReference(key)];
+
+ V val;
+ if (BackingStore.TryGetValue(new IdentityWeakReference(key), out val))
+ {
+ return val;
+ }
+ else
+ {
+ return default(V);
+ }
}
/// <summary>
@@ -329,25 +338,19 @@ namespace Lucene.Net.Util
/// <seealso cref= <a href="#reapInfo">Information about the <code>reapOnRead</code> setting</a> </seealso>
public void Reap()
{
- lock (BackingStore)
+ List<IdentityWeakReference> keysToRemove = new List<IdentityWeakReference>();
+ foreach (IdentityWeakReference zombie in BackingStore.Keys)
{
- List<IdentityWeakReference> keysToRemove = new List<IdentityWeakReference>();
-
- foreach (IdentityWeakReference zombie in BackingStore.Keys)
+ if (!zombie.IsAlive)
{
- if (!zombie.IsAlive)
- keysToRemove.Add(zombie);
- }
-
- foreach (var key in keysToRemove)
- {
- BackingStore.Remove(key);
+ keysToRemove.Add(zombie);
}
}
- /*while ((zombie = queue.poll()) != null)
+
+ foreach (var key in keysToRemove)
{
- BackingStore.Remove(zombie);
- }*/
+ BackingStore.Remove(key);
+ }
}
// we keep a hard reference to our NULL key, so map supports null keys that never get GCed:
[2/3] lucenenet git commit: Merge remote-tracking branch
'guidotag/TestThreadSafety2'
Posted by sy...@apache.org.
Merge remote-tracking branch 'guidotag/TestThreadSafety2'
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/3d092609
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/3d092609
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/3d092609
Branch: refs/heads/master
Commit: 3d0926099390acd908d6ab3f79c4434431792294
Parents: bdf4ec7 9b57fca
Author: Itamar Syn-Hershko <it...@code972.com>
Authored: Mon Mar 2 00:21:47 2015 +0200
Committer: Itamar Syn-Hershko <it...@code972.com>
Committed: Mon Mar 2 00:21:47 2015 +0200
----------------------------------------------------------------------
src/Lucene.Net.Core/Util/VirtualMethod.cs | 2 +-
src/Lucene.Net.Core/Util/WeakIdentityMap.cs | 33 +++++++++++++-----------
2 files changed, 19 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
[3/3] lucenenet git commit: Moving some unused stuff around
Posted by sy...@apache.org.
Moving some unused stuff around
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/9ff49036
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/9ff49036
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/9ff49036
Branch: refs/heads/master
Commit: 9ff4903653b6ca6dec0383eb09213758bd40764d
Parents: 3d09260
Author: Itamar Syn-Hershko <it...@code972.com>
Authored: Mon Mar 2 00:31:31 2015 +0200
Committer: Itamar Syn-Hershko <it...@code972.com>
Committed: Mon Mar 2 00:31:31 2015 +0200
----------------------------------------------------------------------
src/Lucene.Net.Core/Lucene.Net.csproj | 1 -
src/Lucene.Net.Core/Util/VirtualMethod.cs | 165 -------------------
src/Lucene.Net.Core/Util/WeakIdentityMap.cs | 2 +
.../Lucene.Net.TestFramework.csproj | 1 +
.../Util/VirtualMethod.cs | 164 ++++++++++++++++++
5 files changed, 167 insertions(+), 166 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9ff49036/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 41e5b32..5cfcce9 100644
--- a/src/Lucene.Net.Core/Lucene.Net.csproj
+++ b/src/Lucene.Net.Core/Lucene.Net.csproj
@@ -854,7 +854,6 @@
<Compile Include="Util\ToStringUtils.cs" />
<Compile Include="Util\UnicodeUtil.cs" />
<Compile Include="Util\LuceneVersion.cs" />
- <Compile Include="Util\VirtualMethod.cs" />
<Compile Include="Util\WAH8DocIdSet.cs" />
<Compile Include="Util\WeakIdentityMap.cs" />
</ItemGroup>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9ff49036/src/Lucene.Net.Core/Util/VirtualMethod.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/VirtualMethod.cs b/src/Lucene.Net.Core/Util/VirtualMethod.cs
deleted file mode 100644
index e21c253..0000000
--- a/src/Lucene.Net.Core/Util/VirtualMethod.cs
+++ /dev/null
@@ -1,165 +0,0 @@
-using System.Linq;
-using Lucene.Net.Support;
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-
-namespace Lucene.Net.Util
-{
- /*
- * 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>
- /// A utility for keeping backwards compatibility on previously abstract methods
- /// (or similar replacements).
- /// <p>Before the replacement method can be made abstract, the old method must kept deprecated.
- /// If somebody still overrides the deprecated method in a non-final class,
- /// you must keep track, of this and maybe delegate to the old method in the subclass.
- /// The cost of reflection is minimized by the following usage of this class:</p>
- /// <p>Define <strong>static final</strong> fields in the base class ({@code BaseClass}),
- /// where the old and new method are declared:</p>
- /// <pre class="prettyprint">
- /// static final VirtualMethod<BaseClass> newMethod =
- /// new VirtualMethod<BaseClass>(BaseClass.class, "newName", parameters...);
- /// static final VirtualMethod<BaseClass> oldMethod =
- /// new VirtualMethod<BaseClass>(BaseClass.class, "oldName", parameters...);
- /// </pre>
- /// <p>this enforces the singleton status of these objects, as the maintenance of the cache would be too costly else.
- /// If you try to create a second instance of for the same method/{@code baseClass} combination, an exception is thrown.</p>
- /// <p>To detect if e.g. the old method was overridden by a more far subclass on the inheritance path to the current
- /// instance's class, use a <strong>non-static</strong> field:</p>
- /// <pre class="prettyprint">
- /// final boolean isDeprecatedMethodOverridden =
- /// oldMethod.getImplementationDistance(this.getClass()) > newMethod.getImplementationDistance(this.getClass());
- ///
- /// <em>// alternatively (more readable):</em>
- /// final boolean isDeprecatedMethodOverridden =
- /// VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod) > 0
- /// </pre>
- /// <p><seealso cref="getImplementationDistance"/> returns the distance of the subclass that overrides this method.
- /// The one with the larger distance should be used preferable.
- /// this way also more complicated method rename scenarios can be handled
- /// (think of 2.9 {@code TokenStream} deprecations).</p>
- ///
- /// @lucene.internal
- /// </summary>
- public sealed class VirtualMethod<C>
- {
- private static readonly ISet<MethodInfo> SingletonSet = new ConcurrentHashSet<MethodInfo>(new HashSet<MethodInfo>());
-
- private readonly Type BaseClass;
- private readonly string Method;
- private readonly Type[] Parameters;
- private readonly WeakIdentityMap<Type, int> Cache = WeakIdentityMap<Type, int>.NewConcurrentHashMap(false);
-
- /// <summary>
- /// Creates a new instance for the given {@code baseClass} and method declaration. </summary>
- /// <exception cref="UnsupportedOperationException"> if you create a second instance of the same
- /// {@code baseClass} and method declaration combination. this enforces the singleton status. </exception>
- /// <exception cref="IllegalArgumentException"> if {@code baseClass} does not declare the given method. </exception>
- public VirtualMethod(Type baseClass, string method, params Type[] parameters)
- {
- this.BaseClass = baseClass;
- this.Method = method;
- this.Parameters = parameters;
- try
- {
- MethodInfo mi = baseClass.GetMethod(method, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, parameters, null);
- if (mi == null)
- {
- throw new System.ArgumentException(baseClass.Name + " has no such method.");
- }
- else if (!SingletonSet.Add(mi))
- {
- throw new System.NotSupportedException("VirtualMethod instances must be singletons and therefore " + "assigned to static final members in the same class, they use as baseClass ctor param.");
- }
- }
- catch (NotSupportedException nsme)
- {
- throw new System.ArgumentException(baseClass.Name + " has no such method: " + nsme.Message);
- }
- }
-
- /// <summary>
- /// Returns the distance from the {@code baseClass} in which this method is overridden/implemented
- /// in the inheritance path between {@code baseClass} and the given subclass {@code subclazz}. </summary>
- /// <returns> 0 iff not overridden, else the distance to the base class </returns>
- public int GetImplementationDistance(Type subclazz)
- {
- int distance = Cache.Get(subclazz);
- if (distance == default(int))
- {
- // we have the slight chance that another thread may do the same, but who cares?
- Cache.Put(subclazz, distance = Convert.ToInt32(ReflectImplementationDistance(subclazz)));
- }
- return (int)distance;
- }
-
- /// <summary>
- /// Returns, if this method is overridden/implemented in the inheritance path between
- /// {@code baseClass} and the given subclass {@code subclazz}.
- /// <p>You can use this method to detect if a method that should normally be final was overridden
- /// by the given instance's class. </summary>
- /// <returns> {@code false} iff not overridden </returns>
- public bool IsOverriddenAsOf(Type subclazz)
- {
- return GetImplementationDistance(subclazz) > 0;
- }
-
- private int ReflectImplementationDistance(Type subclazz)
- {
- if (!BaseClass.IsAssignableFrom(subclazz))
- {
- throw new System.ArgumentException(subclazz.Name + " is not a subclass of " + BaseClass.Name);
- }
- bool overridden = false;
- int distance = 0;
- for (Type clazz = subclazz; clazz != BaseClass && clazz != null; clazz = clazz.BaseType)
- {
- // lookup method, if success mark as overridden
- if (!overridden)
- {
- MethodInfo mi = clazz.GetMethod(Method,
- BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
- null, Parameters, null);
-
- if (mi != null)
- overridden = true;
- }
-
- // increment distance if overridden
- if (overridden)
- {
- distance++;
- }
- }
- return distance;
- }
-
- /// <summary>
- /// Utility method that compares the implementation/override distance of two methods. </summary>
- /// <returns> <ul>
- /// <li>> 1, iff {@code m1} is overridden/implemented in a subclass of the class overriding/declaring {@code m2}
- /// <li>< 1, iff {@code m2} is overridden in a subclass of the class overriding/declaring {@code m1}
- /// <li>0, iff both methods are overridden in the same class (or are not overridden at all)
- /// </ul> </returns>
- public static int compareImplementationDistance<C>(Type clazz, VirtualMethod<C> m1, VirtualMethod<C> m2)
- {
- return Convert.ToInt32(m1.GetImplementationDistance(clazz)).CompareTo(m2.GetImplementationDistance(clazz));
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9ff49036/src/Lucene.Net.Core/Util/WeakIdentityMap.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/WeakIdentityMap.cs b/src/Lucene.Net.Core/Util/WeakIdentityMap.cs
index e556a28..aa4e1a8 100644
--- a/src/Lucene.Net.Core/Util/WeakIdentityMap.cs
+++ b/src/Lucene.Net.Core/Util/WeakIdentityMap.cs
@@ -61,6 +61,8 @@ namespace Lucene.Net.Util
public sealed class WeakIdentityMap<K, V>
where K : class
{
+ // LUCENENET TODO Make this class internal as it isn't required anywhere; need to have it exposed to tests though
+
//private readonly ReferenceQueue<object> queue = new ReferenceQueue<object>();
private readonly IDictionary<IdentityWeakReference, V> BackingStore;
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9ff49036/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj b/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj
index 84c6bb1..778659d 100644
--- a/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj
+++ b/src/Lucene.Net.TestFramework/Lucene.Net.TestFramework.csproj
@@ -469,6 +469,7 @@
<Compile Include="JavaCompatibility\LuceneTestCase.cs" />
<Compile Include="JavaCompatibility\LuceneTypesHelpers.cs" />
<Compile Include="JavaCompatibility\SystemTypesHelpers.cs" />
+ <Compile Include="Util\VirtualMethod.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lucene.Net.Core\Lucene.Net.csproj">
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/9ff49036/src/Lucene.Net.TestFramework/Util/VirtualMethod.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.TestFramework/Util/VirtualMethod.cs b/src/Lucene.Net.TestFramework/Util/VirtualMethod.cs
new file mode 100644
index 0000000..319efaa
--- /dev/null
+++ b/src/Lucene.Net.TestFramework/Util/VirtualMethod.cs
@@ -0,0 +1,164 @@
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Lucene.Net.Util
+{
+ /*
+ * 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>
+ /// A utility for keeping backwards compatibility on previously abstract methods
+ /// (or similar replacements).
+ /// <p>Before the replacement method can be made abstract, the old method must kept deprecated.
+ /// If somebody still overrides the deprecated method in a non-final class,
+ /// you must keep track, of this and maybe delegate to the old method in the subclass.
+ /// The cost of reflection is minimized by the following usage of this class:</p>
+ /// <p>Define <strong>static final</strong> fields in the base class ({@code BaseClass}),
+ /// where the old and new method are declared:</p>
+ /// <pre class="prettyprint">
+ /// static final VirtualMethod<BaseClass> newMethod =
+ /// new VirtualMethod<BaseClass>(BaseClass.class, "newName", parameters...);
+ /// static final VirtualMethod<BaseClass> oldMethod =
+ /// new VirtualMethod<BaseClass>(BaseClass.class, "oldName", parameters...);
+ /// </pre>
+ /// <p>this enforces the singleton status of these objects, as the maintenance of the cache would be too costly else.
+ /// If you try to create a second instance of for the same method/{@code baseClass} combination, an exception is thrown.</p>
+ /// <p>To detect if e.g. the old method was overridden by a more far subclass on the inheritance path to the current
+ /// instance's class, use a <strong>non-static</strong> field:</p>
+ /// <pre class="prettyprint">
+ /// final boolean isDeprecatedMethodOverridden =
+ /// oldMethod.getImplementationDistance(this.getClass()) > newMethod.getImplementationDistance(this.getClass());
+ ///
+ /// <em>// alternatively (more readable):</em>
+ /// final boolean isDeprecatedMethodOverridden =
+ /// VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod) > 0
+ /// </pre>
+ /// <p><seealso cref="getImplementationDistance"/> returns the distance of the subclass that overrides this method.
+ /// The one with the larger distance should be used preferable.
+ /// this way also more complicated method rename scenarios can be handled
+ /// (think of 2.9 {@code TokenStream} deprecations).</p>
+ ///
+ /// @lucene.internal
+ /// </summary>
+ public sealed class VirtualMethod<C>
+ {
+ private static readonly ISet<MethodInfo> SingletonSet = new ConcurrentHashSet<MethodInfo>(new HashSet<MethodInfo>());
+
+ private readonly Type BaseClass;
+ private readonly string Method;
+ private readonly Type[] Parameters;
+ private readonly WeakIdentityMap<Type, int> Cache = WeakIdentityMap<Type, int>.NewConcurrentHashMap(false);
+
+ /// <summary>
+ /// Creates a new instance for the given {@code baseClass} and method declaration. </summary>
+ /// <exception cref="UnsupportedOperationException"> if you create a second instance of the same
+ /// {@code baseClass} and method declaration combination. this enforces the singleton status. </exception>
+ /// <exception cref="IllegalArgumentException"> if {@code baseClass} does not declare the given method. </exception>
+ public VirtualMethod(Type baseClass, string method, params Type[] parameters)
+ {
+ this.BaseClass = baseClass;
+ this.Method = method;
+ this.Parameters = parameters;
+ try
+ {
+ MethodInfo mi = baseClass.GetMethod(method, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, parameters, null);
+ if (mi == null)
+ {
+ throw new System.ArgumentException(baseClass.Name + " has no such method.");
+ }
+ else if (!SingletonSet.Add(mi))
+ {
+ throw new System.NotSupportedException("VirtualMethod instances must be singletons and therefore " + "assigned to static final members in the same class, they use as baseClass ctor param.");
+ }
+ }
+ catch (NotSupportedException nsme)
+ {
+ throw new System.ArgumentException(baseClass.Name + " has no such method: " + nsme.Message);
+ }
+ }
+
+ /// <summary>
+ /// Returns the distance from the {@code baseClass} in which this method is overridden/implemented
+ /// in the inheritance path between {@code baseClass} and the given subclass {@code subclazz}. </summary>
+ /// <returns> 0 iff not overridden, else the distance to the base class </returns>
+ public int GetImplementationDistance(Type subclazz)
+ {
+ int distance = Cache.Get(subclazz);
+ if (distance == default(int))
+ {
+ // we have the slight chance that another thread may do the same, but who cares?
+ Cache.Put(subclazz, distance = Convert.ToInt32(ReflectImplementationDistance(subclazz)));
+ }
+ return (int)distance;
+ }
+
+ /// <summary>
+ /// Returns, if this method is overridden/implemented in the inheritance path between
+ /// {@code baseClass} and the given subclass {@code subclazz}.
+ /// <p>You can use this method to detect if a method that should normally be final was overridden
+ /// by the given instance's class. </summary>
+ /// <returns> {@code false} iff not overridden </returns>
+ public bool IsOverriddenAsOf(Type subclazz)
+ {
+ return GetImplementationDistance(subclazz) > 0;
+ }
+
+ private int ReflectImplementationDistance(Type subclazz)
+ {
+ if (!BaseClass.IsAssignableFrom(subclazz))
+ {
+ throw new System.ArgumentException(subclazz.Name + " is not a subclass of " + BaseClass.Name);
+ }
+ bool overridden = false;
+ int distance = 0;
+ for (Type clazz = subclazz; clazz != BaseClass && clazz != null; clazz = clazz.BaseType)
+ {
+ // lookup method, if success mark as overridden
+ if (!overridden)
+ {
+ MethodInfo mi = clazz.GetMethod(Method,
+ BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+ null, Parameters, null);
+
+ if (mi != null)
+ overridden = true;
+ }
+
+ // increment distance if overridden
+ if (overridden)
+ {
+ distance++;
+ }
+ }
+ return distance;
+ }
+
+ /// <summary>
+ /// Utility method that compares the implementation/override distance of two methods. </summary>
+ /// <returns> <ul>
+ /// <li>> 1, iff {@code m1} is overridden/implemented in a subclass of the class overriding/declaring {@code m2}
+ /// <li>< 1, iff {@code m2} is overridden in a subclass of the class overriding/declaring {@code m1}
+ /// <li>0, iff both methods are overridden in the same class (or are not overridden at all)
+ /// </ul> </returns>
+ public static int compareImplementationDistance<C>(Type clazz, VirtualMethod<C> m1, VirtualMethod<C> m2)
+ {
+ return Convert.ToInt32(m1.GetImplementationDistance(clazz)).CompareTo(m2.GetImplementationDistance(clazz));
+ }
+ }
+}
\ No newline at end of file