/// <summary> /// Implement IReliableDictionary methods /// </summary> #region IReliableDictionary public async Task AddAsync(ITransaction tx, TKey key, TValue value, TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken)) { await LockManager.AcquireLock(BeginTransaction(tx).TransactionId, key, LockMode.Update, timeout, cancellationToken); if (!Dictionary.TryAdd(key, value)) { throw new ArgumentException("A value with the same key already exists.", nameof(value)); } AddAbortAction(tx, () => { Dictionary.TryRemove(key, out _); return(true); }); AddCommitAction(tx, () => { InternalDictionaryChanged?.Invoke(this, new DictionaryChangedEvent <TKey, TValue>(tx, ChangeType.Added, key, added: value)); return(true); }); }
public async Task <bool> TryUpdateAsync(ITransaction tx, TKey key, TValue newValue, TValue comparisonValue, TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken)) { var acquireResult = await LockManager.AcquireLock(BeginTransaction(tx).TransactionId, key, LockMode.Update, timeout, cancellationToken); var result = Dictionary.TryUpdate(key, newValue, comparisonValue); if (result) { AddAbortAction(tx, () => { Dictionary[key] = comparisonValue; return(true); }); AddCommitAction(tx, () => { InternalDictionaryChanged?.Invoke(this, new DictionaryChangedEvent <TKey, TValue>(tx, ChangeType.Updated, key, added: newValue, removed: comparisonValue)); return(true); }); } else if (acquireResult == AcquireResult.Acquired) { LockManager.ReleaseLock(tx.TransactionId, key); } return(result); }
public async Task <ConditionalValue <TValue> > TryRemoveAsync(ITransaction tx, TKey key, TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken)) { var acquireResult = await LockManager.AcquireLock(BeginTransaction(tx).TransactionId, key, LockMode.Update, timeout, cancellationToken); bool hasValue = Dictionary.TryRemove(key, out var value); if (hasValue) { AddAbortAction(tx, () => { Dictionary.TryAdd(key, value); return(true); }); AddCommitAction(tx, () => { InternalDictionaryChanged?.Invoke(this, new DictionaryChangedEvent <TKey, TValue>(tx, ChangeType.Removed, key, removed: value)); return(true); }); } else if (acquireResult == AcquireResult.Acquired) { LockManager.ReleaseLock(tx.TransactionId, key); } return(new ConditionalValue <TValue>(hasValue, value)); }
public async Task <TValue> AddOrUpdateAsync(ITransaction tx, TKey key, Func <TKey, TValue> addValueFactory, Func <TKey, TValue, TValue> updateValueFactory, TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken)) { await LockManager.AcquireLock(BeginTransaction(tx).TransactionId, key, LockMode.Update, timeout, cancellationToken); bool isUpdate = Dictionary.TryGetValue(key, out TValue oldValue); var newValue = Dictionary.AddOrUpdate(key, addValueFactory, updateValueFactory); if (isUpdate) { AddAbortAction(tx, () => { Dictionary[key] = oldValue; return(true); }); AddCommitAction(tx, () => { InternalDictionaryChanged?.Invoke(this, new DictionaryChangedEvent <TKey, TValue>(tx, ChangeType.Updated, key, added: newValue, removed: oldValue)); return(true); }); } else { AddAbortAction(tx, () => { Dictionary.TryRemove(key, out _); return(true); }); AddCommitAction(tx, () => { InternalDictionaryChanged?.Invoke(this, new DictionaryChangedEvent <TKey, TValue>(tx, ChangeType.Added, key, added: newValue)); return(true); }); } return(newValue); }
public async Task <TValue> GetOrAddAsync(ITransaction tx, TKey key, Func <TKey, TValue> valueFactory, TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken)) { var acquireResult = await LockManager.AcquireLock(BeginTransaction(tx).TransactionId, key, LockMode.Update, timeout, cancellationToken); if (Dictionary.TryGetValue(key, out var value)) { if (acquireResult == AcquireResult.Acquired) { LockManager.DowngradeLock(tx.TransactionId, key); } } else { value = valueFactory(key); Dictionary.TryAdd(key, value); AddAbortAction(tx, () => { Dictionary.TryRemove(key, out _); return(true); }); AddCommitAction(tx, () => { InternalDictionaryChanged?.Invoke(this, new DictionaryChangedEvent <TKey, TValue>(tx, ChangeType.Added, key, added: value)); return(true); }); } return(value); }
public async Task SetAsync(ITransaction tx, TKey key, TValue value, TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken)) { await LockManager.AcquireLock(BeginTransaction(tx).TransactionId, key, LockMode.Update, timeout, cancellationToken); bool oldValueExisted = Dictionary.TryGetValue(key, out TValue oldValue); Dictionary[key] = value; AddAbortAction(tx, () => { if (oldValueExisted) { Dictionary[key] = oldValue; } else { Dictionary.TryRemove(key, out _); } return(true); }); AddCommitAction(tx, () => { InternalDictionaryChanged?.Invoke(this, new DictionaryChangedEvent <TKey, TValue>(tx, ChangeType.Updated, key, added: value, removed: oldValue)); return(true); }); }