Esempio n. 1
0
        public TValue AddOrUpdate(TKey key, TValue addValue, Func <TKey, TValue, TValue> updateValueFactory, out bool added)
        {
            if (ReferenceEquals(updateValueFactory, null))
            {
                throw new ArgumentNullException("updateValueFactory");
            }
            TNeedle needle = PrivateGetNeedle(key);
            Func <TNeedle, TValue, TValue> factory = (pairKey, foundValue) =>
            {
                TKey foundKey;
                if (PrivateTryGetValue(pairKey, out foundKey))
                {
                    return(updateValueFactory(foundKey, foundValue));
                }
                return(addValue);
            };
            var result = _wrapped.AddOrUpdate
                         (
                needle,
                addValue,
                factory,
                out added
                         );

            if (!added)
            {
                NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);
            }
            return(result);
        }
Esempio n. 2
0
        internal bool TryGetOrAdd(TKey key, Predicate <TKey> keyOverwriteCheck, TValue value, out TValue stored)
        {
            // NOTICE this method has no null check
            var needle = PrivateGetNeedle(key);

            if
            (
                _wrapped.TryGetOrAdd
                (
                    needle,
                    input =>
            {
                TKey foundKey;
                if (PrivateTryGetValue(input, out foundKey))
                {
                    return(keyOverwriteCheck(foundKey));
                }
                return(true);
            },
                    value,
                    out stored
                )
            )
            {
                return(true);
            }
            NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);

            return(false);
        }
Esempio n. 3
0
 /// <summary>
 /// Retrieve or creates a new item at the specified index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <returns>The value.</returns>
 /// <exception cref="System.ArgumentOutOfRangeException">index;index must be greater or equal to 0 and less than capacity</exception>
 public T Get(int index)
 {
     if (index < 0 || index >= _entries.Capacity)
     {
         throw new ArgumentOutOfRangeException("index", "index must be greater or equal to 0 and less than capacity");
     }
     // Using TryGetValue first just avoid wasting a needle
     TNeedle found;
     if (_entries.TryGetInternal(index, out found))
     {
         // Null resistant
         T previous;
         found.TryGetValue(out previous);
         return previous;
         // We don't donate because we didn't remove
     }
     var newNeedle = _needleFactory(index);
     if (_entries.InsertInternal(index, newNeedle, out found))
     {
         return newNeedle.Value;
     }
     // we just failed to insert, meaning that we created a usless needle
     // donate it
     NeedleReservoir<T, TNeedle>.DonateNeedle(newNeedle);
     return found.Value;
 }
Esempio n. 4
0
        /// <summary>
        /// Attempts to add the specified key and associated value. The value is added if the key is not found.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="stored">The stored pair independently of success.</param>
        /// <returns>
        ///   <c>true</c> if the specified key and associated value were added; otherwise, <c>false</c>.
        /// </returns>
        public bool TryAdd(TKey key, TValue value, out KeyValuePair <TKey, TValue> stored)
        {
            // No risk of dead needles here
            var needle = PrivateGetNeedle(key);
            KeyValuePair <TNeedle, TValue> storedPair;
            Predicate <TNeedle>            check = found =>
            {
                TKey foundKey;
                if (PrivateTryGetValue(found, out foundKey))
                {
                    // Keeping the found key alive
                    // If we found a key, key will be the key found
                    // If we didn't key will be the key added
                    // So, either way key is the key that is stored
                    // By having it here, we don't need to read _stored.Key
                    key = foundKey;
                    return(false);
                }
                return(true);
            };
            var result = _wrapped.TryAdd(needle, check, value, out storedPair);

            if (!result)
            {
                NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);
            }
            stored = new KeyValuePair <TKey, TValue>(key, storedPair.Value);
            return(result);
        }
Esempio n. 5
0
        /// <summary>
        /// Adds the specified key and associated value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="keyOverwriteCheck">The key predicate to approve overwriting.</param>
        /// <param name="value">The value.</param>
        /// <exception cref="System.ArgumentException">An item with the same key has already been added</exception>
        internal void AddNew(TKey key, Predicate <TKey> keyOverwriteCheck, TValue value)
        {
            // NOTICE this method has no null check
            var needle = PrivateGetNeedle(key);

            try
            {
                _wrapped.AddNew
                (
                    needle,
                    input =>
                {
                    TKey foundKey;
                    if (PrivateTryGetValue(input, out foundKey))
                    {
                        return(keyOverwriteCheck(foundKey));
                    }
                    return(true);
                },
                    value
                );
            }
            catch (ArgumentException)
            {
                NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);

                throw;
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Removes all the elements.
        /// </summary>
        public void Clear()
        {
            var displaced = _wrapped.ClearEnumerable();

            foreach (var item in displaced)
            {
                NeedleReservoir <TKey, TNeedle> .DonateNeedle(item.Key);
            }
        }
Esempio n. 7
0
        public TValue GetOrAdd(TKey key, TValue value)
        {
            var    needle = PrivateGetNeedle(key);
            TValue result;

            if (!_wrapped.TryGetOrAdd(needle, input => !input.IsAlive, value, out result))
            {
                NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);
            }
            return(result);
        }
