示例#1
0
        public static object Get(this IMemoryCache cache, string key, IEntryLink link)
        {
            object value = null;

            cache.TryGetValue(key, link, out value);
            return(value);
        }
示例#2
0
        // Internal for unit testing
        internal MemoryCacheEntryOptions GetMemoryCacheEntryOptions(IEntryLink entryLink)
        {
            var options = new MemoryCacheEntryOptions();

            if (ExpiresOn != null)
            {
                options.SetAbsoluteExpiration(ExpiresOn.Value);
            }

            if (ExpiresAfter != null)
            {
                options.SetAbsoluteExpiration(ExpiresAfter.Value);
            }

            if (ExpiresSliding != null)
            {
                options.SetSlidingExpiration(ExpiresSliding.Value);
            }

            if (Priority != null)
            {
                options.SetPriority(Priority.Value);
            }

            options.AddEntryLink(entryLink);
            return(options);
        }
        public static IDisposable FlowContext(this IEntryLink link)
        {
            var priorLink = ContextLink;

            ContextLink = link;
            return(new LinkContextReverter(priorLink));
        }
示例#4
0
 public static T Set <T>(this IMemoryCache cache, string key, IEntryLink link, object state, Func <ICacheSetContext, T> create)
 {
     return((T)cache.Set(key, link, state, context =>
     {
         return (object)create(context);
     }));
 }
        public object Set([NotNull] string key, IEntryLink link, object state, [NotNull] Func <ICacheSetContext, object> create)
        {
            CheckDisposed();
            CacheEntry priorEntry = null;
            var        now        = _clock.UtcNow;
            var        context    = new CacheSetContext(key)
            {
                State = state, CreationTime = now
            };
            object value = create(context);
            var    entry = new CacheEntry(context, value, _entryExpirationNotification);
            bool   added = false;

            if (link != null)
            {
                // Copy triggers and AbsoluteExpiration to the link.
                // We do this regardless of it gets cached because the triggers are associated with the value we'll return.
                if (entry.Context.Triggers != null)
                {
                    link.AddExpirationTriggers(entry.Context.Triggers);
                }
                if (entry.Context.AbsoluteExpiration.HasValue)
                {
                    link.SetAbsoluteExpiration(entry.Context.AbsoluteExpiration.Value);
                }
            }

            _entryLock.EnterWriteLock();
            try
            {
                if (_entries.TryGetValue(key, out priorEntry))
                {
                    _entries.Remove(key);
                    priorEntry.SetExpired(EvictionReason.Replaced);
                }

                if (!entry.CheckExpired(now))
                {
                    _entries[key] = entry;
                    entry.AttachTriggers();
                    added = true;
                }
            }
            finally
            {
                _entryLock.ExitWriteLock();
            }
            if (priorEntry != null)
            {
                priorEntry.InvokeEvictionCallbacks();
            }
            if (!added)
            {
                entry.InvokeEvictionCallbacks();
            }

            StartScanForExpiredItems();

            return(value);
        }
示例#6
0
        public static T Get <T>(this IMemoryCache cache, string key, IEntryLink link)
        {
            T value = default(T);

            cache.TryGetValue <T>(key, link, out value);
            return(value);
        }
示例#7
0
 public static T Set <T>(this IMemoryCache cache, string key, IEntryLink link, Func <ICacheSetContext, T> create)
 {
     return((T)cache.Set(key, link, create, context =>
     {
         var myCreate = (Func <ICacheSetContext, T>)context.State;
         return (object)myCreate(context);
     }));
 }
