这个缓存管理器如何存储缓存数据?
How is this cache manager storing the cached data?
我正在使用 this cache manager, taken from bbarry on github。
我不明白缓存数据实际存储在何处或如何存储。我见过的大多数缓存都使用 MemoryCache
,但我在任何地方都看不到这一点。
我只能认为ConcurrentDictionary
存储的是缓存数据,但如果是这样,我不明白为什么要设置为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);
});
}
}
我正在使用 this cache manager, taken from bbarry on github。
我不明白缓存数据实际存储在何处或如何存储。我见过的大多数缓存都使用 MemoryCache
,但我在任何地方都看不到这一点。
我只能认为ConcurrentDictionary
存储的是缓存数据,但如果是这样,我不明白为什么要设置为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);
});
}
}