private static void SplitQueue(UnsafeQueue *q)
        {
            //Wrap tail back to 0
            for (int i = 0; i < 5; i++)
            {
                UnsafeQueue.Enqueue(q, 111);
            }

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

            //Move head by 5
            for (int i = 0; i < 5; i++)
            {
                UnsafeQueue.Dequeue <int>(q);
            }

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

            //Circular buffer now "ends" in the middle of the underlying array
        }
示例#2
0
        public static void Enqueue <T>(UnsafeQueue *queue, T item) where T : unmanaged
        {
            Assert.Check(queue != null);
            Assert.Check(queue->_items.Ptr != null);

            var count = queue->_count;
            var items = queue->_items;

            if (count == items.Length)
            {
                if (items.Dynamic == 1)
                {
                    Expand(queue, items.Length * 2);

                    // re-assign items after capacity expanded
                    items = queue->_items;
                }
                else
                {
                    throw new InvalidOperationException(QUEUE_FIXED_SIZE_FULL);
                }
            }

            var tail = queue->_tail;

            *(T *)UnsafeBuffer.Element(items.Ptr, tail, items.Stride) = item;

            // increment count and head index
            queue->_count = (count + 1);
            queue->_tail  = (tail + 1) % items.Length;
        }
示例#3
0
        public static void Enqueue <T>(UnsafeQueue *queue, T item) where T : unmanaged
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == queue->_typeHandle);

            var count = queue->_count;
            var items = queue->_items;

            if (count == items.Length)
            {
                if (items.Dynamic == 1)
                {
                    Expand(queue, items.Length * 2);

                    // re-assign items after capacity expanded
                    items = queue->_items;
                }
                else
                {
                    throw new InvalidOperationException(ThrowHelper.InvalidOperation_CollectionFull);
                }
            }

            var tail = queue->_tail;

            *items.Element <T>(tail) = item;

            // increment count and head index
            queue->_count++;
            MoveNext(items.Length, ref queue->_tail);
        }
示例#4
0
        public static void CopyTo <T>(UnsafeQueue *queue, void *destination, int destinationIndex) where T : unmanaged
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == queue->_typeHandle);
            UDebug.Assert(destination != null);
            UDebug.Assert(destinationIndex > -1);


            int numToCopy = queue->_count;

            if (numToCopy == 0)
            {
                return;
            }

            int bufferLength = queue->_items.Length;
            int head         = queue->_head;

            int firstPart = Math.Min(bufferLength - head, numToCopy);

            UnsafeBuffer.CopyTo <T>(queue->_items, head, destination, destinationIndex, firstPart);
            numToCopy -= firstPart;
            if (numToCopy > 0)
            {
                UnsafeBuffer.CopyTo <T>(queue->_items, 0, destination, destinationIndex + bufferLength - head, numToCopy);
            }
        }
示例#5
0
        public static void Clear(UnsafeQueue *queue)
        {
            Assert.Check(queue != null);
            Assert.Check(queue->_items.Ptr != null);

            queue->_head = 0;
            queue->_tail = 0;
        }
示例#6
0
        public static UnsafeList.Enumerator <T> GetEnumerator <T>(UnsafeQueue *queue) where T : unmanaged
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == queue->_typeHandle);

            return(new UnsafeList.Enumerator <T>(queue->_items, queue->_head, queue->_count));
        }
示例#7
0
        public static void Clear(UnsafeQueue *queue)
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);

            queue->_head  = 0;
            queue->_tail  = 0;
            queue->_count = 0;
        }
示例#8
0
        public static bool TryEnqueue <T>(UnsafeQueue *queue, T item) where T : unmanaged
        {
            if (queue->_count == queue->_items.Length && queue->_items.Dynamic == 0)
            {
                return(false);
            }

            Enqueue <T>(queue, item);
            return(true);
        }
示例#9
0
        public static T Peek <T>(UnsafeQueue *queue) where T : unmanaged
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == queue->_typeHandle);

            if (queue->_count == 0)
            {
                throw new InvalidOperationException(ThrowHelper.InvalidOperation_EmptyQueue);
            }

            return(*queue->_items.Element <T>(queue->_head));
        }
示例#10
0
        public static bool TryPeek <T>(UnsafeQueue *queue, out T result) where T : unmanaged
        {
            Assert.Check(queue != null);
            Assert.Check(queue->_items.Ptr != null);

            if (queue->_count == 0)
            {
                result = default;
                return(false);
            }

            result = *PeekPtr <T>(queue);
            return(true);
        }
示例#11
0
        public static T *PeekPtr <T>(UnsafeQueue *queue) where T : unmanaged
        {
            Assert.Check(queue != null);
            Assert.Check(queue->_items.Ptr != null);

            if (queue->_count == 0)
            {
                throw new InvalidOperationException(QUEUE_EMPTY);
            }

            var items = queue->_items;

            return((T *)UnsafeBuffer.Element(items.Ptr, queue->_head, items.Stride));
        }
示例#12
0
        public static bool TryPeek <T>(UnsafeQueue *queue, out T result) where T : unmanaged
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == queue->_typeHandle);

            if (queue->_count == 0)
            {
                result = default;
                return(false);
            }

            //Don't call Peek as this would perform the same check twice!
            result = *queue->_items.Element <T>(queue->_head);
            return(true);
        }
示例#13
0
        public static void Free(UnsafeQueue *queue)
        {
            if (queue == null)
            {
                return;
            }

            // not fixed, we need to free items separtely
            if (queue->_items.Dynamic == 1)
            {
                UnsafeBuffer.Free(&queue->_items);
            }

            // clear queue memory (just in case)
            *queue = default;

            // free queue memory, if this is a fixed queue it frees the items memory at the same time
            Native.Free(queue);
        }