示例#8
0
        public static T GetOrSet <T>(this IMemoryCache cache, string key, IEntryLink link, object state, Func <ICacheSetContext, T> create)
        {
            T obj;

            if (cache.TryGetValue(key, link, out obj))
            {
                return(obj);
            }
            return(cache.Set(key, link, state, create));
        }
        public bool TryGetValue([NotNull] string key, IEntryLink link, out object value)
        {
            value = null;
            CacheEntry expiredEntry = null;
            bool       found        = false;

            CheckDisposed();
            _entryLock.EnterReadLock();
            try
            {
                CacheEntry entry;
                if (_entries.TryGetValue(key, out entry))
                {
                    // Check if expired due to triggers, timers, etc. and if so, remove it.
                    if (entry.CheckExpired(_clock.UtcNow))
                    {
                        expiredEntry = entry;
                    }
                    else
                    {
                        // Refresh sliding expiration, etc.
                        entry.LastAccessed = _clock.UtcNow;
                        value = entry.Value;
                        found = true;

                        if (link != null)
                        {
                            // Copy triggers and AbsoluteExpiration to the link
                            if (entry.Context.Triggers != null)
                            {
                                link.AddExpirationTriggers(entry.Context.Triggers);
                            }
                            if (entry.Context.AbsoluteExpiration.HasValue)
                            {
                                link.SetAbsoluteExpiration(entry.Context.AbsoluteExpiration.Value);
                            }
                        }
                    }
                }
            }
            finally
            {
                _entryLock.ExitReadLock();
            }

            if (expiredEntry != null)
            {
                // TODO: For efficiency queue this up for batch removal
                RemoveEntry(expiredEntry);
            }

            StartScanForExpiredItems();

            return(found);
        }
示例#10
0
        /// <summary>
        /// Adds inherited trigger and absolute expiration information.
        /// </summary>
        /// <param name="link"></param>
        public static void AddEntryLink(this ICacheSetContext context, IEntryLink link)
        {
            foreach (var trigger in link.Triggers)
            {
                context.AddExpirationTrigger(trigger);
            }

            if (link.AbsoluteExpiration.HasValue)
            {
                context.SetAbsoluteExpiration(link.AbsoluteExpiration.Value);
            }
        }
示例#11
0
        public static bool TryGetValue <T>(this IMemoryCache cache, string key, IEntryLink link, out T value)
        {
            object obj = null;

            if (cache.TryGetValue(key, link, out obj))
            {
                value = (T)obj;
                return(true);
            }
            value = default(T);
            return(false);
        }
示例#12
0
        public async Task <object> SetAsync([NotNull] string key, IEntryLink link, object state, [NotNull] Func <ICacheSetContext, Task <object> > create)
        {
            CheckDisposed();
            var context = new CacheSetContext(key)
            {
                State = state, CreationTime = _clock.UtcNow
            };
            object value = await create(context);

            SetInternal(context, link, value);

            return(value);
        }
        /// <summary>
        /// Adds inherited trigger and absolute expiration information.
        /// </summary>
        /// <param name="link"></param>
        public static MemoryCacheEntryOptions AddEntryLink(this MemoryCacheEntryOptions options, IEntryLink link)
        {
            foreach (var trigger in link.Triggers)
            {
                options.AddExpirationTrigger(trigger);
            }

            if (link.AbsoluteExpiration.HasValue)
            {
                options.SetAbsoluteExpiration(link.AbsoluteExpiration.Value);
            }
            return options;
        }
示例#14
0
        private void SetInternal(CacheSetContext context, IEntryLink link, object value)
        {
            CacheEntry priorEntry = null;
            var        entry      = new CacheEntry(context, value, _entryExpirationNotification);
            bool       added      = false;

            if (link != null)
            {
                // Copy triggers and AbsoluteExpiration to the link.
                // We do this regardless of it gets cached because the triggers are associated with the value we'll return.
                if (entry.Context.Triggers != null)
                {
                    link.AddExpirationTriggers(entry.Context.Triggers);
                }
                if (entry.Context.AbsoluteExpiration.HasValue)
                {
                    link.SetAbsoluteExpiration(entry.Context.AbsoluteExpiration.Value);
                }
            }

            _entryLock.EnterWriteLock();
            try
            {
                if (_entries.TryGetValue(context.Key, out priorEntry))
                {
                    _entries.Remove(context.Key);
                    priorEntry.SetExpired(EvictionReason.Replaced);
                }

                if (!entry.CheckExpired(context.CreationTime))
                {
                    _entries[context.Key] = entry;
                    entry.AttachTriggers();
                    added = true;
                }
            }
            finally
            {
                _entryLock.ExitWriteLock();
            }
            if (priorEntry != null)
            {
                priorEntry.InvokeEvictionCallbacks();
            }
            if (!added)
            {
                entry.InvokeEvictionCallbacks();
            }

            StartScanForExpiredItems();
        }
