Example #1
0
        /// <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); });
        }
Example #2
0
        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);
        }
Example #3
0
        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));
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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); });
        }