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);
        }
Example #2
0
 internal CacheEntry(CacheSetContext context, object value, Action<CacheEntry> notifyCacheOfExpiration)
 {
     Context = context;
     Value = value;
     _notifyCacheOfExpiration = notifyCacheOfExpiration;
     LastAccessed = context.CreationTime;
 }
Example #3
0
 internal CacheEntry(CacheSetContext context, object value, Action <CacheEntry> notifyCacheOfExpiration)
 {
     Context = context;
     Value   = value;
     _notifyCacheOfExpiration = notifyCacheOfExpiration;
     LastAccessed             = context.CreationTime;
 }
Example #4
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);
        }
Example #5
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();
        }