public void RecentlyUsedLookupTest() { string value; MruCache <int, string> mruCache = new MruCache <int, string>(100); for (int i = 0; i < 200; ++i) { mruCache.TryAddValue(i, i.ToString()); for (int j = 0; j < i; j += 10) { Assert.True(mruCache.TryGetValue(j, out value)); Assert.Equal(j.ToString(), value); } } for (int j = 0; j < 100; j += 10) { Assert.True(mruCache.TryGetValue(j, out value)); Assert.Equal(j.ToString(), value); } for (int i = 170; i < 200; ++i) { Assert.True(mruCache.TryGetValue(i, out value)); Assert.Equal(i.ToString(), value); } }
public void TryRemove_returns_false_for_unknown_entry() { var cache = new MruCache <int, string>(capacity: 3); cache.Add(1, "one"); Assert.False(cache.TryRemove(2, out var removed)); Assert.Null(removed); }
private MruCache <string, HttpClient> EnsureHttpClientCache() { if (_httpClientCache == null || !_httpClientCache.AddRef()) { _httpClientCache = new MruCache <string, HttpClient>(10); } return(_httpClientCache); }
public void Clear() { lock (this.mutex) { if (this.tokenCache != null) { this.tokenCache = new MruCache <TokenProvider.Key, TokenProvider.TokenInfo>(this.cacheSize); } } }
public AsyncWaitCallbackMethodExecutor(CodeActivityMetadata metadata, MethodInfo asyncMethod, Activity invokingActivity, Type targetType, InArgument targetObject, Collection <Argument> parameters, RuntimeArgument returnObject, MruCache <MethodInfo, Func <object, object[], object> > funcCache, ReaderWriterLockSlim locker) : base(invokingActivity, targetType, targetObject, parameters, returnObject) { Fx.Assert(asyncMethod != null, "Must provide asyncMethod"); this.asyncMethod = asyncMethod; this.asyncFunc = MethodCallExpressionHelper.GetFunc(metadata, asyncMethod, funcCache, locker); }
internal WorkflowDefinitionDispenser(WorkflowRuntime runtime, bool validateOnCreate, int capacity) { if (capacity <= 0) { capacity = 0x7d0; } this.workflowRuntime = runtime; this.workflowTypes = new MruCache(capacity, this, CacheType.Type); this.xomlFragments = new MruCache(capacity, this, CacheType.Xoml); this.workflowOutParameters = new Dictionary <Type, List <PropertyInfo> >(); this.parametersLock = new ReaderWriterLock(); this.validateOnCreate = validateOnCreate; }
public void when_TryGetValue_called_with_existing_key__should_return_what_it_was_provided() { var mruCache = new MruCache<ValueWrapper<int>, object>(12); object added = new object(); var key = new ValueWrapper<int>(0); mruCache.Add(key, added); object res; Assert.IsTrue(mruCache.TryGetValue(new ValueWrapper<int>(0), out res)); Assert.AreEqual(added, res); }
public void when_TryGetValue_called_with_nonexistent_key__should_return_false() { var mruCache = new MruCache<ValueWrapper<int>, object>(12); object added = new object(); var key = new ValueWrapper<int>(0); mruCache.Add(key, added); object res; Assert.IsFalse(mruCache.TryGetValue(new ValueWrapper<int>(1), out res)); Assert.IsNull(res); }
public AsyncPatternMethodExecutor(CodeActivityMetadata metadata, MethodInfo beginMethod, MethodInfo endMethod, Activity invokingActivity, Type targetType, InArgument targetObject, Collection <Argument> parameters, RuntimeArgument returnObject, MruCache <MethodInfo, Func <object, object[], object> > funcCache, ReaderWriterLockSlim locker) : base(invokingActivity, targetType, targetObject, parameters, returnObject) { Fx.Assert(beginMethod != null && endMethod != null, "Must provide beginMethod and endMethod"); this.beginMethod = beginMethod; this.endMethod = endMethod; this.beginFunc = MethodCallExpressionHelper.GetFunc(metadata, beginMethod, funcCache, locker); this.endFunc = MethodCallExpressionHelper.GetFunc(metadata, endMethod, funcCache, locker); }
public void when_TryGetValue_called_with_nonexistent_key__should_return_false() { var mruCache = new MruCache <ValueWrapper <int>, object>(12); object added = new object(); var key = new ValueWrapper <int>(0); mruCache.Add(key, added); object res; Assert.IsFalse(mruCache.TryGetValue(new ValueWrapper <int>(1), out res)); Assert.IsNull(res); }
public void when_TryGetValue_called_with_existing_key__should_return_what_it_was_provided() { var mruCache = new MruCache <ValueWrapper <int>, object>(12); object added = new object(); var key = new ValueWrapper <int>(0); mruCache.Add(key, added); object res; Assert.IsTrue(mruCache.TryGetValue(new ValueWrapper <int>(0), out res)); Assert.AreEqual(added, res); }
public void Clear_removes_all_entries() { var cache = new MruCache <int, string>(capacity: 3); cache.Add(1, "one"); cache.Add(2, "two"); cache.Add(3, "three"); cache.Clear(); Assert.False(cache.TryGetValue(1, out _)); Assert.False(cache.TryGetValue(2, out _)); Assert.False(cache.TryGetValue(3, out _)); }
public static Func <object[], TResult> GetFunc <TResult> ( CodeActivityMetadata metadata , ConstructorInfo constructorInfo , MruCache <ConstructorInfo, Func <object[], TResult> > cache , ReaderWriterLockSlim locker ) { Func <object[], TResult> func = null; if (constructorInfo != null) { locker.EnterWriteLock(); try { cache.TryGetValue(constructorInfo, out func); } finally { locker.ExitWriteLock(); } } if (func == null) { func = GetFunc <TResult>(metadata, constructorInfo); if (constructorInfo != null) { locker.EnterWriteLock(); try { //MruCache has on ContainsKey(), so we use TryGetValue() Func <object[], TResult> result = null; if (!cache.TryGetValue(constructorInfo, out result)) { cache.Add(constructorInfo, func); } else { func = result; } } finally { locker.ExitWriteLock(); } } } return(func); }
public void TryRemove_removes_existing_entries() { var cache = new MruCache <int, string>(capacity: 3); cache.Add(1, "one"); cache.Add(2, "two"); cache.Add(3, "three"); Assert.True(cache.TryRemove(1, out var removed)); Assert.AreEqual("one", removed); Assert.False(cache.TryGetValue(1, out _)); Assert.True(cache.TryGetValue(2, out _)); Assert.True(cache.TryGetValue(3, out _)); }
public void SimpleCacheAddAndLookupTest() { MruCache <int, string> mruCache = new MruCache <int, string>(100); for (int i = 0; i < 100; ++i) { mruCache.TryAddValue(i, i.ToString()); } string value; for (int i = 0; i < 100; ++i) { Assert.True(mruCache.TryGetValue(i, out value)); Assert.Equal(i.ToString(), value); } Assert.False(mruCache.TryGetValue(101, out value)); }
public void TryGetValue_renews_lifespan_of_entry() { var cache = new MruCache <int, string>(capacity: 3); cache.Add(1, "one"); cache.Add(2, "two"); cache.Add(3, "three"); Assert.True(cache.TryGetValue(3, out _)); Assert.True(cache.TryGetValue(2, out _)); Assert.True(cache.TryGetValue(1, out _)); cache.Add(4, "four"); Assert.True(cache.TryGetValue(1, out _)); Assert.True(cache.TryGetValue(2, out _)); Assert.False(cache.TryGetValue(3, out _)); Assert.True(cache.TryGetValue(4, out _)); }
public void Add_expires_last_used_entry_when_at_capacity() { var cache = new MruCache <int, string>(capacity: 3); cache.Add(1, "one"); cache.Add(2, "two"); cache.Add(3, "three"); Assert.True(cache.TryGetValue(1, out _)); Assert.True(cache.TryGetValue(2, out _)); Assert.True(cache.TryGetValue(3, out _)); cache.Add(4, "four"); Assert.False(cache.TryGetValue(1, out _)); Assert.True(cache.TryGetValue(2, out _)); Assert.True(cache.TryGetValue(3, out _)); Assert.True(cache.TryGetValue(4, out _)); }
public void OverflowCacheAndLookupTest() { MruCache <int, string> mruCache = new MruCache <int, string>(100); for (int i = 0; i < 200; ++i) { mruCache.TryAddValue(i, i.ToString()); } string value; Assert.False(mruCache.TryGetValue(0, out value)); Assert.False(mruCache.TryGetValue(90, out value)); for (int i = 120; i < 200; ++i) { Assert.True(mruCache.TryGetValue(i, out value)); Assert.Equal(i.ToString(), value); } }
public void OverflowFreshCacheAndLookupTest() { string value; MruCache <int, string> mruCache = new MruCache <int, string>(100); for (int i = 0; i < 200; ++i) { mruCache.TryAddValue(i, i.ToString()); Assert.True(mruCache.TryGetValue(i, out value)); // No longer a virgin Assert.Equal(i.ToString(), value); } for (int j = 0; j < 2; ++j) { for (int i = 110; i < 200; ++i) { if (!mruCache.TryGetValue(i, out value)) { mruCache.TryAddValue(i, i.ToString()); Assert.True(mruCache.TryGetValue(i, out value)); } } } for (int i = 300; i < 310; ++i) { mruCache.TryAddValue(i, i.ToString()); } int cacheCount = 0; for (int i = 110; i < 200; ++i) { if (mruCache.TryGetValue(i, out value)) { ++cacheCount; } } Assert.True(cacheCount > 60); // See that old cache was not killed }
internal static Func <object, object[], object> GetFunc(CodeActivityMetadata metadata, MethodInfo methodInfo, MruCache <MethodInfo, Func <object, object[], object> > cache, ReaderWriterLockSlim locker, bool valueTypeReference = false) { Func <object, object[], object> func = null; locker.EnterWriteLock(); try { cache.TryGetValue(methodInfo, out func); } finally { locker.ExitWriteLock(); } if (func == null) { func = GetFunc(metadata, methodInfo, valueTypeReference); locker.EnterWriteLock(); try { //MruCache has on ContainsKey(), so we use TryGetValue() Func <object, object[], object> result = null; if (!cache.TryGetValue(methodInfo, out result)) { cache.Add(methodInfo, func); } else { func = result; } } finally { locker.ExitWriteLock(); } } return(func); }
public void OverflowVersionCacheAndLookupTest() { string value; MruCache <int, string> mruCache = new MruCache <int, string>(100); for (int i = 0; i < 200; ++i) { mruCache.TryAddValue(i, i.ToString()); Assert.True(mruCache.TryGetValue(i, out value)); // No longer a virgin Assert.Equal(i.ToString(), value); } for (int i = 0; i < 90; ++i) { Assert.False(mruCache.TryGetValue(i, out value)); } for (int i = 140; i < 200; ++i) { Assert.True(mruCache.TryGetValue(i, out value)); Assert.Equal(i.ToString(), value); } }
// Set methodExecutor, returning an error string if there are any problems (ambiguous match, etc.). public void DetermineMethodInfo(CodeActivityMetadata metadata, MruCache<MethodInfo, Func<object, object[], object>> funcCache, ReaderWriterLockSlim locker, ref MethodExecutor methodExecutor) { bool returnEarly = false; MethodExecutor oldMethodExecutor = methodExecutor; methodExecutor = null; if (string.IsNullOrEmpty(this.MethodName)) { metadata.AddValidationError(SR.ActivityPropertyMustBeSet("MethodName", this.Parent.DisplayName)); returnEarly = true; } Type targetType = this.TargetType; // If TargetType and the type of TargetObject are both set, it's an error. if (targetType != null && this.TargetObject != null && !this.TargetObject.IsEmpty) { metadata.AddValidationError(SR.TargetTypeAndTargetObjectAreMutuallyExclusive(this.Parent.GetType().Name, this.Parent.DisplayName)); returnEarly = true; } // If TargetType was set, look for a static method. If TargetObject was set, look for an instance method. They can't both be set. BindingFlags bindingFlags = this.TargetType != null ? staticBindingFlags : instanceBindingFlags; string bindingType = bindingFlags == staticBindingFlags ? staticString : instanceString; if (targetType == null) { if (this.TargetObject != null && !this.TargetObject.IsEmpty) { targetType = this.TargetObject.ArgumentType; } else { metadata.AddValidationError(SR.OneOfTwoPropertiesMustBeSet("TargetObject", "TargetType", this.Parent.GetType().Name, this.Parent.DisplayName)); returnEarly = true; } } // We've had one or more constraint violations already if (returnEarly) { return; } // Convert OutArgs and InOutArgs to out/ref types before resolution Type[] parameterTypes = Parameters.Select(argument => argument.Direction == ArgumentDirection.In ? argument.ArgumentType : argument.ArgumentType.MakeByRefType()) .ToArray(); Type[] genericTypeArguments = this.GenericTypeArguments.ToArray(); InheritanceAndParamArrayAwareBinder methodBinder = new InheritanceAndParamArrayAwareBinder(targetType, genericTypeArguments, this.Parent); // It may be possible to know (and check) the resultType even if the result won't be assigned anywhere. // Used 1.) for detecting async pattern, and 2.) to make sure we selected the correct MethodInfo. Type resultType = this.ResultType; if (this.RunAsynchronously) { int formalParamCount = parameterTypes.Length; Type[] beginMethodParameterTypes = new Type[formalParamCount + 2]; for (int i = 0; i < formalParamCount; i++) { beginMethodParameterTypes[i] = parameterTypes[i]; } beginMethodParameterTypes[formalParamCount] = typeof(AsyncCallback); beginMethodParameterTypes[formalParamCount + 1] = typeof(object); Type[] endMethodParameterTypes = { typeof(IAsyncResult) }; this.beginMethod = Resolve(targetType, "Begin" + this.MethodName, bindingFlags, methodBinder, beginMethodParameterTypes, genericTypeArguments, true); if (this.beginMethod != null && !this.beginMethod.ReturnType.Equals(typeof(IAsyncResult))) { this.beginMethod = null; } this.endMethod = Resolve(targetType, "End" + this.MethodName, bindingFlags, methodBinder, endMethodParameterTypes, genericTypeArguments, true); if (this.endMethod != null && resultType != null && !TypeHelper.AreTypesCompatible(this.endMethod.ReturnType, resultType)) { metadata.AddValidationError(SR.ReturnTypeIncompatible(this.endMethod.ReturnType.Name, MethodName, targetType.Name, this.Parent.DisplayName, resultType.Name)); this.endMethod = null; return; } if (this.beginMethod != null && this.endMethod != null && this.beginMethod.IsStatic == this.endMethod.IsStatic) { if (!(oldMethodExecutor is AsyncPatternMethodExecutor) || !((AsyncPatternMethodExecutor)oldMethodExecutor).IsTheSame(this.beginMethod, this.endMethod)) { methodExecutor = new AsyncPatternMethodExecutor(metadata, this.beginMethod, this.endMethod, this.Parent, this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker); } else { methodExecutor = new AsyncPatternMethodExecutor((AsyncPatternMethodExecutor)oldMethodExecutor, this.TargetType, this.TargetObject, this.Parameters, this.Result); } return; } } MethodInfo result; try { result = Resolve(targetType, this.MethodName, bindingFlags, methodBinder, parameterTypes, genericTypeArguments, false); } catch (AmbiguousMatchException) { metadata.AddValidationError(SR.DuplicateMethodFound(targetType.Name, bindingType, MethodName, this.Parent.DisplayName)); return; } if (result == null) { metadata.AddValidationError(SR.PublicMethodWithMatchingParameterDoesNotExist(targetType.Name, bindingType, MethodName, this.Parent.DisplayName)); return; } else if (resultType != null && !TypeHelper.AreTypesCompatible(result.ReturnType, resultType)) { metadata.AddValidationError( SR.ReturnTypeIncompatible(result.ReturnType.Name, MethodName, targetType.Name, this.Parent.DisplayName, resultType.Name)); return; } else { this.syncMethod = result; if (this.RunAsynchronously) { if (!(oldMethodExecutor is AsyncWaitCallbackMethodExecutor) || !((AsyncWaitCallbackMethodExecutor)oldMethodExecutor).IsTheSame(this.syncMethod)) { methodExecutor = new AsyncWaitCallbackMethodExecutor(metadata, this.syncMethod, this.Parent, this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker); } else { methodExecutor = new AsyncWaitCallbackMethodExecutor((AsyncWaitCallbackMethodExecutor)oldMethodExecutor, this.TargetType, this.TargetObject, this.Parameters, this.Result); } } else if (!(oldMethodExecutor is SyncMethodExecutor) || !((SyncMethodExecutor)oldMethodExecutor).IsTheSame(this.syncMethod)) { methodExecutor = new SyncMethodExecutor(metadata, this.syncMethod, this.Parent, this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker); } else { methodExecutor = new SyncMethodExecutor((SyncMethodExecutor)oldMethodExecutor, this.TargetType, this.TargetObject, this.Parameters, this.Result); } } }
public AsyncPatternMethodExecutor(CodeActivityMetadata metadata, MethodInfo beginMethod, MethodInfo endMethod, Activity invokingActivity, Type targetType, InArgument targetObject, Collection<Argument> parameters, RuntimeArgument returnObject, MruCache<MethodInfo, Func<object, object[], object>> funcCache, ReaderWriterLockSlim locker) : base(invokingActivity, targetType, targetObject, parameters, returnObject) { Fx.Assert(beginMethod != null && endMethod != null, "Must provide beginMethod and endMethod"); this.beginMethod = beginMethod; this.endMethod = endMethod; this.beginFunc = MethodCallExpressionHelper.GetFunc(metadata, beginMethod, funcCache, locker); this.endFunc = MethodCallExpressionHelper.GetFunc(metadata, endMethod, funcCache, locker); }
// Set methodExecutor, returning an error string if there are any problems (ambiguous match, etc.). public void DetermineMethodInfo(CodeActivityMetadata metadata, MruCache <MethodInfo, Func <object, object[], object> > funcCache, ReaderWriterLockSlim locker, ref MethodExecutor methodExecutor) { bool returnEarly = false; MethodExecutor oldMethodExecutor = methodExecutor; methodExecutor = null; if (string.IsNullOrEmpty(this.MethodName)) { metadata.AddValidationError(SR.ActivityPropertyMustBeSet("MethodName", this.Parent.DisplayName)); returnEarly = true; } Type targetType = this.TargetType; // If TargetType and the type of TargetObject are both set, it's an error. if (targetType != null && this.TargetObject != null && !this.TargetObject.IsEmpty) { metadata.AddValidationError(SR.TargetTypeAndTargetObjectAreMutuallyExclusive(this.Parent.GetType().Name, this.Parent.DisplayName)); returnEarly = true; } // If TargetType was set, look for a static method. If TargetObject was set, look for an instance method. They can't both be set. BindingFlags bindingFlags = this.TargetType != null ? staticBindingFlags : instanceBindingFlags; string bindingType = bindingFlags == staticBindingFlags ? staticString : instanceString; if (targetType == null) { if (this.TargetObject != null && !this.TargetObject.IsEmpty) { targetType = this.TargetObject.ArgumentType; } else { metadata.AddValidationError(SR.OneOfTwoPropertiesMustBeSet("TargetObject", "TargetType", this.Parent.GetType().Name, this.Parent.DisplayName)); returnEarly = true; } } // We've had one or more constraint violations already if (returnEarly) { return; } // Convert OutArgs and InOutArgs to out/ref types before resolution Type[] parameterTypes = Parameters.Select(argument => argument.Direction == ArgumentDirection.In ? argument.ArgumentType : argument.ArgumentType.MakeByRefType()) .ToArray(); Type[] genericTypeArguments = this.GenericTypeArguments.ToArray(); InheritanceAndParamArrayAwareBinder methodBinder = new InheritanceAndParamArrayAwareBinder(targetType, genericTypeArguments, this.Parent); // It may be possible to know (and check) the resultType even if the result won't be assigned anywhere. // Used 1.) for detecting async pattern, and 2.) to make sure we selected the correct MethodInfo. Type resultType = this.ResultType; if (this.RunAsynchronously) { int formalParamCount = parameterTypes.Length; Type[] beginMethodParameterTypes = new Type[formalParamCount + 2]; for (int i = 0; i < formalParamCount; i++) { beginMethodParameterTypes[i] = parameterTypes[i]; } beginMethodParameterTypes[formalParamCount] = typeof(AsyncCallback); beginMethodParameterTypes[formalParamCount + 1] = typeof(object); Type[] endMethodParameterTypes = { typeof(IAsyncResult) }; this.beginMethod = Resolve(targetType, "Begin" + this.MethodName, bindingFlags, methodBinder, beginMethodParameterTypes, genericTypeArguments, true); if (this.beginMethod != null && !this.beginMethod.ReturnType.Equals(typeof(IAsyncResult))) { this.beginMethod = null; } this.endMethod = Resolve(targetType, "End" + this.MethodName, bindingFlags, methodBinder, endMethodParameterTypes, genericTypeArguments, true); if (this.endMethod != null && resultType != null && !TypeHelper.AreTypesCompatible(this.endMethod.ReturnType, resultType)) { metadata.AddValidationError(SR.ReturnTypeIncompatible(this.endMethod.ReturnType.Name, MethodName, targetType.Name, this.Parent.DisplayName, resultType.Name)); this.endMethod = null; return; } if (this.beginMethod != null && this.endMethod != null && this.beginMethod.IsStatic == this.endMethod.IsStatic) { if (!(oldMethodExecutor is AsyncPatternMethodExecutor) || !((AsyncPatternMethodExecutor)oldMethodExecutor).IsTheSame(this.beginMethod, this.endMethod)) { methodExecutor = new AsyncPatternMethodExecutor(metadata, this.beginMethod, this.endMethod, this.Parent, this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker); } else { methodExecutor = new AsyncPatternMethodExecutor((AsyncPatternMethodExecutor)oldMethodExecutor, this.TargetType, this.TargetObject, this.Parameters, this.Result); } return; } } MethodInfo result; try { result = Resolve(targetType, this.MethodName, bindingFlags, methodBinder, parameterTypes, genericTypeArguments, false); } catch (AmbiguousMatchException) { metadata.AddValidationError(SR.DuplicateMethodFound(targetType.Name, bindingType, MethodName, this.Parent.DisplayName)); return; } if (result == null) { metadata.AddValidationError(SR.PublicMethodWithMatchingParameterDoesNotExist(targetType.Name, bindingType, MethodName, this.Parent.DisplayName)); return; } else if (resultType != null && !TypeHelper.AreTypesCompatible(result.ReturnType, resultType)) { metadata.AddValidationError( SR.ReturnTypeIncompatible(result.ReturnType.Name, MethodName, targetType.Name, this.Parent.DisplayName, resultType.Name)); return; } else { this.syncMethod = result; if (this.RunAsynchronously) { if (!(oldMethodExecutor is AsyncWaitCallbackMethodExecutor) || !((AsyncWaitCallbackMethodExecutor)oldMethodExecutor).IsTheSame(this.syncMethod)) { methodExecutor = new AsyncWaitCallbackMethodExecutor(metadata, this.syncMethod, this.Parent, this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker); } else { methodExecutor = new AsyncWaitCallbackMethodExecutor((AsyncWaitCallbackMethodExecutor)oldMethodExecutor, this.TargetType, this.TargetObject, this.Parameters, this.Result); } } else if (!(oldMethodExecutor is SyncMethodExecutor) || !((SyncMethodExecutor)oldMethodExecutor).IsTheSame(this.syncMethod)) { methodExecutor = new SyncMethodExecutor(metadata, this.syncMethod, this.Parent, this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker); } else { methodExecutor = new SyncMethodExecutor((SyncMethodExecutor)oldMethodExecutor, this.TargetType, this.TargetObject, this.Parameters, this.Result); } } }
public AsyncWaitCallbackMethodExecutor(CodeActivityMetadata metadata, MethodInfo asyncMethod, Activity invokingActivity, Type targetType, InArgument targetObject, Collection<Argument> parameters, RuntimeArgument returnObject, MruCache<MethodInfo, Func<object, object[], object>> funcCache, ReaderWriterLockSlim locker) : base(invokingActivity, targetType, targetObject, parameters, returnObject) { Fx.Assert(asyncMethod != null, "Must provide asyncMethod"); this.asyncMethod = asyncMethod; this.asyncFunc = MethodCallExpressionHelper.GetFunc(metadata, asyncMethod, funcCache, locker); }