示例#1
0
        public void SegmentBackgroundCompactionTest()
        {
            var segmentFactory = new MemorySegmentFactory <int>(10);

            using (var queue = new DiskQueue <int>("dummy", segmentFactory, -1, true, 100))
            {
                Assert.AreEqual(1, queue.SegmentCount);

                for (int i = 0; i < segmentFactory.Capacity; i++)
                {
                    queue.Add(i);
                }

                Assert.AreEqual(1, queue.SegmentCount);

                queue.Add(-1);
                Assert.AreEqual(2, queue.SegmentCount);
                Assert.AreEqual(2, segmentFactory.AllocatedSegments.Count);

                for (int i = 0; i < segmentFactory.Capacity; i++)
                {
                    queue.Take();
                }

                Assert.IsTrue(segmentFactory.AllocatedSegments[0].IsCompleted);

                TimingAssert.AreEqual(10000, 1, () => { Interlocked.MemoryBarrier(); return(queue.SegmentCount); });
                Assert.AreEqual(2, segmentFactory.AllocatedSegments.Count);
            }
        }
示例#2
0
        // =========================

        private void TakeWakesUpTest(DiskQueue <int> queue)
        {
            Barrier            bar         = new Barrier(2);
            AtomicNullableBool takeResult  = new AtomicNullableBool();
            AtomicNullableBool takeResult2 = new AtomicNullableBool();
            Task task = Task.Run(() =>
            {
                bar.SignalAndWait();
                int item         = 0;
                takeResult.Value = queue.TryTake(out item, 60000);
                Assert.AreEqual(100, item);

                item = 0;
                takeResult2.Value = queue.TryTake(out item, 60000);
                Assert.AreEqual(200, item);
            });

            bar.SignalAndWait();
            Thread.Sleep(10);
            Assert.IsFalse(takeResult.HasValue);

            queue.Add(100);
            TimingAssert.AreEqual(10000, true, () => takeResult.Value);

            Thread.Sleep(10);
            Assert.IsFalse(takeResult2.HasValue);

            queue.Add(200);
            TimingAssert.AreEqual(10000, true, () => takeResult2.Value);

            task.Wait();
        }
示例#3
0
        public void SegmentAllocationCompactionTest()
        {
            var segmentFactory = new MemorySegmentFactory <int>(10);

            using (var queue = new DiskQueue <int>("dummy", segmentFactory, -1, false))
            {
                Assert.AreEqual(1, queue.SegmentCount);

                for (int i = 0; i < segmentFactory.Capacity; i++)
                {
                    queue.Add(i);
                }

                Assert.AreEqual(1, queue.SegmentCount);

                queue.Add(-1);
                Assert.AreEqual(2, queue.SegmentCount);
                Assert.AreEqual(2, segmentFactory.AllocatedSegments.Count);

                for (int i = 0; i < segmentFactory.Capacity; i++)
                {
                    queue.Take();
                }

                Assert.IsTrue(segmentFactory.AllocatedSegments[0].IsCompleted);

                // should trigger compaction
                queue.Take();

                Assert.AreEqual(1, queue.SegmentCount);
                Assert.AreEqual(2, segmentFactory.AllocatedSegments.Count);
            }
        }
示例#4
0
        public void SegmentDiscoveryTest()
        {
            var segmentFactory = new MemorySegmentFactory <int>(10);

            using (var queue = new DiskQueue <int>("dummy", segmentFactory, -1, false))
            {
                Assert.AreEqual(1, queue.SegmentCount);

                for (int i = 0; i < segmentFactory.Capacity * 2; i++)
                {
                    queue.Add(i);
                }

                Assert.AreEqual(2, queue.SegmentCount);
            }

            using (var queue = new DiskQueue <int>("dummy", segmentFactory, -1, false))
            {
                Assert.AreEqual(3, queue.SegmentCount);
                Assert.AreEqual(3, segmentFactory.AllocatedSegments.Count);

                for (int i = 0; i < segmentFactory.Capacity * 2; i++)
                {
                    Assert.AreEqual(i, queue.Take());
                }

                Assert.AreEqual(2, queue.SegmentCount);
            }
        }
示例#5
0
        // =========================

        private void PeekWakesUpTest(DiskQueue <int> queue)
        {
            Barrier            bar         = new Barrier(3);
            AtomicNullableBool peekResult  = new AtomicNullableBool();
            AtomicNullableBool peekResult2 = new AtomicNullableBool();
            Task task = Task.Run(() =>
            {
                bar.SignalAndWait();
                int item         = 0;
                peekResult.Value = queue.TryPeek(out item, 60000);
                Assert.AreEqual(100, item);
            });

            Task task2 = Task.Run(() =>
            {
                bar.SignalAndWait();
                int item          = 0;
                peekResult2.Value = queue.TryPeek(out item, 60000);
                Assert.AreEqual(100, item);
            });

            bar.SignalAndWait();
            Thread.Sleep(10);
            Assert.IsFalse(peekResult.HasValue);
            Assert.IsFalse(peekResult2.HasValue);

            queue.Add(100);
            TimingAssert.AreEqual(10000, true, () => peekResult.Value);
            TimingAssert.AreEqual(10000, true, () => peekResult2.Value);

            Task.WaitAll(task, task2);
        }