Esempio n. 8
0
        public bool TryGetOrAdd(TKey key, TValue value, out TValue stored)
        {
            var needle = PrivateGetNeedle(key);

            if (_wrapped.TryGetOrAdd(needle, input => !input.IsAlive, value, out stored))
            {
                return(true);
            }
            NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);

            return(false);
        }
Esempio n. 9
0
        public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)
        {
            var needle = PrivateGetNeedle(key);

            if (_wrapped.TryUpdate(needle, newValue, comparisonValue))
            {
                return(true);
            }
            NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);

            return(false);
        }
Esempio n. 10
0
        public bool TryUpdate(TKey key, TValue newValue, Predicate <TValue> valueCheck)
        {
            var needle = PrivateGetNeedle(key);

            if (_wrapped.TryUpdate(needle, newValue, valueCheck))
            {
                return(true);
            }
            NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);

            return(false);
        }
Esempio n. 11
0
 /// <summary>
 /// Inserts the item at the specified index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <param name="item">The item.</param>
 /// <returns>
 ///   <c>true</c> if the item was inserted; otherwise, <c>false</c>.
 /// </returns>
 /// <exception cref="System.ArgumentOutOfRangeException">index;index must be greater or equal to 0 and less than capacity.</exception>
 /// <remarks>
 /// The insertion can fail if the index is already used or is being written by another thread.
 /// If the index is being written it can be understood that the insert operation happened before but the item was overwritten or removed.
 /// </remarks>
 public bool Insert(int index, T item)
 {
     // Only succeeds if there was nothing there before
     // meaning that if this succeeds it replaced nothing
     // If this fails whatever was there is still there
     var newNeedle = NeedleReservoir<T, TNeedle>.GetNeedle(item);
     if (_entries.Insert(index, newNeedle))
     {
         return true;
     }
     NeedleReservoir<T, TNeedle>.DonateNeedle(newNeedle);
     return false;
 }
Esempio n. 12
0
 /// <summary>
 /// Retrieve or creates a new needle at the specified index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <returns>The needle.</returns>
 /// <exception cref="System.ArgumentOutOfRangeException">index;index must be greater or equal to 0 and less than capacity</exception>
 public TNeedle GetNeedle(int index)
 {
     TNeedle found;
     var newNeedle = _needleFactory(index);
     if (_entries.Insert(index, newNeedle, out found))
     {
         return newNeedle;
     }
     // we just failed to insert, meaning that we created a usless needle
     // donate it
     NeedleReservoir<T, TNeedle>.DonateNeedle(newNeedle);
     return found;
 }
Esempio n. 13
0
 /// <summary>
 /// Removes the item at the specified index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <param name="previous">The previous item in the specified index.</param>
 /// <returns>
 ///   <c>true</c> if the item was removed; otherwise, <c>false</c>.
 /// </returns>
 /// <exception cref="System.ArgumentOutOfRangeException">index;index must be greater or equal to 0 and less than capacity</exception>
 public bool RemoveAt(int index, out T previous)
 {
     TNeedle found;
     if (_entries.RemoveAt(index, out found))
     {
         // TryGetValue is null resistant
         found.TryGetValue(out previous);
         // Donate it
         NeedleReservoir<T, TNeedle>.DonateNeedle(found);
         return true;
     }
     previous = default(T);
     return false;
 }
Esempio n. 14
0
 /// <summary>
 /// Sets the item at the specified index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <param name="item">The item.</param>
 /// <param name="previous">The previous item in the specified index.</param>
 /// <returns>
 ///   <c>true</c> if the item was new; otherwise, <c>false</c>.
 /// </returns>
 /// <exception cref="System.ArgumentOutOfRangeException">index;index must be greater or equal to 0 and less than capacity</exception>
 public bool Exchange(int index, T item, out T previous)
 {
     TNeedle found;
     if (_entries.Exchange(index, NeedleReservoir<T, TNeedle>.GetNeedle(item), out found))
     {
         previous = default(T);
         return true;
     }
     // TryGetValue is null resistant
     found.TryGetValue(out previous);
     // This is a needle that is no longer referenced, we donate it
     NeedleReservoir<T, TNeedle>.DonateNeedle(found);
     return false;
 }
