Exemple #1
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="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(nameof(index), "index must be greater or equal to 0 and less than capacity");
            }
            // Using TryGetValue first just avoid wasting a needle
            if (_entries.TryGetInternal(index, out var found))
            {
                // Null resistant
                found.TryGetValue(out var previous);
                return(previous);
                // We don't donate because we didn't remove
            }
            var newNeedle = _needleIndexFactory(index);

            if (_entries.InsertInternal(index, newNeedle, out found))
            {
                return(newNeedle.Value);
            }
            // we just failed to insert, meaning that we created a useless needle
            // donate it
            Reservoir.DonateNeedle(newNeedle);
            return(found.Value);
        }
Exemple #2
0
        /// <summary>
        /// Adds the specified item. Will not overwrite existing items.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns>Returns the position where the item was added, -1 otherwise.</returns>
        public int TryAdd(T item)
        {
            var index = Interlocked.Increment(ref _index) & (_capacity - 1);

            if (_entries.InsertInternal(index, item))
            {
                return(index);
            }
            return(-1);
        }
Exemple #3
0
 /// <summary>
 /// Attempts to Adds the specified item.
 /// </summary>
 /// <param name="item">The item.</param>
 /// <returns>
 ///   <c>true</c> if the item was added; otherwise, <c>false</c>.
 /// </returns>
 public bool TryAdd(T item)
 {
     if (_entries.Count < Capacity)
     {
         var preCount = Interlocked.Increment(ref _preCount);
         if (preCount <= Capacity)
         {
             var index = (Interlocked.Increment(ref _indexEnqueue) - 1) & (Capacity - 1);
             if (_entries.InsertInternal(index, item))
             {
                 return(true);
             }
         }
         Interlocked.Decrement(ref _preCount);
     }
     return(false);
 }