示例#6
0
        public void TestConstruction()
        {
            var factory = new MemorySegmentFactory <int>(100);

            using (var queue = new DiskQueue <int>("dummy", factory, 10, true, 500))
            {
                Assert.AreEqual("dummy", queue.Path);
                Assert.AreEqual(0, queue.Count);
                Assert.IsTrue(queue.IsEmpty);
                Assert.IsTrue(queue.IsBackgroundCompactionEnabled);
                Assert.AreEqual(1, queue.SegmentCount);
                Assert.AreEqual(1, factory.AllocatedSegments.Count);
                Assert.AreEqual(factory.Capacity * 10, queue.BoundedCapacity);

                for (int i = 0; i < factory.Capacity + 1; i++)
                {
                    queue.Add(1);
                }

                Assert.AreEqual(factory.Capacity + 1, queue.Count);
                Assert.IsFalse(queue.IsEmpty);
                Assert.AreEqual(2, queue.SegmentCount);
                Assert.AreEqual(2, factory.AllocatedSegments.Count);
            }
        }
示例#7
0
        // ==============================


        private void TestSimpleAddTakePeek(DiskQueue <int> queue)
        {
            Assert.AreEqual(0, queue.Count);
            Assert.IsTrue(queue.IsEmpty);

            Assert.IsTrue(queue.TryAdd(1));

            Assert.AreEqual(1, queue.Count);
            Assert.IsFalse(queue.IsEmpty);

            int item = 0;

            Assert.IsTrue(queue.TryPeek(out item));
            Assert.AreEqual(1, item);

            Assert.IsFalse(queue.IsEmpty);

            item = 0;
            Assert.IsTrue(queue.TryTake(out item));
            Assert.AreEqual(1, item);

            Assert.AreEqual(0, queue.Count);
            Assert.IsTrue(queue.IsEmpty);


            for (int i = 1; i < 1000; i++)
            {
                if (i % 2 == 0)
                {
                    queue.Add(i);
                }
                else
                {
                    queue.AddForced(i);
                }

                Assert.AreEqual(i, queue.Count);
            }

            int itemNum = 0;

            while (queue.TryTake(out item))
            {
                itemNum++;
                Assert.AreEqual(itemNum, item);
            }

            Assert.AreEqual(999, itemNum);

            Assert.AreEqual(0, queue.Count);
            Assert.IsTrue(queue.IsEmpty);
        }
