Update of /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Expressions
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv11994/src/Spring/Spring.Core/Expressions
Modified Files:
MethodNode.cs
Log Message:
SPRNET-755
Index: MethodNode.cs
===================================================================
RCS file: /cvsroot/springnet/Spring.Net/src/Spring/Spring.Core/Expressions/MethodNode.cs,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** MethodNode.cs 7 Sep 2007 03:01:26 -0000 1.19
--- MethodNode.cs 6 Mar 2008 20:20:36 -0000 1.20
***************
*** 49,52 ****
--- 49,53 ----
private int argumentCount;
private SafeMethod method;
+ private int methodHash;
private bool isCollectionProcessor = false;
private ICollectionProcessor collectionProcessor;
***************
*** 93,119 ****
object[] argValues = ResolveArguments(evalContext);
! if (!initialized)
{
! lock(this)
{
! if (!initialized)
! {
! Initialize(argValues, context);
! initialized = true;
! }
}
}
! if (isCollectionProcessor)
{
! return collectionProcessor.Process((ICollection) context, argValues);
}
else
{
object[] paramValues = (isParamArray ? ReflectionUtils.PackageParamArray(argValues, argumentCount, paramArrayType) : argValues);
! return method.Invoke(context, paramValues);
}
}
private void Initialize(object[] argValues, object context)
{
--- 94,149 ----
object[] argValues = ResolveArguments(evalContext);
! ICollectionProcessor localCollectionProcessor = null;
! SafeMethod localMethod = null;
!
! // resolve method, if necessary
! lock (this)
{
! // calculate checksum, if the cached method matches the current context
! if (initialized && !isCollectionProcessor)
{
! int calculatedHash = CalculateMethodHash(context.GetType(), argValues);
! initialized = (calculatedHash == methodHash);
! }
!
! if (!initialized)
! {
! Initialize(argValues, context);
! initialized = true;
! }
!
! if (isCollectionProcessor)
! {
! localCollectionProcessor = collectionProcessor;
! }
! else
! {
! localMethod = method;
}
}
! // invoke method
! if (localCollectionProcessor != null)
{
! return collectionProcessor.Process((ICollection)context, argValues);
}
else
{
object[] paramValues = (isParamArray ? ReflectionUtils.PackageParamArray(argValues, argumentCount, paramArrayType) : argValues);
! return localMethod.Invoke(context, paramValues);
}
}
+ private int CalculateMethodHash(Type contextType, object[] argValues)
+ {
+ int hash = contextType.GetHashCode();
+ for (int i = 0; i < argValues.Length; i++)
+ {
+ object arg = argValues[i];
+ if (arg != null) hash += s_primes[i] * arg.GetType().GetHashCode();
+ }
+ return hash;
+ }
+
private void Initialize(object[] argValues, object context)
{
***************
*** 121,125 ****
if ((context == null || context is ICollection) && collectionProcessorMap.Contains(methodName))
{
! collectionProcessor = (ICollectionProcessor) collectionProcessorMap[methodName];
isCollectionProcessor = true;
}
--- 151,155 ----
if ((context == null || context is ICollection) && collectionProcessorMap.Contains(methodName))
{
! collectionProcessor = (ICollectionProcessor)collectionProcessorMap[methodName];
isCollectionProcessor = true;
}
***************
*** 154,158 ****
{
ParameterInfo lastParameter = parameters[parameters.Length - 1];
! isParamArray = lastParameter.GetCustomAttributes(typeof (ParamArrayAttribute), false).Length > 0;
if (isParamArray)
{
--- 184,188 ----
{
ParameterInfo lastParameter = parameters[parameters.Length - 1];
! isParamArray = lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0;
if (isParamArray)
{
***************
*** 163,166 ****
--- 193,197 ----
method = new SafeMethod(mi);
+ methodHash = CalculateMethodHash(contextType, argValues);
}
}
***************
*** 180,184 ****
try
{
! mi = type.GetMethod(methodName, bindingFlags|BindingFlags.FlattenHierarchy);
}
catch (AmbiguousMatchException)
--- 211,215 ----
try
{
! mi = type.GetMethod(methodName, bindingFlags | BindingFlags.FlattenHierarchy);
}
catch (AmbiguousMatchException)
***************
*** 194,202 ****
}
!
private static MethodInfo[] GetCandidateMethods(Type type, string methodName, BindingFlags bindingFlags, int argCount)
{
! MethodInfo[] methods = type.GetMethods(bindingFlags|BindingFlags.FlattenHierarchy);
ArrayList matches = new ArrayList();
--- 225,233 ----
}
!
private static MethodInfo[] GetCandidateMethods(Type type, string methodName, BindingFlags bindingFlags, int argCount)
{
! MethodInfo[] methods = type.GetMethods(bindingFlags | BindingFlags.FlattenHierarchy);
ArrayList matches = new ArrayList();
***************
*** 213,217 ****
{
ParameterInfo lastParameter = parameters[parameters.Length - 1];
! if (lastParameter.GetCustomAttributes(typeof (ParamArrayAttribute), false).Length > 0)
{
matches.Add(method);
--- 244,248 ----
{
ParameterInfo lastParameter = parameters[parameters.Length - 1];
! if (lastParameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0)
{
matches.Add(method);
***************
*** 221,226 ****
}
! return (MethodInfo[]) matches.ToArray(typeof(MethodInfo));
}
}
}
--- 252,275 ----
}
! return (MethodInfo[])matches.ToArray(typeof(MethodInfo));
}
+
+ // used to calculate signature hash while caring for arg positions
+ private static readonly int[] s_primes =
+ {
+ 17, 19, 23, 29
+ , 31, 37, 41, 43, 47, 53, 59, 61, 67, 71
+ , 73, 79, 83, 89, 97, 101, 103, 107, 109, 113
+ , 127, 131, 137, 139, 149, 151, 157, 163, 167, 173
+ , 179, 181, 191, 193, 197, 199, 211, 223, 227, 229
+ , 233, 239, 241, 251, 257, 263, 269, 271, 277, 281
+ , 283, 293, 307, 311, 313, 317, 331, 337, 347, 349
+ , 353, 359, 367, 373, 379, 383, 389, 397, 401, 409
+ , 419, 421, 431, 433, 439, 443, 449, 457, 461, 463
+ , 467, 479, 487, 491, 499, 503, 509, 521, 523, 541
+ , 547, 557, 563, 569, 571, 577, 587, 593, 599, 601
+ , 607, 613, 617, 619, 631, 641, 643, 647, 653, 659
+ , 661, 673, 677, 683, 691, 701, 709, 719, 727, 733
+ };
}
}
|