示例#15
0
        public void NestedLinkContextsCanAggregate()
        {
            var    clock = new TestClock();
            var    cache = CreateCache(clock);
            var    obj   = new object();
            string key2  = "myKey2";
            string key3  = "myKey3";

            var expirationToken2 = new TestExpirationToken()
            {
                ActiveChangeCallbacks = true
            };
            var expirationToken3 = new TestExpirationToken()
            {
                ActiveChangeCallbacks = true
            };

            IEntryLink link1 = null;
            IEntryLink link2 = null;

            using (link1 = cache.CreateLinkingScope())
            {
                cache.Set(key2, obj, new MemoryCacheEntryOptions()
                          .AddExpirationToken(expirationToken2)
                          .SetAbsoluteExpiration(TimeSpan.FromSeconds(10)));

                using (link2 = cache.CreateLinkingScope())
                {
                    cache.Set(key3, obj, new MemoryCacheEntryOptions()
                              .AddExpirationToken(expirationToken3)
                              .SetAbsoluteExpiration(TimeSpan.FromSeconds(15)));
                }
            }

            Assert.Equal(1, link1.ExpirationTokens.Count());
            Assert.NotNull(link1.AbsoluteExpiration);
            Assert.Equal(clock.UtcNow + TimeSpan.FromSeconds(10), link1.AbsoluteExpiration);

            Assert.Equal(1, link2.ExpirationTokens.Count());
            Assert.NotNull(link2.AbsoluteExpiration);
            Assert.Equal(clock.UtcNow + TimeSpan.FromSeconds(15), link2.AbsoluteExpiration);
        }
示例#16
0
 public static object Set(this IMemoryCache cache, string key, IEntryLink link, Func <ICacheSetContext, object> create)
 {
     return(cache.Set(key, link, state: null, create: create));
 }
示例#17
0
 public LinkContextReverter(IEntryLink priorLink)
 {
     _priorLink = priorLink;
 }
示例#18
0
 public static IDisposable FlowContext(this IEntryLink link)
 {
     var priorLink = ContextLink;
     ContextLink = link;
     return new LinkContextReverter(priorLink);
 }
示例#19
0
        public bool TryGetValue([NotNull] string key, IEntryLink link, out object value)
        {
            value = null;
            CacheEntry expiredEntry = null;
            bool found = false;
            CheckDisposed();
            _entryLock.EnterReadLock();
            try
            {
                CacheEntry entry;
                if (_entries.TryGetValue(key, out entry))
                {
                    // Check if expired due to triggers, timers, etc. and if so, remove it.
                    if (entry.CheckExpired(_clock.UtcNow))
                    {
                        expiredEntry = entry;
                    }
                    else
                    {
                        // Refresh sliding expiration, etc.
                        entry.LastAccessed = _clock.UtcNow;
                        value = entry.Value;
                        found = true;

                        if (link != null)
                        {
                            // Copy triggers and AbsoluteExpiration to the link
                            if (entry.Context.Triggers != null)
                            {
                                link.AddExpirationTriggers(entry.Context.Triggers);
                            }
                            if (entry.Context.AbsoluteExpiration.HasValue)
                            {
                                link.SetAbsoluteExpiration(entry.Context.AbsoluteExpiration.Value);
                            }
                        }
                    }
                }
            }
            finally
            {
                _entryLock.ExitReadLock();
            }

            if (expiredEntry != null)
            {
                // TODO: For efficiency queue this up for batch removal
                RemoveEntry(expiredEntry);
            }

            StartScanForExpiredItems();

            return found;
        }
