示例#1
0
        /// <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.
        /// </summary>
        public static Func <T, R> memo <T, R>(Func <T, R> func)
        {
            var cache   = new WeakDict <T, R>();
            var syncMap = new ConcurrentDictionary <T, object>();

            return(inp =>
                   matchUnsafe(cache.TryGetValue(inp),
                               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;
            }));
        }
示例#2
0
        /// <summary>
        /// Returns a `Func<A, B>` that wraps func.  Each time the resulting
        /// `Func<A, B>` is called with a new value, its result is memoized (cached).
        /// Subsequent calls use the memoized value.
        ///
        /// Remarks:
        ///     Thread-safe and memory-leak safe.
        /// </summary>
        public static Func <A, B> memo <A, B>(Func <A, B> func)
        {
            var cache   = new WeakDict <A, B> ();
            var syncMap = new ConcurrentDictionary <A, object>();

            return(inp =>
            {
                if (cache.TryGetValue(inp, out var x))
                {
                    return x;
                }
                else
                {
                    B res;
                    var sync = syncMap.GetOrAdd(inp, new object());
                    lock (sync)
                    {
                        res = cache.GetOrAdd(inp, func);
                    }
                    syncMap.TryRemove(inp, out sync);
                    return res;
                }
            });
        }