Beispiel #1
0
        public async Task SetCachedItemAsync(string key, byte[] value, TimeSpan?slidingExpiration, DateTimeOffset?absoluteExpiration)
        {
            if (slidingExpiration.HasValue)
            {
                var now = _systemClock.UtcNow;
                absoluteExpiration = now.AddMilliseconds(slidingExpiration.Value.TotalMilliseconds);
            }

            var cacheStore = await StateManager.GetOrAddAsync <IReliableDictionary <string, CachedItem> >(CacheStoreName);

            var cacheStoreMetadata = await StateManager.GetOrAddAsync <IReliableDictionary <string, CacheStoreMetadata> >(CacheStoreMetadataName);

            await RetryHelper.ExecuteWithRetry(StateManager, async (tx, cancellationToken, state) =>
            {
                _log?.Invoke($"Set cached item called with key: {key} on partition id: {Partition?.PartitionInfo.Id}");

                Func <string, Task <ConditionalValue <CachedItem> > > getCacheItem = async(string cacheKey) => await cacheStore.TryGetValueAsync(tx, cacheKey, LockMode.Update);
                var linkedDictionaryHelper = new LinkedDictionaryHelper(getCacheItem, ByteSizeOffset);

                var cacheStoreInfo    = (await cacheStoreMetadata.TryGetValueAsync(tx, CacheStoreMetadataKey, LockMode.Update)).Value ?? new CacheStoreMetadata(0, null, null);
                var existingCacheItem = (await getCacheItem(key)).Value;
                var cachedItem        = ApplyAbsoluteExpiration(existingCacheItem, absoluteExpiration) ?? new CachedItem(value, null, null, slidingExpiration, absoluteExpiration);

                // empty linked dictionary
                if (cacheStoreInfo.FirstCacheKey == null)
                {
                    var metadata = new CacheStoreMetadata(value.Length + ByteSizeOffset, key, key);
                    await cacheStoreMetadata.SetAsync(tx, CacheStoreMetadataKey, metadata);
                    await cacheStore.SetAsync(tx, key, cachedItem);
                }
                else
                {
                    var cacheMetadata = cacheStoreInfo;

                    // linked node already exists in dictionary
                    if (existingCacheItem != null)
                    {
                        var removeResult = await linkedDictionaryHelper.Remove(cacheStoreInfo, cachedItem);
                        cacheMetadata    = removeResult.CacheStoreMetadata;
                        await ApplyChanges(tx, cacheStore, cacheStoreMetadata, removeResult);
                    }

                    // add to last
                    var addLastResult = await linkedDictionaryHelper.AddLast(cacheMetadata, key, cachedItem, value);
                    await ApplyChanges(tx, cacheStore, cacheStoreMetadata, addLastResult);
                }
            });
        }
Beispiel #2
0
        public async Task <LinkedDictionaryItemsChanged> Remove(CacheStoreMetadata cacheStoreMetadata, CachedItem cachedItem)
        {
            var before = cachedItem.BeforeCacheKey;
            var after  = cachedItem.AfterCacheKey;
            var size   = (cacheStoreMetadata.Size - cachedItem.Value.Length) - _byteSizeOffset;

            // only item in linked dictionary
            if (before == null && after == null)
            {
                return(new LinkedDictionaryItemsChanged(new Dictionary <string, CachedItem>(), new CacheStoreMetadata(size, null, null)));
            }

            // first item in linked dictionary
            if (before == null)
            {
                var afterCachedItem = (await _getCacheItem(after)).Value;
                var newCachedItem   = new Dictionary <string, CachedItem> {
                    { after, new CachedItem(afterCachedItem.Value, null, afterCachedItem.AfterCacheKey, afterCachedItem.SlidingExpiration, afterCachedItem.AbsoluteExpiration) }
                };
                return(new LinkedDictionaryItemsChanged(newCachedItem, new CacheStoreMetadata(size, after, cacheStoreMetadata.LastCacheKey)));
            }

            // last item in linked dictionary
            if (after == null)
            {
                var beforeCachedItem = (await _getCacheItem(before)).Value;
                var newCachedItem    = new Dictionary <string, CachedItem> {
                    { before, new CachedItem(beforeCachedItem.Value, beforeCachedItem.BeforeCacheKey, null, beforeCachedItem.SlidingExpiration, beforeCachedItem.AbsoluteExpiration) }
                };
                return(new LinkedDictionaryItemsChanged(newCachedItem, new CacheStoreMetadata(size, cacheStoreMetadata.FirstCacheKey, before)));
            }

            // middle item in linked dictionary

            var beforeItem = (await _getCacheItem(before)).Value;
            var afterItem  = (await _getCacheItem(after)).Value;

            var metadata = new CacheStoreMetadata(size, cacheStoreMetadata.FirstCacheKey, cacheStoreMetadata.LastCacheKey);

            var newCachedItems = new Dictionary <string, CachedItem>();

            // add new before cached item
            newCachedItems.Add(before, new CachedItem(beforeItem.Value, beforeItem.BeforeCacheKey, after, beforeItem.SlidingExpiration, beforeItem.AbsoluteExpiration));
            // add new after cached item
            newCachedItems.Add(after, new CachedItem(afterItem.Value, before, afterItem.AfterCacheKey, afterItem.SlidingExpiration, afterItem.AbsoluteExpiration));

            return(new LinkedDictionaryItemsChanged(newCachedItems, metadata));
        }
Beispiel #3
0
        public async Task <LinkedDictionaryItemsChanged> AddLast(CacheStoreMetadata cacheStoreMetadata, string cacheItemKey, CachedItem cachedItem, byte[] newValue)
        {
            var cachedDictionary = new Dictionary <string, CachedItem>();
            var firstCacheKey    = cacheItemKey;

            // set current last item to be the second from last
            if (cacheStoreMetadata.LastCacheKey != null)
            {
                var currentLastCacheItem = (await _getCacheItem(cacheStoreMetadata.LastCacheKey)).Value;
                firstCacheKey = cacheStoreMetadata.FirstCacheKey;
                cachedDictionary.Add(cacheStoreMetadata.LastCacheKey, new CachedItem(currentLastCacheItem.Value, currentLastCacheItem.BeforeCacheKey, cacheItemKey, currentLastCacheItem.SlidingExpiration, currentLastCacheItem.AbsoluteExpiration));
            }

            // set new cached item to be last item in list
            cachedDictionary.Add(cacheItemKey, new CachedItem(newValue, cacheStoreMetadata.LastCacheKey, null, cachedItem.SlidingExpiration, cachedItem.AbsoluteExpiration));

            // calculate size of new collection
            var size = (cacheStoreMetadata.Size + newValue.Length) + _byteSizeOffset;

            // set new last item in the metadata
            var newCacheStoreMetadata = new CacheStoreMetadata(size, firstCacheKey, cacheItemKey);

            return(new LinkedDictionaryItemsChanged(cachedDictionary, newCacheStoreMetadata));
        }
Beispiel #4
0
 public LinkedDictionaryItemsChanged(Dictionary <string, CachedItem> cachedItemsToUpdate, CacheStoreMetadata cacheStoreMetadata)
 {
     CachedItemsToUpdate = cachedItemsToUpdate;
     CacheStoreMetadata  = cacheStoreMetadata;
 }