コード例 #1
0
        public bool TryPeek(out T result)
        {
            result = default(T);

            if (count == 0)
            {
                return(false);
            }

            int             hintIndex;
            CyclicDeque <T> bag = GetBag(out hintIndex, false);
            bool            ret = true;

            if (bag == null || !bag.PeekBottom(out result))
            {
                var self = bag;
                ret = false;
                foreach (var other in staging)
                {
                    ret = TryGetHint(out hintIndex) && container[hintIndex].PeekTop(out result);

                    if (!ret && other.Value != self)
                    {
                        ret = other.Value.PeekTop(out result);
                    }

                    if (ret)
                    {
                        break;
                    }
                }
            }

            return(ret);
        }
コード例 #2
0
 public ConcurrentBag()
 {
     container = new CyclicDeque <T> [size];
     for (int i = 0; i < container.Length; i++)
     {
         container[i] = new CyclicDeque <T> ();
     }
 }
コード例 #3
0
ファイル: ConcurrentBag.cs プロジェクト: destinyclown/xunit
        public void Add(T item)
        {
            int             index;
            CyclicDeque <T> bag = GetBag(out index);

            bag.PushBottom(item);
            AddHint(index);
            Interlocked.Increment(ref count);
        }
コード例 #4
0
        public void Add(T item)
        {
            Interlocked.Increment(ref count);
            GrowIfNecessary();

            CyclicDeque <T> bag = GetBag();

            bag.PushBottom(item);
        }
コード例 #5
0
ファイル: ConcurrentBag.cs プロジェクト: destinyclown/xunit
 void TidyBag(int index, CyclicDeque <T> bag)
 {
     if (bag != null && bag.IsEmpty)
     {
         if (staging.TryRemove(index, out bag) && !bag.IsEmpty)
         {
             staging.TryAdd(index, bag);
         }
     }
 }
コード例 #6
0
 IEnumerator <T> GetEnumeratorInternal()
 {
     for (int i = 0; i < size; i++)
     {
         CyclicDeque <T> bag = container[i];
         foreach (T item in bag.GetEnumerable())
         {
             yield return(item);
         }
     }
 }
コード例 #7
0
        public bool TryTake(out T result)
        {
            result = default(T);

            if (count == 0)
            {
                return(false);
            }

            int             hintIndex;
            CyclicDeque <T> bag = GetBag(out hintIndex, false);
            bool            ret = true;

            if (bag == null || bag.PopBottom(out result) != PopResult.Succeed)
            {
                var self = bag;
                ret = false;
                foreach (var other in staging)
                {
                    // Try to retrieve something based on a hint
                    ret = TryGetHint(out hintIndex) && (bag = container[hintIndex]).PopTop(out result) == PopResult.Succeed;

                    // We fall back to testing our slot
                    if (!ret && other.Value != self)
                    {
                        var status = other.Value.PopTop(out result);
                        while (status == PopResult.Abort)
                        {
                            status = other.Value.PopTop(out result);
                        }
                        ret       = status == PopResult.Succeed;
                        hintIndex = other.Key;
                        bag       = other.Value;
                    }

                    // If we found something, stop
                    if (ret)
                    {
                        break;
                    }
                }
            }

            if (ret)
            {
                TidyBag(hintIndex, bag);
                Interlocked.Decrement(ref count);
            }

            return(ret);
        }
コード例 #8
0
        public void Add(T item)
        {
            int             index;
            CyclicDeque <T> bag = GetBag(out index);

            bag.PushBottom(item);

            // Cache operation ?
            if (container.Count > hintThreshold)
            {
                addHints.Enqueue(index);
            }

            Interlocked.Increment(ref count);
        }
コード例 #9
0
        public bool TryTake(out T result)
        {
            result = default(T);

            if (count == 0)
            {
                return(false);
            }

            int             hintIndex;
            CyclicDeque <T> bag         = GetBag(out hintIndex);
            bool            hintEnabled = container.Count > hintThreshold;

            if (bag == null || bag.PopBottom(out result) != PopResult.Succeed)
            {
                foreach (var other in container)
                {
                    // Try to retrieve something based on a hint
                    bool ret = hintEnabled && addHints.TryDequeue(out hintIndex) && container[hintIndex].PopTop(out result) == PopResult.Succeed;

                    // We fall back to testing our slot
                    if (!ret && other.Value != bag)
                    {
                        ret = other.Value.PopTop(out result) == PopResult.Succeed;
                    }

                    // If we found something, stop
                    if (ret)
                    {
                        Interlocked.Decrement(ref count);
                        return(true);
                    }
                }
            }
            else
            {
                Interlocked.Decrement(ref count);
                return(true);
            }

            return(false);
        }
コード例 #10
0
        public bool TryPeek(out T result)
        {
            result = default(T);

            if (count == 0)
            {
                return(false);
            }

            int             hintIndex;
            CyclicDeque <T> bag = GetBag(out hintIndex, false);
            bool            ret = true;

            if (bag == null || !bag.PeekBottom(out result))
            {
                var self = bag;
                ret = false;
                foreach (var other in staging)
                {
                    // Try to retrieve something based on a hint
                    ret = TryGetHint(out hintIndex) && container[hintIndex].PeekTop(out result);

                    // We fall back to testing our slot
                    if (!ret && other.Value != self)
                    {
                        ret = other.Value.PeekTop(out result);
                    }

                    // If we found something, stop
                    if (ret)
                    {
                        break;
                    }
                }
            }

            return(ret);
        }
コード例 #11
0
        void Grow(int referenceSize)
        {
            lock (syncLock) {
                if (referenceSize != size)
                {
                    return;
                }

                CyclicDeque <T>[] slice = new CyclicDeque <T> [size * multiplier];
                int i = 0;
                for (i = 0; i < container.Length; i++)
                {
                    slice[i] = container[i];
                }
                for (; i < slice.Length; i++)
                {
                    slice[i] = new CyclicDeque <T> ();
                }

                container = slice;
                size      = slice.Length;
            }
        }
コード例 #12
0
        public bool TryTake(out T item)
        {
            item = default(T);
            CyclicDeque <T> bag = GetBag();

            if (bag == null || bag.PopBottom(out item) != PopResult.Succeed)
            {
                for (int i = 0; i < container.Length; i++)
                {
                    if (container[i].PopTop(out item) == PopResult.Succeed)
                    {
                        Interlocked.Decrement(ref count);
                        return(true);
                    }
                }
            }
            else
            {
                Interlocked.Decrement(ref count);
                return(true);
            }

            return(false);
        }