示例#20
0
        public object Set([NotNull] string key, IEntryLink link, object state, [NotNull] Func<ICacheSetContext, object> create)
        {
            CheckDisposed();
            CacheEntry priorEntry = null;
            var now = _clock.UtcNow;
            var context = new CacheSetContext(key) { State = state, CreationTime = now };
            object value = create(context);
            var entry = new CacheEntry(context, value, _entryExpirationNotification);
            bool added = false;

            if (link != null)
            {
                // Copy triggers and AbsoluteExpiration to the link.
                // We do this regardless of it gets cached because the triggers are associated with the value we'll return.
                if (entry.Context.Triggers != null)
                {
                    link.AddExpirationTriggers(entry.Context.Triggers);
                }
                if (entry.Context.AbsoluteExpiration.HasValue)
                {
                    link.SetAbsoluteExpiration(entry.Context.AbsoluteExpiration.Value);
                }
            }

            _entryLock.EnterWriteLock();
            try
            {
                if (_entries.TryGetValue(key, out priorEntry))
                {
                    _entries.Remove(key);
                    priorEntry.SetExpired(EvictionReason.Replaced);
                }

                if (!entry.CheckExpired(now))
                {
                    _entries[key] = entry;
                    entry.AttachTriggers();
                    added = true;
                }
            }
            finally
            {
                _entryLock.ExitWriteLock();
            }
            if (priorEntry != null)
            {
                priorEntry.InvokeEvictionCallbacks();
            }
            if (!added)
            {
                entry.InvokeEvictionCallbacks();
            }

            StartScanForExpiredItems();

            return value;
        }
示例#21
0
 public LinkContextReverter(IEntryLink priorLink)
 {
     _priorLink = priorLink;
 }
示例#22
0
        /// <summary>
        /// Adds inherited trigger and absolute expiration information.
        /// </summary>
        /// <param name="link"></param>
        public static MemoryCacheEntryOptions AddEntryLink(this MemoryCacheEntryOptions options, IEntryLink link)
        {
            foreach (var trigger in link.Triggers)
            {
                options.AddExpirationTrigger(trigger);
            }

            if (link.AbsoluteExpiration.HasValue)
            {
                options.SetAbsoluteExpiration(link.AbsoluteExpiration.Value);
            }
            return(options);
        }
        /// <summary>
        /// Adds inherited token and absolute expiration information.
        /// </summary>
        /// <param name="link"></param>
        public static MemoryCacheEntryOptions AddEntryLink(this MemoryCacheEntryOptions options, IEntryLink link)
        {
            foreach (var expirationToken in link.ExpirationTokens)
            {
                options.AddExpirationToken(expirationToken);
            }

            if (link.AbsoluteExpiration.HasValue)
            {
                options.SetAbsoluteExpiration(link.AbsoluteExpiration.Value);
            }
            return options;
        }
示例#24
0
        // Internal for unit testing
        internal MemoryCacheEntryOptions GetMemoryCacheEntryOptions(IEntryLink entryLink)
        {
            var options = new MemoryCacheEntryOptions();
            if (ExpiresOn != null)
            {
                options.SetAbsoluteExpiration(ExpiresOn.Value);
            }

            if (ExpiresAfter != null)
            {
                options.SetAbsoluteExpiration(ExpiresAfter.Value);
            }

            if (ExpiresSliding != null)
            {
                options.SetSlidingExpiration(ExpiresSliding.Value);
            }

            if (Priority != null)
            {
                options.SetPriority(Priority.Value);
            }

            options.AddEntryLink(entryLink);
            return options;
        }
 public static CatalogueItemFacade ToFacade(this IEntryLink entryLink)
 {
     return(new CatalogueItemFacade(entryLink, CatalogueItemKind.Entry, () => entryLink.Target.Name, isLink: true));
 }
示例#26
0
        /// <summary>
        /// Adds inherited token and absolute expiration information.
        /// </summary>
        /// <param name="link"></param>
        public static MemoryCacheEntryOptions AddEntryLink(this MemoryCacheEntryOptions options, IEntryLink link)
        {
            foreach (var expirationToken in link.ExpirationTokens)
            {
                options.AddExpirationToken(expirationToken);
            }

            if (link.AbsoluteExpiration.HasValue)
            {
                options.SetAbsoluteExpiration(link.AbsoluteExpiration.Value);
            }
            return(options);
        }
示例#27
0
 public static async Task <T> SetAsync <T>(this IMemoryCache cache, string key, IEntryLink link, object state, Func <ICacheSetContext, Task <T> > create)
 {
     return((T)await cache.SetAsync(key, link, state, async context =>
     {
         return (object)await create(context);
     }));
 }