Example #1
0
        /// <summary>
        /// Returns the next item to be taken from the back without removing it.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">No more items to be taken.</exception>
        public T Peek(T item)
        {
            T result = default(T);

            while (true)
            {
                int revision = _revision;
                if (IsOperationSafe())
                {
                    var  entries = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done    = false;
                    try
                    {
                        result = entries.Peek();
                    }
                    finally
                    {
                        var isOperationSafe = IsOperationSafe(entries, revision);
                        if (isOperationSafe)
                        {
                            done = true;
                        }
                    }
                    if (done)
                    {
                        return(result);
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }
Example #2
0
 /// <summary>
 /// Sets the value associated with the specified key.
 /// </summary>
 /// <param name="key">The key.</param>
 /// <param name="value">The value.</param>
 public void Set(TKey key, TValue value)
 {
     while (true)
     {
         int revision = _revision;
         if (IsOperationSafe())
         {
             bool isNew;
             var  entries = ThreadingHelper.VolatileRead(ref _entriesNew);
             if (SetExtracted(key, value, entries, out isNew) != -1)
             {
                 if (IsOperationSafe(entries, revision))
                 {
                     if (isNew)
                     {
                         Interlocked.Increment(ref _count);
                     }
                     break;
                 }
                 else
                 {
                     int oldStatus = Interlocked.CompareExchange(ref _status, (int)BucketStatus.GrowRequested, (int)BucketStatus.Free);
                     if (oldStatus == (int)BucketStatus.Free)
                     {
                         _revision++;
                     }
                 }
             }
         }
         else
         {
             CooperativeGrow();
         }
     }
 }
Example #3
0
 internal void Release()
 {
     if (ThreadingHelper.VolatileRead(ref _capture).Flags.IsEmpty())
     {
         _target = default(T);
         Thread.MemoryBarrier();
     }
 }
Example #4
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">the key is already present</exception>
        public void Add(TKey key, TValue value)
        {
            bool result = false;
            int  revision;

            while (true)
            {
                revision = _revision;
                if (IsOperationSafe())
                {
                    bool isCollision = false;
                    var  entries     = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done        = false;
                    try
                    {
                        if (AddExtracted(key, value, entries, out isCollision) != -1)
                        {
                            result = true;
                        }
                    }
                    finally
                    {
                        var isOperationSafe = IsOperationSafe(entries, revision);
                        if (isOperationSafe)
                        {
                            if (result)
                            {
                                Interlocked.Increment(ref _count);
                                done = true;
                            }
                            else
                            {
                                if (isCollision)
                                {
                                    var oldStatus = Interlocked.CompareExchange(ref _status, (int)BucketStatus.GrowRequested, (int)BucketStatus.Free);
                                    if (oldStatus == (int)BucketStatus.Free)
                                    {
                                        _revision++;
                                    }
                                }
                                else
                                {
                                    throw new ArgumentException("the key is already present");
                                }
                            }
                        }
                    }
                    if (done)
                    {
                        return;
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }
Example #5
0
        private void WaitCanWrite()
        {
            if (Thread.CurrentThread != ThreadingHelper.VolatileRead(ref _ownerThread))
            {
                var check = Interlocked.CompareExchange(ref _master, -1, 0);
                while (true)
                {
                    switch (check)
                    {
                    case -2:
                    // Write mode already requested
                    case -1:
                        // There is another writer
                        // Go to wait
                        _freeToWrite.Wait();
                        check = Interlocked.CompareExchange(ref _master, -1, 0);
                        break;

                    case 0:
                        // Free to proceed
                        // GO!
                        _freeToRead.Reset();
                        if (Interlocked.CompareExchange(ref _ownerThread, Thread.CurrentThread, null) == null)
                        {
                            // Success
                            Interlocked.Increment(ref _writeCount);
                            return;
                        }
                        else
                        {
                            // It was reserved by another thread
                            break;
                        }

                    case 1:
                        // There are readers currently
                        // Requesting write mode
                        check = Interlocked.CompareExchange(ref _master, -2, 1);
                        if (check == 1)
                        {
                            _freeToRead.Reset();
                            check = -2;
                        }
                        break;
                    }
                }
            }
        }
Example #6
0
 private bool CanRead()
 {
     if (Thread.CurrentThread == ThreadingHelper.VolatileRead(ref _ownerThread))
     {
         Interlocked.Increment(ref _readCount);
         _currentReadingCount.Value++;
         return(true);
     }
     if (Interlocked.CompareExchange(ref _master, 1, 0) >= 0)
     {
         _freeToWrite.Reset();
         Interlocked.Increment(ref _readCount);
         _currentReadingCount.Value++;
         return(true);
     }
     return(false);
 }
Example #7
0
        /// <summary>
        /// Adds the specified item at the front.
        /// </summary>
        /// <param name="item">The item.</param>
        public void Enqueue(T item)
        {
            bool result = false;

            while (true)
            {
                if (IsOperationSafe())
                {
                    var  entries = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done    = false;
                    try
                    {
                        Interlocked.Increment(ref _workingThreads);
                        if (entries.Enqueue(item))
                        {
                            result = true;
                        }
                    }
                    finally
                    {
                        Interlocked.Decrement(ref _workingThreads);
                        if (result)
                        {
                            Interlocked.Increment(ref _count);
                            done = true;
                        }
                        else
                        {
                            var oldStatus = Interlocked.CompareExchange(ref _status, (int)BucketStatus.GrowRequested, (int)BucketStatus.Free);
                            if (oldStatus == (int)BucketStatus.Free)
                            {
                                _revision++;
                            }
                        }
                    }
                    if (done)
                    {
                        return;
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }
Example #8
0
        /// <summary>
        /// Tries to retrieve the key and associated value at the specified index.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns>
        ///   <c>true</c> if the value was retrieved; otherwise, <c>false</c>.
        /// </returns>
        public bool TryGet(int index, out TKey key, out TValue value)
        {
            value = default(TValue);
            key   = default(TKey);
            bool result = false;
            int  revision;

            while (true)
            {
                revision = _revision;
                if (IsOperationSafe())
                {
                    var  entries = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done    = false;
                    try
                    {
                        TValue tmpValue;
                        TKey   tmpKey;
                        if (TryGetExtracted(index, entries, out tmpKey, out tmpValue))
                        {
                            key    = tmpKey;
                            value  = tmpValue;
                            result = true;
                        }
                    }
                    finally
                    {
                        var isOperationSafe = IsOperationSafe(entries, revision);
                        if (isOperationSafe)
                        {
                            done = true;
                        }
                    }
                    if (done)
                    {
                        return(result);
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }
Example #9
0
        /// <summary>
        /// Removes the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns>
        ///   <c>true</c> if the specified key was removed; otherwise, <c>false</c>.
        /// </returns>
        public bool Remove(TKey key)
        {
            bool result = false;
            int  revision;

            while (true)
            {
                revision = _revision;
                if (IsOperationSafe())
                {
                    var  entries = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done    = false;
                    try
                    {
                        if (RemoveExtracted(key, entries))
                        {
                            result = true;
                        }
                    }
                    finally
                    {
                        var isOperationSafe = IsOperationSafe(entries, revision);
                        if (isOperationSafe)
                        {
                            if (result)
                            {
                                Interlocked.Decrement(ref _count);
                            }
                            done = true;
                        }
                    }
                    if (done)
                    {
                        return(result);
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }
Example #10
0
        /// <summary>
        /// Attempts to retrieve and remove the next item from the back.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns>
        ///   <c>true</c> if the item was taken; otherwise, <c>false</c>.
        /// </returns>
        public bool TryDequeue(out T item)
        {
            item = default(T);
            bool result = false;

            while (true)
            {
                if (IsOperationSafe())
                {
                    var  entries = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done    = false;
                    try
                    {
                        Interlocked.Increment(ref _workingThreads);
                        T tmpItem;
                        if (entries.TryDequeue(out tmpItem))
                        {
                            item   = tmpItem;
                            result = true;
                        }
                    }
                    finally
                    {
                        Interlocked.Decrement(ref _workingThreads);
                        if (result)
                        {
                            Interlocked.Decrement(ref _count);
                        }
                        done = true;
                    }
                    if (done)
                    {
                        return(result);
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }
Example #11
0
        /// <summary>
        /// Tries to retrieve 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 retrieved; otherwise, <c>false</c>.
        /// </returns>
        public bool TryGet(int index, out T item)
        {
            item = default(T);
            bool result = false;
            int  revision;

            while (true)
            {
                revision = _revision;
                if (IsOperationSafe())
                {
                    var  entries = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done    = false;
                    try
                    {
                        T tmpItem;
                        if (TryGetExtracted(index, entries, out tmpItem))
                        {
                            item   = tmpItem;
                            result = true;
                        }
                    }
                    finally
                    {
                        var isOperationSafe = IsOperationSafe(entries, revision);
                        if (isOperationSafe)
                        {
                            done = true;
                        }
                    }
                    if (done)
                    {
                        return(result);
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }
Example #12
0
        /// <summary>
        /// Determines whether the specified key is contained.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns>
        ///   <c>true</c> if the specified key is contained; otherwise, <c>false</c>.
        /// </returns>
        public bool ContainsKey(TKey key)
        {
            bool result = false;
            int  revision;

            while (true)
            {
                revision = _revision;
                if (IsOperationSafe())
                {
                    var  entries = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done    = false;
                    try
                    {
                        if (ContainsKeyExtracted(key, entries))
                        {
                            result = true;
                        }
                    }
                    finally
                    {
                        var isOperationSafe = IsOperationSafe(entries, revision);
                        if (isOperationSafe)
                        {
                            done = true;
                        }
                    }
                    if (done)
                    {
                        return(result);
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }
Example #13
0
        /// <summary>
        /// Attempts to add the specified key and associated value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns>The value found in the destination after the attempt, regardless of collisions.</returns>
        public TValue TryAdd(TKey key, TValue value)
        {
            bool result = false;
            int  revision;
            KeyValuePair <TKey, TValue> previous = default(KeyValuePair <TKey, TValue>);
            TValue found = value;

            while (true)
            {
                revision = _revision;
                if (IsOperationSafe())
                {
                    bool isCollision = false;
                    var  entries     = ThreadingHelper.VolatileRead(ref _entriesNew);
                    bool done        = false;
                    try
                    {
                        if (TryAddExtracted(key, value, entries, out previous) != -1)
                        {
                            result = true;
                        }
                        else
                        {
                            isCollision = !_keyComparer.Equals(previous.Key, key);
                        }
                    }
                    finally
                    {
                        var isOperationSafe = IsOperationSafe(entries, revision);
                        if (isOperationSafe)
                        {
                            if (result)
                            {
                                Interlocked.Increment(ref _count);
                                done = true;
                            }
                            else
                            {
                                if (isCollision)
                                {
                                    var oldStatus = Interlocked.CompareExchange(ref _status, (int)BucketStatus.GrowRequested, (int)BucketStatus.Free);
                                    if (oldStatus == (int)BucketStatus.Free)
                                    {
                                        _revision++;
                                    }
                                }
                                else
                                {
                                    done  = true;
                                    found = previous.Value;
                                }
                            }
                        }
                    }
                    if (done)
                    {
                        return(found);
                    }
                }
                else
                {
                    CooperativeGrow();
                }
            }
        }