示例#14
0
        // expand algorithm from first answer here: https://codereview.stackexchange.com/questions/129819/queue-resizing-array-implementation
        static void Expand(UnsafeQueue *queue, int capacity)
        {
            Assert.Check(capacity > 0);

            // queue has to be dynamic and capacity we're going to have to be larger
            Assert.Check(queue->_items.Dynamic == 1);
            Assert.Check(queue->_items.Length < capacity);

            // new buffer for elements
            UnsafeBuffer newItems = default;

            // initialize to double size of existing one
            UnsafeBuffer.InitDynamic(&newItems, capacity, queue->_items.Stride);

            if (queue->_count > 0)
            {
                // when head is 'ahead' or at tail it means that we're wrapping around
                if (queue->_head >= queue->_tail)
                {
                    // so we need to copy head first, from (head, length-head) into (0, length-head)
                    UnsafeBuffer.Copy(queue->_items, queue->_head, newItems, 0, queue->_items.Length - queue->_head);

                    // and then copy tail, from (0, tail) into (length-head, tail)
                    UnsafeBuffer.Copy(queue->_items, 0, newItems, queue->_items.Length - queue->_head, queue->_tail);
                }
                else
                {
                    // if not, we can just copy from (tail, count) into (0, count)
                    UnsafeBuffer.Copy(queue->_items, queue->_head, newItems, 0, queue->_count);
                }
            }

            // free existing buffer
            UnsafeBuffer.Free(&queue->_items);

            queue->_items = newItems;
            queue->_head  = 0;
            queue->_tail  = queue->_count % queue->_items.Length;
        }
示例#15
0
        public static T Dequeue <T>(UnsafeQueue *queue) where T : unmanaged
        {
            Assert.Check(queue != null);
            Assert.Check(queue->_items.Ptr != null);

            var count = queue->_count;

            if (count == 0)
            {
                throw new InvalidOperationException(QUEUE_EMPTY);
            }

            var head  = queue->_head;
            var items = queue->_items;

            // grab result
            T result = *(T *)UnsafeBuffer.Element(items.Ptr, head, items.Stride);

            // decrement count and tail index
            queue->_count = (count - 1);
            queue->_head  = (head + 1) % items.Length;
            return(result);
        }
示例#16
0
        public static bool TryDequeue <T>(UnsafeQueue *queue, out T result) where T : unmanaged
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == queue->_typeHandle);

            if (queue->_count == 0)
            {
                result = default;
                return(false);
            }

            var head  = queue->_head;
            var items = queue->_items;

            // grab result
            result = *items.Element <T>(head);

            // decrement count and head index
            queue->_count--;
            MoveNext(items.Length, ref queue->_head);
            return(true);
        }
示例#17
0
        public static bool Contains <T>(UnsafeQueue *queue, T item) where T : unmanaged, IEquatable <T>
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == queue->_typeHandle);

            int count = queue->_count;
            int head  = queue->_head;
            int tail  = queue->_tail;

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

            if (head < tail)
            {
                return(UnsafeBuffer.IndexOf(queue->_items, item, head, count) > -1);
            }

            return(UnsafeBuffer.IndexOf(queue->_items, item, head, queue->_items.Length - head) > -1 ||
                   UnsafeBuffer.IndexOf(queue->_items, item, 0, tail) > -1);
        }
示例#18
0
        public static T Dequeue <T>(UnsafeQueue *queue) where T : unmanaged
        {
            UDebug.Assert(queue != null);
            UDebug.Assert(queue->_items.Ptr != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == queue->_typeHandle);

            var count = queue->_count;

            if (count == 0)
            {
                throw new InvalidOperationException(ThrowHelper.InvalidOperation_EmptyQueue);
            }

            var head  = queue->_head;
            var items = queue->_items;

            // grab result
            T result = *items.Element <T>(head);

            // decrement count and head index
            queue->_count--;
            MoveNext(items.Length, ref queue->_head);
            return(result);
        }
 public NativeQueue(int capacity)
 {
     m_inner = UnsafeQueue.Allocate <T>(capacity, false);
 }
示例#20
0
 public static UnsafeList.Iterator <T> GetIterator <T>(UnsafeQueue *queue) where T : unmanaged
 {
     return(new UnsafeList.Iterator <T>(queue->_items, queue->_head, queue->_count));
 }
示例#21
0
 public static int GetCapacity(UnsafeQueue *queue)
 {
     UDebug.Assert(queue != null);
     UDebug.Assert(queue->_items.Ptr != null);
     return(queue->_items.Length);
 }
示例#22
0
 public static T Peek <T>(UnsafeQueue *queue) where T : unmanaged
 {
     return(*PeekPtr <T>(queue));
 }
示例#23
0
 public static int GetCount(UnsafeQueue *queue)
 {
     UDebug.Assert(queue != null);
     UDebug.Assert(queue->_items.Ptr != null);
     return(queue->_count);
 }
示例#24
0
 public static bool IsFixedSize(UnsafeQueue *queue)
 {
     Assert.Check(queue != null);
     return(queue->_items.Dynamic == 0);
 }
示例#25
0
 public static int Count(UnsafeQueue *queue)
 {
     Assert.Check(queue != null);
     Assert.Check(queue->_items.Ptr != null);
     return(queue->_count);
 }
示例#26
0
 public static int Capacity(UnsafeQueue *queue)
 {
     Assert.Check(queue != null);
     Assert.Check(queue->_items.Ptr != null);
     return(queue->_items.Length);
 }
 public NativeQueue(int capacity, bool fixedSize)
 {
     m_inner = UnsafeQueue.Allocate <T>(capacity, fixedSize);
 }