示例#8
0
        private static TimeSpan RunConcurrentDiskQFile(string name, int elemCount, int addThCount, int takeThCount, int addSpin, int takeSpin)
        {
            if (Directory.Exists("dummy"))
            {
                Directory.Delete("dummy", true);
            }
            Directory.CreateDirectory("dummy");


            DiskQueue <int> col = new DiskQueue <int>("dummy",
                                                      new NonPersistentDiskQueueSegmentFactory <int>(10000, "prefix", new ItemSerializer(), 256, 16),
                                                      10, true);

            //DiskQueue<int> col = new DiskQueue<int>("dummy",
            //    new PersistentDiskQueueSegmentFactory<int>(10000, "prefix", new ItemSerializer(), false, false, 1000, 64),
            //    10, true);

            CancellationTokenSource srcCancel = new CancellationTokenSource();

            Thread[] addThreads  = new Thread[addThCount];
            Thread[] takeThreads = new Thread[takeThCount];

            int        addedElemCount = 0;
            List <int> globalList     = new List <int>();

            Barrier barierStart  = new Barrier(1 + addThreads.Length + takeThreads.Length);
            Barrier barierAdders = new Barrier(1 + addThreads.Length);
            Barrier barierTakers = new Barrier(1 + takeThreads.Length);

            Action addAction = () =>
            {
                barierStart.SignalAndWait();

                int index = 0;
                while ((index = Interlocked.Increment(ref addedElemCount)) <= elemCount)
                {
                    col.Add(index - 1);
                    Thread.SpinWait(addSpin);
                }

                barierAdders.SignalAndWait();
            };


            Action takeAction = () =>
            {
                CancellationToken myToken = srcCancel.Token;
                List <int>        valList = new List <int>(elemCount / takeThCount + 100);

                barierStart.SignalAndWait();

                try
                {
                    while (!srcCancel.IsCancellationRequested)
                    {
                        int val = 0;
                        val = col.Take(myToken);

                        valList.Add(val);
                        Thread.SpinWait(takeSpin);
                    }
                }
                catch (OperationCanceledException)
                {
                }

                int val2 = 0;
                while (col.TryTake(out val2))
                {
                    valList.Add(val2);
                }

                barierTakers.SignalAndWait();

                lock (globalList)
                {
                    globalList.AddRange(valList);
                }
            };

            for (int i = 0; i < addThreads.Length; i++)
            {
                addThreads[i] = new Thread(new ThreadStart(addAction));
            }
            for (int i = 0; i < takeThreads.Length; i++)
            {
                takeThreads[i] = new Thread(new ThreadStart(takeAction));
            }


            for (int i = 0; i < takeThreads.Length; i++)
            {
                takeThreads[i].Start();
            }
            for (int i = 0; i < addThreads.Length; i++)
            {
                addThreads[i].Start();
            }

            barierStart.SignalAndWait();

            Stopwatch sw = Stopwatch.StartNew();

            barierAdders.SignalAndWait();
            srcCancel.Cancel();
            barierTakers.SignalAndWait();
            sw.Stop();

            for (int i = 0; i < addThreads.Length; i++)
            {
                addThreads[i].Join();
            }
            for (int i = 0; i < takeThreads.Length; i++)
            {
                takeThreads[i].Join();
            }

            globalList.Sort();
            if (globalList.Count != elemCount)
            {
                Console.WriteLine("Bad count");
            }

            for (int i = 0; i < globalList.Count; i++)
            {
                if (globalList[i] != i)
                {
                    Console.WriteLine("invalid elements");
                    break;
                }
            }

            if (name != null)
            {
                Console.WriteLine(name + ". DiskQFile. Time = " + sw.ElapsedMilliseconds.ToString() + "ms");
            }

            col.Dispose();
            return(sw.Elapsed);
        }
示例#9
0
        // ======================


        private void PreserveOrderTest(DiskQueue <int> queue, int elemCount)
        {
            Barrier bar = new Barrier(2);
            CancellationTokenSource cancelled = new CancellationTokenSource();
            List <int> takenElems             = new List <int>(elemCount + 1);

            Action addAction = () =>
            {
                int    curElem = 0;
                Random rnd     = new Random(Environment.TickCount + Thread.CurrentThread.ManagedThreadId);

                bar.SignalAndWait();
                while (curElem < elemCount)
                {
                    if (rnd.Next(100) == 0)
                    {
                        queue.AddForced(curElem);
                    }
                    else
                    {
                        queue.Add(curElem);
                    }

                    if (rnd.Next(100) == 0)
                    {
                        Thread.Yield();
                    }
                    SpinWaitHelper.SpinWait(rnd.Next(12));

                    curElem++;
                }

                cancelled.Cancel();
            };

            Action takeAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Thread.CurrentThread.ManagedThreadId);

                bar.SignalAndWait();
                try
                {
                    while (!cancelled.IsCancellationRequested)
                    {
                        takenElems.Add(queue.Take(cancelled.Token));

                        if (rnd.Next(100) == 0)
                        {
                            Thread.Yield();
                        }
                        SpinWaitHelper.SpinWait(rnd.Next(12));
                    }
                }
                catch (OperationCanceledException) { }

                int item = 0;
                while (queue.TryTake(out item))
                {
                    takenElems.Add(item);
                }
            };


            var sw = System.Diagnostics.Stopwatch.StartNew();

            Task addTask  = Task.Factory.StartNew(addAction, TaskCreationOptions.LongRunning);
            Task takeTask = Task.Factory.StartNew(takeAction, TaskCreationOptions.LongRunning);

            Task.WaitAll(addTask, takeTask);

            Assert.AreEqual(elemCount, takenElems.Count);
            for (int i = 0; i < takenElems.Count; i++)
            {
                if (i != takenElems[i])
                {
                    Assert.AreEqual(i, takenElems[i], $"i != takenElems[i], nextItem = {takenElems[i + 1]}");
                }
            }
        }
示例#10
0
        // ==================================

        private void RunComplexTest(DiskQueue <int> q, int elemCount, int thCount)
        {
            int atomicRandom = 0;

            int trackElemCount = elemCount;
            int addFinished    = 0;

            Thread[] threadsTake = new Thread[thCount];
            Thread[] threadsAdd  = new Thread[thCount];

            CancellationTokenSource tokSrc = new CancellationTokenSource();

            List <int> global = new List <int>(elemCount);

            Action addAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2);

                while (true)
                {
                    int item = Interlocked.Decrement(ref trackElemCount);
                    if (item < 0)
                    {
                        break;
                    }

                    if (rnd.Next(100) == 0)
                    {
                        q.AddForced(item);
                    }
                    else
                    {
                        q.Add(item);
                    }


                    int sleepTime = rnd.Next(12);

                    int tmpItem = 0;
                    if (q.TryPeek(out tmpItem) && tmpItem == item)
                    {
                        sleepTime += 15;
                    }

                    if (sleepTime > 0)
                    {
                        SpinWaitHelper.SpinWait(sleepTime);
                    }
                }

                Interlocked.Increment(ref addFinished);
            };


            Action takeAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2);

                List <int> data = new List <int>();

                try
                {
                    while (Volatile.Read(ref addFinished) < thCount)
                    {
                        int tmp = 0;
                        if (q.TryTake(out tmp, -1, tokSrc.Token))
                        {
                            data.Add((int)tmp);
                        }

                        int sleepTime = rnd.Next(12);
                        if (sleepTime > 0)
                        {
                            SpinWaitHelper.SpinWait(sleepTime);
                        }
                    }
                }
                catch (OperationCanceledException) { }

                int tmp2;
                while (q.TryTake(out tmp2))
                {
                    data.Add((int)tmp2);
                }

                lock (global)
                    global.AddRange(data);
            };


            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i] = new Thread(new ThreadStart(takeAction));
            }
            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i] = new Thread(new ThreadStart(addAction));
            }


            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i].Start();
            }
            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i].Start();
            }


            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i].Join();
            }
            tokSrc.Cancel();
            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i].Join();
            }


            Assert.AreEqual(elemCount, global.Count);
            global.Sort();

            for (int i = 0; i < elemCount; i++)
            {
                Assert.AreEqual(i, global[i]);
            }
        }
示例#11
0
        // ======================

        private void ValidateCountTest(DiskQueue <int> queue, CommonSegmentFactory <int> factory, int elemCount)
        {
            Barrier bar = new Barrier(2);
            CancellationTokenSource cancelled = new CancellationTokenSource();
            List <int> takenElems             = new List <int>(elemCount + 1);
            AtomicBool needSync = new AtomicBool();

            Action addAction = () =>
            {
                int    curElem = 0;
                Random rnd     = new Random(Environment.TickCount + Thread.CurrentThread.ManagedThreadId);

                bar.SignalAndWait();
                while (curElem < elemCount)
                {
                    bool itemAdded = true;
                    if (rnd.Next(100) == 0)
                    {
                        queue.AddForced(curElem);
                    }
                    else if (needSync.Value)
                    {
                        itemAdded = queue.TryAdd(curElem);
                    }
                    else
                    {
                        queue.Add(curElem);
                    }

                    if (rnd.Next(100) == 0)
                    {
                        Thread.Yield();
                    }
                    SpinWaitHelper.SpinWait(rnd.Next(12));

                    if (itemAdded)
                    {
                        curElem++;
                    }

                    Assert.IsTrue(itemAdded || needSync.Value);

                    if (curElem % 1000 == 0)
                    {
                        needSync.Value = true;
                    }
                    if (needSync.Value && bar.ParticipantsRemaining == 1)
                    {
                        Assert.AreEqual(factory.SumCountFromAllocated(), queue.Count);
                        needSync.Value = false;
                        bar.SignalAndWait();
                    }
                }

                cancelled.Cancel();
            };

            Action takeAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Thread.CurrentThread.ManagedThreadId);

                bar.SignalAndWait();
                try
                {
                    while (!cancelled.IsCancellationRequested)
                    {
                        takenElems.Add(queue.Take(cancelled.Token));

                        if (rnd.Next(100) == 0)
                        {
                            Thread.Yield();
                        }
                        SpinWaitHelper.SpinWait(rnd.Next(12));

                        if (needSync.Value)
                        {
                            bar.SignalAndWait(cancelled.Token);
                        }
                    }
                }
                catch (OperationCanceledException) { }

                int item = 0;
                while (queue.TryTake(out item))
                {
                    takenElems.Add(item);
                }
            };


            var sw = System.Diagnostics.Stopwatch.StartNew();

            Task addTask  = Task.Factory.StartNew(addAction, TaskCreationOptions.LongRunning);
            Task takeTask = Task.Factory.StartNew(takeAction, TaskCreationOptions.LongRunning);

            Task.WaitAll(addTask, takeTask);

            Assert.AreEqual(elemCount, takenElems.Count);
            for (int i = 0; i < takenElems.Count; i++)
            {
                if (i != takenElems[i])
                {
                    Assert.AreEqual(i, takenElems[i], $"i != takenElems[i], nextItem = {takenElems[i + 1]}");
                }
            }
        }