using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Runtime.Caching; using Umbraco.Core.Models.EntityBase; namespace Umbraco.Core.Persistence.Caching { /// /// The Runtime Cache provider looks up objects in the Runtime cache for fast retrival /// internal sealed class RuntimeCacheProvider : IRepositoryCacheProvider { #region Singleton private static readonly Lazy lazy = new Lazy(() => new RuntimeCacheProvider()); public static RuntimeCacheProvider Current { get { return lazy.Value; } } private RuntimeCacheProvider() { } #endregion private readonly ObjectCache _memoryCache = new MemoryCache("in-memory"); //TODO Save this in cache as well, so its not limited to a single server usage private ConcurrentDictionary _keyTracker = new ConcurrentDictionary(); public IEntity GetById(Type type, Guid id) { var key = GetCompositeId(type, id); var item = _memoryCache.Get(key); return item as IEntity; } public IEnumerable GetByIds(Type type, List ids) { foreach (var guid in ids) { yield return _memoryCache.Get(GetCompositeId(type, guid)) as IEntity; } } public IEnumerable GetAllByType(Type type) { foreach (var key in _keyTracker.Keys) { if (key.StartsWith(type.Name)) { yield return _memoryCache.Get(key) as IEntity; } } } public void Save(Type type, IEntity entity) { var key = GetCompositeId(type, entity.Key); var exists = _memoryCache.GetCacheItem(key) != null; _keyTracker.TryAdd(key, key); if (exists) { _memoryCache.Set(key, entity, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(5) }); return; } _memoryCache.Add(key, entity, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(5) }); } public void Delete(Type type, IEntity entity) { string throwaway = null; var key = GetCompositeId(type, entity.Key); var keyBeSure = _keyTracker.TryGetValue(key, out throwaway); object itemRemoved = _memoryCache.Remove(key); _keyTracker.TryRemove(key, out throwaway); } private string GetCompositeId(Type type, Guid id) { return string.Format("{0}-{1}", type.Name, id.ToString()); } } }