Exemple #1
0
        public void PushLeft_IsAtomic()
        {
            //Arrange
            long pushCount = 0;
            long sum       = 0;
            bool cancelled = false;

            var deque = new ConcurrentDeque <int>();

            //keep adding items to the deque
            Action pushLeft = () =>
            {
                Random rnd = new Random();
                while (!cancelled)
                {
                    int val = rnd.Next(1, 11);
                    deque.PushLeft(val);
                    Interlocked.Increment(ref pushCount);
                    Interlocked.Add(ref sum, val);
                }
            };

            //Act
            pushLeft.RunInParallel(() => cancelled = true, ThreadCount, RunningTime);

            //Assert
            VerifyState(deque, pushCount, sum);
        }
Exemple #2
0
        public void EnumeratorDoesNotIncludeConcurrentModifications()
        {
            //Arrange
            var   arr   = new[] { 1, 2, 3 };
            var   deque = new ConcurrentDeque <Int32>(arr);
            Int32 item;

            //Act
            var iterator = deque.GetEnumerator();

            iterator.MoveNext();

            deque.TryPopLeft(out item);
            deque.TryPopLeft(out item);
            deque.PushLeft(6);

            deque.TryPopRight(out item);
            deque.PushRight(6);

            //Assert
            Assert.AreEqual(1, iterator.Current);

            Assert.True(iterator.MoveNext());
            Assert.AreEqual(2, iterator.Current);

            Assert.True(iterator.MoveNext());
            Assert.AreEqual(3, iterator.Current);

            Assert.False(iterator.MoveNext());
        }
Exemple #3
0
        private static void ExecuteOp(ConcurrentDeque <int> deque, int op)
        {
            int item;

            switch (op)
            {
            case PopLeft:
                deque.TryPopLeft(out item);
                break;

            case PopRight:
                deque.TryPopRight(out item);
                break;

            case PushLeft:
                deque.PushLeft(10);
                break;

            case PushRight:
                deque.PushRight(10);
                break;

            default:
                throw new InvalidOperationException();
            }
        }
Exemple #4
0
        public void TryPopLeft_IsAtomic()
        {
            //Arrange
            const int    initialCount = 5000000;
            const double stopAt       = initialCount * 0.9;

            int popCount = 0;
            var deque    = new ConcurrentDeque <int>();

            for (int i = 0; i < initialCount; i++)
            {
                deque.PushLeft(i);
            }

            Action popLeft = () =>
            {
                while (popCount <= stopAt)
                {
                    int i;
                    Assert.True(deque.TryPopLeft(out i));
                    Interlocked.Increment(ref popCount);
                }
            };

            //Act
            popLeft.RunInParallel(ThreadCount);

            //Assert
            var  expectedCount = initialCount - popCount;
            long expectedSum   = Enumerable.Range(0, expectedCount).LongSum();

            VerifyState(deque, expectedCount, expectedSum);
        }
Exemple #5
0
        public void PushLeft_AppendsNode_ToEmptyDeque()
        {
            var deque = new ConcurrentDeque <int>();

            deque.PushLeft(1);

            Assert.Equal(new[] { 1 }, deque);
        }
Exemple #6
0
        public void PushLeft_AppendsNode_ToNonEmptyList()
        {
            var deque = new ConcurrentDeque <int>(new[] { 1, 2, 3 });

            deque.PushLeft(0);

            Assert.Equal(new[] { 0, 1, 2, 3 }, deque);
        }
Exemple #7
0
        public void PushLeftAppendsNodeToNonEmptyList()
        {
            var deque = new ConcurrentDeque <Int32>(new[] { 1, 2, 3 });

            deque.PushLeft(0);

            Assert.AreEqual(new[] { 0, 1, 2, 3 }, deque);
        }
Exemple #8
0
        public void PushLeftAppendsNodeToEmptyDeque()
        {
            var deque = new ConcurrentDeque <Int32>();

            deque.PushLeft(1);

            Assert.AreEqual(new[] { 1 }, deque);
        }
Exemple #9
0
        public void PushLeftKeepsReferenceToPreviousLeftNode()
        {
            //Arrange
            const Int32 prevValue = 1;
            const Int32 value     = 5;
            var         deque     = new ConcurrentDeque <Int32>();

            deque.PushLeft(prevValue);

            //Act
            deque.PushLeft(value);

            //Assert
            var anchor  = deque._anchor;
            var newNode = anchor._left;

            Assert.AreEqual(prevValue, newNode._right._value);
        }
Exemple #10
0
        public void PushLeftStabilizesDeque()
        {
            //Arrange
            const Int32 prevValue = 1;
            const Int32 value     = 5;
            var         deque     = new ConcurrentDeque <Int32>();

            deque.PushLeft(prevValue);

            //Act
            deque.PushLeft(value);

            //Assert
            var anchor  = deque._anchor;
            var newNode = anchor._left;

            Assert.AreSame(newNode, newNode._right._left);
            Assert.AreEqual(ConcurrentDeque <Int32> .DequeStatus.Stable, anchor._status);
        }
