/// <summary> /// Atomically searches for a specified key in the table and returns the corresponding value.If the key does not exist in the table, the method invokes a callback method to create a value that is bound to the specified key. /// </summary> /// <param name="key">The key to search for. key represents the object to which the property is attached.</param> /// <param name="createValueCallback">A delegate to a method that can create a value for the given key. It has a single parameter of type TKey, and returns a value of type TValue.</param> /// <returns>The value attached to key, if key already exists in the table; otherwise, the new value returned by the createValueCallback delegate.</returns> public TValue GetValue(TKey key, CreateValueCallback createValueCallback) { if (key == null) { throw new ArgumentNullException("key"); } if (createValueCallback == null) { throw new ArgumentNullException("createValueCallback"); } return(_wrapped.GetOrAdd(key, input => createValueCallback(input))); }
public static Func <T, R> memo <T, R>(Func <T, R> func) { var cache = new WeakDictionary <T, R>(); var syncMap = new ConcurrentDictionary <T, object>(); return(inp => cache.TryGetValue(inp).Match( some: x => x, none: () => { R res; var sync = syncMap.GetOrAdd(inp, new object()); lock (sync) { res = cache.GetOrAdd(inp, func); } syncMap.TryRemove(inp, out sync); return res; })); }
/// <summary> /// Returns a Func<T,R> that wraps func. Each time the resulting /// Func<T,R> is called with a new value, its result is memoized (cached). /// Subsequent calls use the memoized value. /// /// Remarks: /// Thread-safe and memory-leak safe. /// R is limited to reference types. /// </summary> public static Func <T, R> memo <T, R>(this Func <T, R> func) where R : class { var cache = new WeakDictionary <T, R>(); var syncMap = new ConcurrentDictionary <T, object>(); return(inp => { R res; if (!cache.TryGetValue(inp, out res)) { var sync = syncMap.GetOrAdd(inp, new object()); lock (sync) { res = cache.GetOrAdd(inp, func); } syncMap.TryRemove(inp, out sync); } return res; }); }
public object GetOrAdd(WeakDictionary <object, int, object> d, Tuple <object, int> k, Func <Tuple <object, int>, object> valueFactory) { return(d.GetOrAdd(k.Item1, k.Item2, (kp1, kp2) => valueFactory(Tuple.Create(kp1, kp2)))); }
public object GetOrAdd(WeakDictionary <object, int, object> d, Tuple <object, int> k, object v) { return(d.GetOrAdd(k.Item1, k.Item2, v)); }
public object GetOrAdd(WeakDictionary <int, object> d, int k, Func <int, object> valueFactory) { return(d.GetOrAdd(k, (kp1) => valueFactory(kp1))); }
public object GetOrAdd(WeakDictionary <int, object> d, int k, object v) { return(d.GetOrAdd(k, v)); }