Esempio n. 15
0
        /// <summary>
        /// Adds the specified key and associated value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <exception cref="System.ArgumentException">An item with the same key has already been added</exception>
        public void AddNew(TKey key, TValue value)
        {
            var needle = PrivateGetNeedle(key);

            try
            {
                _wrapped.AddNew(needle, input => !input.IsAlive, value);
            }
            catch (ArgumentException)
            {
                NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);

                throw;
            }
        }
Esempio n. 16
0
 public bool Update(int index, Func<T, T> itemUpdateFactory, Predicate<T> check, out bool isEmpty)
 {
     TNeedle newNeedle = null;
     Func<TNeedle, TNeedle> replacementFactory = needle => newNeedle = NeedleReservoir<T, TNeedle>.GetNeedle(itemUpdateFactory(needle.Value));
     Predicate<TNeedle> replacementCheck = needle => check(needle.Value);
     if (_entries.Update(index, replacementFactory, replacementCheck, out isEmpty))
     {
         return true;
     }
     if (newNeedle != null)
     {
     }
     NeedleReservoir<T, TNeedle>.DonateNeedle(newNeedle);
     return false;
 }
Esempio n. 17
0
 public bool RemoveAt(int index, Predicate<T> check)
 {
     TNeedle found = null;
     Predicate<TNeedle> replacementCheck = needle =>
     {
         found = needle;
         return check(needle.Value);
     };
     if (_entries.RemoveAt(index, replacementCheck))
     {
         // Donate it
         NeedleReservoir<T, TNeedle>.DonateNeedle(found);
         return true;
     }
     return false;
 }
Esempio n. 18
0
 /// <summary>
 /// Inserts the item at the specified index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <param name="item">The item.</param>
 /// <param name="previous">The previous item in the specified index.</param>
 /// <returns>
 ///   <c>true</c> if the item was inserted; otherwise, <c>false</c>.
 /// </returns>
 /// <exception cref="System.ArgumentOutOfRangeException">index;index must be greater or equal to 0 and less than capacity</exception>
 /// <remarks>
 /// The insertion can fail if the index is already used or is being written by another thread.
 /// If the index is being written it can be understood that the insert operation happened before but the item was overwritten or removed.
 /// </remarks>
 public bool Insert(int index, T item, out T previous)
 {
     // Only succeeds if there was nothing there before
     // meaning that if this succeeds it replaced nothing
     // If this fails whatever was there is still there
     TNeedle found;
     var newNeedle = NeedleReservoir<T, TNeedle>.GetNeedle(item);
     if (_entries.Insert(index, newNeedle, out found))
     {
         previous = default(T);
         return true;
     }
     NeedleReservoir<T, TNeedle>.DonateNeedle(newNeedle);
     // TryGetValue is null resistant
     found.TryGetValue(out previous);
     return false;
 }
Esempio n. 19
0
        /// <summary>
        /// Removes all the elements.
        /// </summary>
        public IEnumerable <KeyValuePair <TKey, TValue> > ClearEnumerable()
        {
            // No risk of dead needles here
            var displaced = _wrapped.ClearEnumerable();

            foreach (var item in displaced)
            {
                TKey foundKey;
                if (PrivateTryGetValue(item.Key, out foundKey))
                {
                    var value = item.Value;
                    yield return(new KeyValuePair <TKey, TValue>(foundKey, value));

                    NeedleReservoir <TKey, TNeedle> .DonateNeedle(item.Key);
                }
            }
        }
Esempio n. 20
0
        public bool TryGetOrAdd(TKey key, Func <TKey, TValue> valueFactory, out TValue stored)
        {
            if (ReferenceEquals(valueFactory, null))
            {
                throw new ArgumentNullException("valueFactory");
            }
            var needle = PrivateGetNeedle(key);
            Func <TNeedle, TValue, TValue> factory = (pairKey, foundValue) =>
            {
                TKey foundKey;
                return(valueFactory(PrivateTryGetValue(pairKey, out foundKey) ? foundKey : key));
            };

            if (_wrapped.TryGetOrAdd(needle, () => valueFactory(key), factory, out stored))
            {
                return(true);
            }
            NeedleReservoir <TKey, TNeedle> .DonateNeedle(needle);

            return(false);
        }