Exemple #11
0
        public void PushLeftAppendsNodeToEmptyList()
        {
            //Arrange
            const Int32 value = 5;
            var         deque = new ConcurrentDeque <Int32>();

            //Act
            deque.PushLeft(value);

            //Assert
            var anchor = deque._anchor;

            Assert.NotNull(anchor._right);
            Assert.NotNull(anchor._left);
            Assert.AreSame(anchor._left, anchor._right);
            Assert.AreEqual(value, anchor._left._value);
        }
Exemple #12
0
        public void PushLeftAppendsNodeToNonEmptyList()
        {
            //Arrange
            const Int32 value = 5;
            var         deque = new ConcurrentDeque <Int32>();

            deque.PushRight(1);

            //Act
            deque.PushLeft(value);

            //Assert
            var anchor       = deque._anchor;
            var leftmostNode = anchor._left;

            Assert.NotNull(leftmostNode);
            Assert.AreEqual(value, leftmostNode._value);
        }
Exemple #13
0
        public void InterleavedPushPopLeftOps()
        {
            //Arrange
            var  deque     = new ConcurrentDeque <int>();
            long sum       = 0;
            long nodeCount = 0;
            bool cancelled = false;

            Action action = () =>
            {
                Random rnd = new Random();

                while (!cancelled)
                {
                    //slightly biased towards "push"
                    if (rnd.NextDouble() >= 0.45)
                    {
                        //push
                        var val = rnd.Next(1, 51);
                        deque.PushLeft(val);
                        Interlocked.Increment(ref nodeCount);
                        Interlocked.Add(ref sum, val);
                    }
                    else
                    {
                        //pop
                        int val;
                        if (deque.TryPopLeft(out val))
                        {
                            Interlocked.Decrement(ref nodeCount);
                            Interlocked.Add(ref sum, -val);
                        }
                    }
                }
            };

            //Act
            action.RunInParallel(() => cancelled = true, ThreadCount, RunningTime);

            //Assert
            VerifyState(deque, nodeCount, sum);
        }
Exemple #14
0
        public void InterleavedOps()
        {
            //Arrange
            var  deque      = new ConcurrentDeque <int>();
            long sum        = 0;
            long nodeCount  = 0;
            bool cancelled  = false;
            bool shouldPush = true;

            Action action = () =>
            {
                Random rnd = new Random();

                while (!cancelled)
                {
                    if (shouldPush)
                    {
                        //push to either end
                        var val = rnd.Next(1, 51);
                        if (rnd.NextDouble() > 0.50)
                        {
                            deque.PushLeft(val);
                        }
                        else
                        {
                            deque.PushRight(val);
                        }
                        Interlocked.Increment(ref nodeCount);
                        Interlocked.Add(ref sum, val);

                        //start popping
                        if (nodeCount >= 10000)
                        {
                            shouldPush = false;
                        }
                    }
                    else
                    {
                        //pop from either end
                        int val;
                        if (rnd.NextDouble() > 0.50)
                        {
                            if (deque.TryPopLeft(out val))
                            {
                                Interlocked.Decrement(ref nodeCount);
                                Interlocked.Add(ref sum, -val);
                            }
                        }
                        else
                        {
                            if (deque.TryPopRight(out val))
                            {
                                Interlocked.Decrement(ref nodeCount);
                                Interlocked.Add(ref sum, -val);
                            }
                        }

                        //start pushing
                        if (nodeCount == 0)
                        {
                            shouldPush = true;
                        }
                    }
                }
            };

            //Act
            action.RunInParallel(() => cancelled = true, ThreadCount, RunningTime);

            //Assert
            VerifyState(deque, nodeCount, sum);
        }
Exemple #15
0
        public static void Main(string[] args)
        {
            var  options   = new Options();
            var  deque     = new ConcurrentDeque <int>(Enumerable.Repeat(1, 100000));
            bool cancelled = false;

            //parse arguments
            if (!CommandLine.Parser.Default.ParseArgumentsStrict(args, options))
            {
                return;
            }

            Setup(options);

            using (var countersContainer = CreateContainer(options))
            {
                //action to be executed by each thread - concurrently mutate the deque
                Action action = () =>
                {
                    int i = 0;
                    int poppedValue;

                    while (!cancelled)
                    {
                        //pop from/push onto the deque
                        i++;
                        if (i % 4 == 0)
                        {
                            deque.PushLeft(1);
                        }
                        else if (i % 3 == 0)
                        {
                            deque.PushRight(1);
                        }
                        else if (i % 2 == 0)
                        {
                            deque.TryPopLeft(out poppedValue);
                        }
                        else
                        {
                            deque.TryPopRight(out poppedValue);
                        }

                        //increment counters
                        countersContainer.Increment();
                    }

                    countersContainer.Complete();
                };

                Action cancel = () =>
                {
                    cancelled = true;
                };

                //launch a set of threads to mutate the deque concurrently
                action.RunInParallel(cancel, _threadCount, _runningTime);

                countersContainer.PrintCounters();
            }
        }