Пример #1
0
        /// <summary>
        /// Memoizer with two parameters, used to perform a lazy-cached evaluation. (see http://en.wikipedia.org/wiki/Memoization)
        /// </summary>
        /// <typeparam name="T">The return type to memoize</typeparam>
        /// <param name="func">the function to evaluate</param>
        /// <returns>A memoized value</returns>
        public static Func <TArg1, TArg2, TResult> AsLockedMemoized <TArg1, TArg2, TResult>(this Func <TArg1, TArg2, TResult> func)
        {
#if XAMARIN
            // On Xamarin.iOS, the SynchronizedDictionary type costs a lot in terms of
            // generic delegates, where trampolines are used a lot. As simple lock will not create that
            // much contention for now.

            var values = new Dictionary <CachedTuple <TArg1, TArg2>, TResult>(CachedTuple <TArg1, TArg2> .Comparer);

            return((arg1, arg2) =>
            {
                var tuple = CachedTuple.Create(arg1, arg2);

                lock (values)
                {
                    return values.FindOrCreate(
                        tuple,
                        () => func(tuple.Item1, tuple.Item2)
                        );
                }
            });
#elif !HAS_NO_CONCURRENT_DICT
            var values = new ConcurrentDictionary <CachedTuple <TArg1, TArg2>, TResult>(CachedTuple <TArg1, TArg2> .Comparer);

            return((arg1, arg2) =>
            {
                var tuple = CachedTuple.Create(arg1, arg2);

                return values.GetOrAdd(
                    tuple,

                    // Use the parameter to avoid closure heap allocation
                    k => func(k.Item1, k.Item2)
                    );
            });
#else
            var values = new SynchronizedDictionary <Tuple <TArg1, TArg2>, TResult>();

            return((arg1, arg2) =>
            {
                TResult value = default(TResult);

                var tuple = Tuple.Create(arg1, arg2);

                values.Lock.Write(
                    v => v.TryGetValue(tuple, out value),
                    v => value = values[tuple] = func(arg1, arg2)
                    );

                return value;
            });
#endif
        }
Пример #2
0
        /// <summary>
        /// Memoizer with four parameters, used to perform a lazy-cached evaluation. (see http://en.wikipedia.org/wiki/Memoization)
        /// </summary>
        /// <typeparam name="T">The return type to memoize</typeparam>
        /// <param name="func">the function to evaluate</param>
        /// <returns>A memoized value</returns>
        public static Func <TArg1, TArg2, TArg3, TArg4, TResult> AsLockedMemoized <TArg1, TArg2, TArg3, TArg4, TResult>(this Func <TArg1, TArg2, TArg3, TArg4, TResult> func)
        {
#if XAMARIN
            var values = new Dictionary <CachedTuple <TArg1, TArg2, TArg3, TArg4>, TResult>(CachedTuple <TArg1, TArg2, TArg3, TArg4> .Comparer);

            return((arg1, arg2, arg3, arg4) =>
            {
                var tuple = CachedTuple.Create(arg1, arg2, arg3, arg4);

                lock (values)
                {
                    return values.FindOrCreate(
                        tuple,

                        // Use the parameter to avoid closure heap allocation
                        () => func(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4)
                        );
                }
            });
#elif !HAS_NO_CONCURRENT_DICT
            var values = new ConcurrentDictionary <CachedTuple <TArg1, TArg2, TArg3, TArg4>, TResult>(CachedTuple <TArg1, TArg2, TArg3, TArg4> .Comparer);

            return((arg1, arg2, arg3, arg4) =>
            {
                var tuple = CachedTuple.Create(arg1, arg2, arg3, arg4);

                return values.GetOrAdd(
                    tuple,

                    // Use the parameter to avoid closure heap allocation
                    k => func(k.Item1, k.Item2, k.Item3, k.Item4)
                    );
            });
#else
            var values = new SynchronizedDictionary <Tuple <TArg1, TArg2, TArg3, TArg4>, TResult>();

            return((arg1, arg2, arg3, arg4) =>
            {
                TResult value = default(TResult);

                var tuple = new Tuple <TArg1, TArg2, TArg3, TArg4>(arg1, arg2, arg3, arg4);

                values.Lock.Write(
                    v => v.TryGetValue(tuple, out value),
                    v => value = values[tuple] = func(arg1, arg2, arg3, arg4)
                    );

                return value;
            });
#endif
        }
Пример #3
0
        /// <summary>
        /// Memoizer with two parameters, used to perform a lazy-cached evaluation. (see http://en.wikipedia.org/wiki/Memoization)
        /// </summary>
        /// <typeparam name="TParam1">The first parameter type to memoize</typeparam>
        /// <typeparam name="TParam2">The second parameter type to memoize</typeparam>
        /// <param name="func">the function to evaluate</param>
        /// <returns>A memoized value</returns>
        public static Func <TParam1, TParam2, TResult> AsMemoized <TParam1, TParam2, TResult>(this Func <TParam1, TParam2, TResult> func)
        {
            Dictionary <CachedTuple <TParam1, TParam2>, TResult> values = new Dictionary <CachedTuple <TParam1, TParam2>, TResult>(CachedTuple <TParam1, TParam2> .Comparer);

            return((arg1, arg2) =>
            {
                var tuple = CachedTuple.Create(arg1, arg2);
                TResult value;

                if (!values.TryGetValue(tuple, out value))
                {
                    value = values[tuple] = func(arg1, arg2);
                }

                return value;
            });
        }
Пример #4
0
 public int GetHashCode(CachedTuple <T1, T2> obj)
 {
     return(obj._cachedHashCode);
 }
Пример #5
0
 public bool Equals(CachedTuple <T1, T2> x, CachedTuple <T1, T2> y)
 {
     return(InternalEquals(x, y));
 }