Beispiel #1
0
        public PendingValue(TKey key, MissingValueFactory <TKey, TValue> factory)
        {
            _key     = key;
            _factory = factory ?? DefaultMissingValueFactory;

            _source = new TaskCompletionSource <TValue>();
        }
Beispiel #2
0
        public Task <TValue> GetOrAdd(TKey key, MissingValueFactory <TKey, TValue> missingValueFactory)
        {
            if (TryGetValue(key, out var cacheValue))
            {
                return(cacheValue.HasValue
                    ? cacheValue.Value
                    : cacheValue.GetValue(() => new PendingValue <TKey, TValue>(key, missingValueFactory)));
            }

            void RemoveValue()
            {
                _values.TryRemove(key, out _);
            }

            cacheValue = _policy.CreateValue(RemoveValue);

            if (!_values.TryAdd(key, cacheValue))
            {
                return(GetOrAdd(key, missingValueFactory));
            }

            _metrics.Miss();

            async Task <TValue> Added()
            {
                await _tracker.Add(cacheValue).ConfigureAwait(false);

                return(await cacheValue.GetValue(() => new PendingValue <TKey, TValue>(key, missingValueFactory)).ConfigureAwait(false));
            }

            return(Added());
        }
Beispiel #3
0
        public PendingValue(TKey key, MissingValueFactory <TKey, TValue> factory)
        {
            _key     = key;
            _factory = factory ?? DefaultMissingValueFactory;

            _value = new TaskCompletionSource <TValue>(TaskCreationOptions.RunContinuationsAsynchronously);
        }
Beispiel #4
0
        public IIndex <TKey, TValue> AddIndex <TKey>(string indexName, KeyProvider <TKey, TValue> keyProvider,
                                                     MissingValueFactory <TKey, TValue> missingValueFactory = null)
        {
            if (_indices.ContainsKey(indexName))
            {
                throw new ArgumentException($"An index with the same name was already added: {indexName}", nameof(indexName));
            }

            var index = new Index <TKey, TValue>(_nodeTracker, keyProvider);

            _indices[indexName] = index;

            return(index);
        }
Beispiel #5
0
        public Task <TValue> Get(TKey key, MissingValueFactory <TKey, TValue> missingValueFactory)
        {
            lock (_lock)
            {
                INode <TValue> existingNode;
                if (TryGetExistingNode(key, out existingNode))
                {
                    if (existingNode.HasValue)
                    {
                        _nodeTracker.Statistics.Hit();
                        return(existingNode.Value);
                    }

                    var pending = new PendingValue <TKey, TValue>(key, missingValueFactory);

                    return(existingNode.GetValue(pending));
                }

                if (missingValueFactory == null)
                {
                    _nodeTracker.Statistics.Miss();
                    throw new KeyNotFoundException($"Key not found: {key}");
                }

                var pendingValue = new PendingValue <TKey, TValue>(key, missingValueFactory);

                var nodeValueFactory = new NodeValueFactory <TValue>(pendingValue, 0);

                var node = new FactoryNode <TValue>(nodeValueFactory);

                _index[key] = new WeakReference <INode <TValue> >(node, false);

                _nodeTracker.Add(nodeValueFactory);

                return(pendingValue.Value);
            }
        }