/// <inheritdoc /> public void ClearOfType(string typeName) { var type = TypeFinder.GetTypeByName(typeName); if (type == null) { return; } var isInterface = type.IsInterface; foreach (var kvp in Items .Where(x => { // entry.Value is Lazy<object> and not null, its value may be null // remove null values as well, does not hurt // get non-created as NonCreatedValue & exceptions as null var value = FastDictionaryAppCacheBase.GetSafeLazyValue(x.Value, true); // if T is an interface remove anything that implements that interface // otherwise remove exact types (not inherited types) return(value == null || (isInterface ? (type.IsInstanceOfType(value)) : (value.GetType() == type))); })) { Items.TryRemove(kvp.Key, out _); } }
/// <inheritdoc /> public virtual void ClearOfType <T>() { try { _locker.EnterWriteLock(); var typeOfT = typeof(T); var isInterface = typeOfT.IsInterface; foreach (var key in MemoryCache .Where(x => { // x.Value is Lazy<object> and not null, its value may be null // remove null values as well, does not hurt // get non-created as NonCreatedValue & exceptions as null var value = FastDictionaryAppCacheBase.GetSafeLazyValue((Lazy <object>)x.Value, true); // if T is an interface remove anything that implements that interface // otherwise remove exact types (not inherited types) return(value == null || (isInterface ? (value is T) : (value.GetType() == typeOfT))); }) .Select(x => x.Key) .ToArray()) // ToArray required to remove { MemoryCache.Remove(key); } } finally { if (_locker.IsWriteLockHeld) { _locker.ExitWriteLock(); } } }
/// <inheritdoc /> public object Get(string key, Func <object> factory, TimeSpan?timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null) { // see notes in HttpRuntimeAppCache Lazy <object> result; using (var lck = new UpgradeableReadLock(_locker)) { result = MemoryCache.Get(key) as Lazy <object>; if (result == null || FastDictionaryAppCacheBase.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null { result = FastDictionaryAppCacheBase.GetSafeLazy(factory); var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles); lck.UpgradeToWriteLock(); //NOTE: This does an add or update MemoryCache.Set(key, result, policy); } } //return result.Value; var value = result.Value; // will not throw (safe lazy) if (value is FastDictionaryAppCacheBase.ExceptionHolder eh) { eh.Exception.Throw(); // throw once! } return(value); }
/// <inheritdoc /> public IEnumerable <object> SearchByKey(string keyStartsWith) { return(Items .Where(kvp => kvp.Key.InvariantStartsWith(keyStartsWith)) .Select(kvp => FastDictionaryAppCacheBase.GetSafeLazyValue(kvp.Value)) .Where(x => x != null)); }
/// <inheritdoc /> public void ClearOfType <T>(Func <string, T, bool> predicate) { var typeOfT = typeof(T); var isInterface = typeOfT.IsInterface; foreach (var kvp in Items .Where(x => { // entry.Value is Lazy<object> and not null, its value may be null // remove null values as well, does not hurt // compare on exact type, don't use "is" // get non-created as NonCreatedValue & exceptions as null var value = FastDictionaryAppCacheBase.GetSafeLazyValue(x.Value, true); if (value == null) { return(true); } // if T is an interface remove anything that implements that interface // otherwise remove exact types (not inherited types) return((isInterface ? (value is T) : (value.GetType() == typeOfT)) // run predicate on the 'public key' part only, ie without prefix && predicate(x.Key, (T)value)); })) { Items.TryRemove(kvp.Key, out _); } }
/// <inheritdoc /> public IEnumerable <object> SearchByRegex(string regex) { var compiled = new Regex(regex, RegexOptions.Compiled); return(Items .Where(kvp => compiled.IsMatch(kvp.Key)) .Select(kvp => FastDictionaryAppCacheBase.GetSafeLazyValue(kvp.Value)) .Where(x => x != null)); }
/// <inheritdoc /> public void Insert(string key, Func <object> factory, TimeSpan?timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null) { InnerCache.Insert(key, () => { var result = FastDictionaryAppCacheBase.GetSafeLazy(factory); var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache // do not store null values (backward compat), clone / reset to go into the cache return(value == null ? null : CheckCloneableAndTracksChanges(value)); }, timeout, isSliding, priority, removedCallback, dependentFiles); }
/// <inheritdoc /> public object Get(string key, Func <object> factory) { var cached = InnerCache.Get(key, () => { var result = FastDictionaryAppCacheBase.GetSafeLazy(factory); var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache // do not store null values (backward compat), clone / reset to go into the cache return(value == null ? null : CheckCloneableAndTracksChanges(value)); }); return(CheckCloneableAndTracksChanges(cached)); }
/// <inheritdoc /> public void Insert(string key, Func <object> factory, TimeSpan?timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null) { // NOTE - here also we must insert a Lazy<object> but we can evaluate it right now // and make sure we don't store a null value. var result = FastDictionaryAppCacheBase.GetSafeLazy(factory); var value = result.Value; // force evaluation now if (value == null) { return; // do not store null values (backward compat) } var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles); //NOTE: This does an add or update MemoryCache.Set(key, result, policy); }
/// <inheritdoc /> public object Get(string key) { Lazy <object> result; try { _locker.EnterReadLock(); result = MemoryCache.Get(key) as Lazy <object>; // null if key not found } finally { if (_locker.IsReadLockHeld) { _locker.ExitReadLock(); } } return(result == null ? null : FastDictionaryAppCacheBase.GetSafeLazyValue(result)); // return exceptions as null }
/// <inheritdoc /> public object Get(string cacheKey, Func <object> getCacheItem) { var result = Items.GetOrAdd(cacheKey, k => FastDictionaryAppCacheBase.GetSafeLazy(getCacheItem)); var value = result.Value; // will not throw (safe lazy) if (!(value is FastDictionaryAppCacheBase.ExceptionHolder eh)) { return(value); } // and... it's in the cache anyway - so contrary to other cache providers, // which would trick with GetSafeLazyValue, we need to remove by ourselves, // in order NOT to cache exceptions Items.TryRemove(cacheKey, out result); eh.Exception.Throw(); // throw once! return(null); // never reached }
/// <inheritdoc /> public IEnumerable <object> SearchByKey(string keyStartsWith) { KeyValuePair <string, object>[] entries; try { _locker.EnterReadLock(); entries = MemoryCache .Where(x => x.Key.InvariantStartsWith(keyStartsWith)) .ToArray(); // evaluate while locked } finally { if (_locker.IsReadLockHeld) { _locker.ExitReadLock(); } } return(entries .Select(x => FastDictionaryAppCacheBase.GetSafeLazyValue((Lazy <object>)x.Value)) // return exceptions as null .Where(x => x != null) // backward compat, don't store null values in the cache .ToList()); }
/// <inheritdoc /> public IEnumerable <object> SearchByRegex(string regex) { var compiled = new Regex(regex, RegexOptions.Compiled); KeyValuePair <string, object>[] entries; try { _locker.EnterReadLock(); entries = MemoryCache .Where(x => compiled.IsMatch(x.Key)) .ToArray(); // evaluate while locked } finally { if (_locker.IsReadLockHeld) { _locker.ExitReadLock(); } } return(entries .Select(x => FastDictionaryAppCacheBase.GetSafeLazyValue((Lazy <object>)x.Value)) // return exceptions as null .Where(x => x != null) // backward compat, don't store null values in the cache .ToList()); }
/// <inheritdoc /> public object Get(string cacheKey) { Items.TryGetValue(cacheKey, out var result); // else null return(result == null ? null : FastDictionaryAppCacheBase.GetSafeLazyValue(result)); // return exceptions as null }