public PendingValue(TKey key, MissingValueFactory <TKey, TValue> factory) { _key = key; _factory = factory ?? DefaultMissingValueFactory; _source = new TaskCompletionSource <TValue>(); }
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()); }
public PendingValue(TKey key, MissingValueFactory <TKey, TValue> factory) { _key = key; _factory = factory ?? DefaultMissingValueFactory; _value = new TaskCompletionSource <TValue>(TaskCreationOptions.RunContinuationsAsynchronously); }
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); }
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); } }