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 }
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); }
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); }
//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); }
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); }
public void InvalidTypeTest() { var q = UnsafeMPMCQueue.Allocate <int>(10); Assert.Catch <AssertException>(() => { UnsafeMPMCQueue.TryEnqueue <float>(q, 162); }); UnsafeMPMCQueue.Free(q); }
public void ConstructorTest() { var q = UnsafeMPMCQueue.Allocate <int>(10); Assert.AreEqual(0, UnsafeMPMCQueue.GetCount(q)); Assert.AreEqual(16, UnsafeMPMCQueue.GetCapacity(q)); UnsafeMPMCQueue.Free(q); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
// 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); }
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); }
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); }
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); }
public bool TryDequeue(out T result) { return(UnsafeMPMCQueue.TryDequeue <T>(m_inner, out result)); }
public void Clear() { UnsafeMPMCQueue.Clear(m_inner); }
public T[] ToArray() { return(UnsafeMPMCQueue.ToArray <T>(m_inner)); }
public UnsafeMPMCQueue.Enumerator <T> GetEnumerator() { return(UnsafeMPMCQueue.GetEnumerator <T>(m_inner)); }
IEnumerator IEnumerable.GetEnumerator() { return(UnsafeMPMCQueue.GetEnumerator <T>(m_inner)); }
public void Dispose() { UnsafeMPMCQueue.Free(m_inner); m_inner = null; }
public NativeMPMCQueue(int segmentSize, bool fixedSize) { m_inner = UnsafeMPMCQueue.Allocate <T>(segmentSize, fixedSize); }
public bool TryEnqueue(T item) { return(UnsafeMPMCQueue.TryEnqueue <T>(m_inner, item)); }
public bool TryPeek(out T result) { return(UnsafeMPMCQueue.TryPeek <T>(m_inner, out result)); }