using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Text.RegularExpressions; using Umbraco.Extensions; namespace Umbraco.Cms.Core.Cache { /// /// Implements on top of a concurrent dictionary. /// public class DictionaryAppCache : IRequestCache { /// /// Gets the internal items dictionary, for tests only! /// private readonly ConcurrentDictionary _items = new ConcurrentDictionary(); public int Count => _items.Count; /// public bool IsAvailable => true; /// public virtual object? Get(string key) { return _items.TryGetValue(key, out var value) ? value : null; } /// public virtual object? Get(string key, Func factory) { return _items.GetOrAdd(key, _ => factory()); } public bool Set(string key, object value) => _items.TryAdd(key, value); public bool Remove(string key) => _items.TryRemove(key, out _); /// public virtual IEnumerable SearchByKey(string keyStartsWith) { var items = new List(); foreach (var (key, value) in _items) if (key.InvariantStartsWith(keyStartsWith)) items.Add(value); return items; } /// public IEnumerable SearchByRegex(string regex) { var compiled = new Regex(regex, RegexOptions.Compiled); var items = new List(); foreach (var (key, value) in _items) if (compiled.IsMatch(key)) items.Add(value); return items; } /// public virtual void Clear() { _items.Clear(); } /// public virtual void Clear(string key) { _items.TryRemove(key, out _); } /// public virtual void ClearOfType(Type type) { _items.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == type); } /// public virtual void ClearOfType() { var typeOfT = typeof(T); ClearOfType(typeOfT); } /// public virtual void ClearOfType(Func predicate) { var typeOfT = typeof(T); _items.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT && predicate(kvp.Key, (T)kvp.Value)); } /// public virtual void ClearByKey(string keyStartsWith) { _items.RemoveAll(kvp => kvp.Key.InvariantStartsWith(keyStartsWith)); } /// public virtual void ClearByRegex(string regex) { var compiled = new Regex(regex, RegexOptions.Compiled); _items.RemoveAll(kvp => compiled.IsMatch(kvp.Key)); } public IEnumerator> GetEnumerator() => _items.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } }