简体   繁体   中英

How is this cache manager storing the cached data?

I am using this cache manager, taken from bbarry on github .

I don't understand where or how the cached data is actually being stored. Most caching I've seen uses MemoryCache , but I don't see a mention of this anywhere.

I can only think that the ConcurrentDictionary is storing the cached data, but if so, I don't understand why this is a set to readonly .

public static class Cache<T> {
    static readonly ConcurrentDictionary<string, T> Dictionary = new ConcurrentDictionary<string, T>();

    //by making this a tuple with the generic constraint, there will be one per cache type; the first parameter will always be the default value
    static readonly ConcurrentDictionary<string, Tuple<T, DateTime, TimeSpan>> Removals = new ConcurrentDictionary<string, Tuple<T, DateTime, TimeSpan>>();


    public static T GetOrAdd(string key, Func<string, T> creator) { return GetOrAdd(key, creator, null, null); }


    public static T GetOrAdd(string key, Func<string, T> creator, DateTime absoluteExpiration) { return GetOrAdd(key, creator, absoluteExpiration, null); }


    public static T GetOrAdd(string key, Func<string, T> creator, TimeSpan slidingExpiration) { return GetOrAdd(key, creator, null, slidingExpiration); }


    public static bool TryGetValue(string key, out T value) {
        Tuple<T, DateTime, TimeSpan> when;
        if (Removals.TryGetValue(key, out when) && when.Item3 != TimeSpan.Zero) {
            Remove(key, Tuple.Create(default(T), DateTime.Now.Add(when.Item3), when.Item3));
        }
        return Dictionary.TryGetValue(key, out value); 
    }


    public static bool Expire(string key, out T value) { return Dictionary.TryRemove(key, out value); }


    public static void Expire(string key) {
        T value;
        Dictionary.TryRemove(key, out value);
    }

    static T GetOrAdd(string key, Func<string, T> creator, DateTime? absoluteExpiration, TimeSpan? slidingExpiration) {
        if (key == null) {
            throw new ArgumentNullException("key");
        }
        Tuple<T, DateTime, TimeSpan> when;
        var updateRemoval = Removals.TryGetValue(key, out when) && when.Item3 != TimeSpan.Zero;
        var v = Dictionary.GetOrAdd(key, creator);
        if (absoluteExpiration == null && slidingExpiration == null && !updateRemoval) {
            return v;
        }
        if (absoluteExpiration != null || slidingExpiration != null) {
            var expiration = (TimeSpan)(slidingExpiration ?? (absoluteExpiration - DateTime.Now));
            when = Tuple.Create(default(T), DateTime.Now.Add(expiration), expiration);
        } else {
            when = Tuple.Create(default(T), DateTime.Now.Add(when.Item3), when.Item3);
        }
        if (absoluteExpiration != null) {
            Removals.TryAdd(key, Tuple.Create(default(T), (DateTime)absoluteExpiration, TimeSpan.Zero));
        } else {
            Removals.AddOrUpdate(key, when, (a, b) => when);
        }

        Remove(key, when);
        return v;
    }

    static void Remove(string key, Tuple<T, DateTime, TimeSpan> then) {
        System.Threading.Tasks.Task.Delay(then.Item3).ContinueWith(task => {
            Tuple<T, DateTime, TimeSpan> when;
            if (!Removals.TryGetValue(key, out when) || when.Item2 >= DateTime.Now)
                return;
            T v;
            Dictionary.TryRemove(key, out v);
            Removals.TryRemove(key, out when);
        });
    }
}

The readonly modifier doesn't mean that you can't modify a collection which was marked with it ( ConcurrentDictionary<string, T> Dictionary in this case).

It only means that you can't reassign its value. So in this example you can't do

Dictionary = new ConcurrentDictionary<string, T>();

again. The documentation for readonly (linked above) lists the possible places where a field marked as readonly can be assigned. In constructor or static constructor or field declaration.

And the answer to your question is yes, it's the ConcurrentDictionary which stores the data in this case. ( GetOrAdd method).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM