コード例 #1
0
        private static void SplitQueue(UnsafeMPMCQueue *q)
        {
            //Wrap tail back to 0
            for (int i = 0; i < 5; i++)
            {
                UnsafeMPMCQueue.TryEnqueue(q, 111);
            }

            //First half
            for (int i = 0; i < 5; i++)
            {
                UnsafeMPMCQueue.TryEnqueue(q, i);
            }

            //Move head by 5
            for (int i = 0; i < 5; i++)
            {
                UnsafeMPMCQueue.TryDequeue <int>(q, out int num);
            }

            //Second half (head and tail are now both 5)
            for (int i = 5; i < 10; i++)
            {
                UnsafeMPMCQueue.TryEnqueue(q, i);
            }

            //Circular buffer now "ends" in the middle of the underlying array
        }
コード例 #2
0
        public void IteratorConcurrencyTest()
        {
            var q     = UnsafeMPMCQueue.Allocate <int>(16000);
            int count = 10000;

            Thread writer = new Thread(() =>
            {
                for (int i = 0; i < count;)
                {
                    if (UnsafeMPMCQueue.TryEnqueue(q, i))
                    {
                        i++;
                    }
                }
            });

            writer.Start();

            Thread.Sleep(3); // Wait some arbitrary time so there's data to enumerate

            var enumerator = UnsafeMPMCQueue.GetEnumerator <int>(q);
            int num        = 0;

            foreach (int i in enumerator)
            {
                Assert.AreEqual(num++, i);
            }

            writer.Join();

            Assert.AreEqual(count, UnsafeMPMCQueue.GetCount(q));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #3
0
        public void IteratorSplitTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(10);

            // Wrap tail around
            SplitQueue(q);

            for (int i = 10; i < 50; i++)
            {
                UnsafeMPMCQueue.TryEnqueue <int>(q, i);
            }

            // Iterator should start from the head.
            int num = 0;

            foreach (int i in UnsafeMPMCQueue.GetEnumerator <int>(q))
            {
                Assert.AreEqual(num, i);
                num++;
            }

            // Iterated 50 items
            Assert.AreEqual(50, num);
            UnsafeMPMCQueue.Free(q);
        }
コード例 #4
0
        //Demonstration that this queue is SPSC
        public void SPSCConcurrencyTest()
        {
            var q     = UnsafeMPMCQueue.Allocate <ComplexType>(16);
            int count = 10000;


            Thread reader = new Thread(() =>
            {
                for (int i = 0; i < count;)
                {
                    if (UnsafeMPMCQueue.TryDequeue(q, out ComplexType num))
                    {
                        Assert.IsTrue(num.Equals(new ComplexType((ushort)i)));
                        i++;
                    }
                }
            });

            reader.Start();

            for (int i = 0; i < count;)
            {
                if (UnsafeMPMCQueue.TryEnqueue(q, new ComplexType((ushort)i)))
                {
                    i++;
                }
            }

            reader.Join();

            UnsafeMPMCQueue.Free(q);
        }
コード例 #5
0
        public void TryActionTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(16);

            //Inserts 10 items.
            SplitQueue(q);

            //Insert 6 more to fill the queue
            for (int i = 0; i < 6; i++)
            {
                UnsafeMPMCQueue.TryEnqueue(q, 999);
            }

            Assert.IsTrue(UnsafeMPMCQueue.TryPeek(q, out int result));
            Assert.AreEqual(0, result);

            for (int i = 0; i < 10; i++)
            {
                Assert.IsTrue(UnsafeMPMCQueue.TryDequeue(q, out int val));
                Assert.AreEqual(i, val);
            }

            //Empty 6 last items
            for (int i = 0; i < 6; i++)
            {
                Assert.IsTrue(UnsafeMPMCQueue.TryDequeue(q, out int val));
            }

            //Empty queue
            Assert.IsFalse(UnsafeMPMCQueue.TryPeek(q, out int res));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #6
0
        public void InvalidTypeTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(10);

            Assert.Catch <AssertException>(() => { UnsafeMPMCQueue.TryEnqueue <float>(q, 162); });

            UnsafeMPMCQueue.Free(q);
        }
コード例 #7
0
        public void ConstructorTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(10);

            Assert.AreEqual(0, UnsafeMPMCQueue.GetCount(q));
            Assert.AreEqual(16, UnsafeMPMCQueue.GetCapacity(q));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #8
0
        public void ClearTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(16);

            //Inserts 10 items.
            SplitQueue(q);

            Assert.AreEqual(10, UnsafeMPMCQueue.GetCount(q));
            UnsafeMPMCQueue.Clear(q);
            Assert.AreEqual(0, UnsafeMPMCQueue.GetCount(q));

            Assert.IsTrue(UnsafeMPMCQueue.IsEmpty <int>(q));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #9
0
        public void EnqueueTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(100);

            for (int i = 0; i < 100; i++)
            {
                UnsafeMPMCQueue.TryEnqueue(q, i * i);
            }

            Assert.AreEqual(100, UnsafeMPMCQueue.GetCount(q));

            UnsafeMPMCQueue.Clear(q);

            Assert.AreEqual(0, UnsafeMPMCQueue.GetCount(q));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #10
0
        public void DequeueTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(10);

            for (int i = 0; i < 10; i++)
            {
                UnsafeMPMCQueue.TryEnqueue(q, i * i);
            }


            for (int i = 0; i < 10; i++)
            {
                UnsafeMPMCQueue.TryDequeue(q, out int num);
                Assert.AreEqual(i * i, num);
            }

            UnsafeMPMCQueue.Free(q);
        }
コード例 #11
0
        public void ExpandFixedTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(64, true);

            // Fill buffer to capacity
            for (int i = 0; i < 64;)
            {
                if (UnsafeMPMCQueue.TryEnqueue(q, i))
                {
                    i++;
                }
            }


            // Buffer is full, can no longer insert.
            Assert.IsFalse(UnsafeMPMCQueue.TryEnqueue(q, 10));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #12
0
        public void ExpandTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>();

            SplitQueue(q);

            // Fill buffer beyond capacity
            for (int i = 0; i < 100;)
            {
                if (UnsafeMPMCQueue.TryEnqueue(q, 999))
                {
                    i++;
                }
            }


            Assert.AreEqual(110, UnsafeMPMCQueue.GetCount(q));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #13
0
        public void PeekTest()
        {
            var q = UnsafeMPMCQueue.Allocate <int>(10);

            for (int i = 0; i < 10; i++)
            {
                UnsafeMPMCQueue.TryEnqueue(q, (int)Math.Pow(i + 2, 2));
            }

            for (int i = 0; i < 10; i++)
            {
                UnsafeMPMCQueue.TryPeek(q, out int result);
                Assert.AreEqual(4, result);
            }

            //Verify no items are dequeued
            Assert.AreEqual(10, UnsafeMPMCQueue.GetCount(q));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #14
0
        public void ClearFixedTest()
        {
            int size = 128; // Power of two.
            var q    = UnsafeMPMCQueue.Allocate <int>(size, true);

            //Inserts 10 items.
            SplitQueue(q);

            Assert.AreEqual(10, UnsafeMPMCQueue.GetCount(q));
            Assert.AreEqual(size, UnsafeMPMCQueue.GetCapacity(q));

            UnsafeMPMCQueue.Clear(q);

            Assert.AreEqual(0, UnsafeMPMCQueue.GetCount(q));
            // Queue capacity needs to remain unchanged after clear.
            Assert.AreEqual(size, UnsafeMPMCQueue.GetCapacity(q));

            Assert.IsTrue(UnsafeMPMCQueue.IsEmpty <int>(q));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #15
0
        // Demonstration that this queue is MPSC
        public void MPSCConcurrencyTest()
        {
            var q     = UnsafeMPMCQueue.Allocate <int>(16000);
            int count = 10000;

            Thread writer = new Thread(() =>
            {
                for (int i = 0; i < count / 2;)
                {
                    if (UnsafeMPMCQueue.TryEnqueue(q, i))
                    {
                        i++;
                    }
                }
            });

            Thread writer2 = new Thread(() =>
            {
                for (int i = 0; i < count / 2;)
                {
                    if (UnsafeMPMCQueue.TryEnqueue(q, i))
                    {
                        i++;
                    }
                }
            });

            writer.Start();
            writer2.Start();


            writer.Join();
            writer2.Join();

            Assert.AreEqual(count, UnsafeMPMCQueue.GetCount(q));

            UnsafeMPMCQueue.Free(q);
        }
コード例 #16
0
        public void IteratorSingleSegmentTest()
        {
            UnsafeMPMCQueue *q = UnsafeMPMCQueue.Allocate <int>(10);

            for (int i = 0; i < 10; i++)
            {
                UnsafeMPMCQueue.TryEnqueue <int>(q, i);
            }

            var enumerator = UnsafeMPMCQueue.GetEnumerator <int>(q);

            int ii = 0;

            foreach (int num in enumerator)
            {
                Assert.AreEqual(ii, num);
                ii++;
            }

            Assert.AreEqual(10, ii);

            UnsafeMPMCQueue.Free(q);
        }
コード例 #17
0
        public void CopyTo(T[] array, int arrayIndex)
        {
            if (array == null)
            {
                throw new ArgumentNullException(nameof(array));
            }

            if ((uint)arrayIndex > array.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(arrayIndex));
            }

            if (array.Length - arrayIndex < Count)
            {
                throw new ArgumentException("Insufficient space in the target location to copy the information.");
            }

            if (array.Length == 0)
            {
                return;
            }

            UnsafeMPMCQueue.ToArray <T>(m_inner).CopyTo(array, arrayIndex);
        }
コード例 #18
0
        public void IteratorMultiSegmentTest()
        {
            UnsafeMPMCQueue *q = UnsafeMPMCQueue.Allocate <int>(8);

            // Enqueue large amount so we get multiple segments.
            for (int i = 0; i < 50; i++)
            {
                UnsafeMPMCQueue.TryEnqueue(q, i);
            }

            var enumerator = UnsafeMPMCQueue.GetEnumerator <int>(q);

            int ii = 0;

            foreach (int num in enumerator)
            {
                Assert.AreEqual(ii, num);
                ii++;
            }

            Assert.AreEqual(50, ii);

            UnsafeMPMCQueue.Free(q);
        }
コード例 #19
0
 public bool TryDequeue(out T result)
 {
     return(UnsafeMPMCQueue.TryDequeue <T>(m_inner, out result));
 }
コード例 #20
0
 public void Clear()
 {
     UnsafeMPMCQueue.Clear(m_inner);
 }
コード例 #21
0
 public T[] ToArray()
 {
     return(UnsafeMPMCQueue.ToArray <T>(m_inner));
 }
コード例 #22
0
 public UnsafeMPMCQueue.Enumerator <T> GetEnumerator()
 {
     return(UnsafeMPMCQueue.GetEnumerator <T>(m_inner));
 }
コード例 #23
0
 IEnumerator IEnumerable.GetEnumerator()
 {
     return(UnsafeMPMCQueue.GetEnumerator <T>(m_inner));
 }
コード例 #24
0
 public void Dispose()
 {
     UnsafeMPMCQueue.Free(m_inner);
     m_inner = null;
 }
コード例 #25
0
 public NativeMPMCQueue(int segmentSize, bool fixedSize)
 {
     m_inner = UnsafeMPMCQueue.Allocate <T>(segmentSize, fixedSize);
 }
コード例 #26
0
 public bool TryEnqueue(T item)
 {
     return(UnsafeMPMCQueue.TryEnqueue <T>(m_inner, item));
 }
コード例 #27
0
 public bool TryPeek(out T result)
 {
     return(UnsafeMPMCQueue.TryPeek <T>(m_inner, out result));
 }