public static UnsafeRingBuffer *Allocate(int capacity, int stride, bool overwrite)
        {
            Assert.Check(capacity > 0);
            Assert.Check(stride > 0);

            // fixedSize means we are allocating the memory for the collection header and the items in it as one block
            var alignment = AllocHelper.GetAlignmentForArrayElement(stride);

            // align header size to the elements alignment
            var sizeOfHeader = AllocHelper.RoundUpToAlignment(sizeof(UnsafeRingBuffer), alignment);
            var sizeOfBuffer = stride * capacity;

            // allocate memory for list and array with the correct alignment
            var ptr = AllocHelper.MallocAndClear(sizeOfHeader + sizeOfBuffer, alignment);

            // grab header ptr
            var ring = (UnsafeRingBuffer *)ptr;

            // initialize fixed buffer from same block of memory as the collection, offset by sizeOfHeader
            UnsafeBuffer.InitFixed(&ring->_items, (byte *)ptr + sizeOfHeader, capacity, stride);

            // initialize count to 0
            ring->_count     = 0;
            ring->_overwrite = overwrite;
            return(ring);
        }
示例#2
0
        public static UnsafeHashSet *Allocate(int capacity, int valStride, bool fixedSize = false)
        {
            var entryStride = sizeof(UnsafeHashCollection.Entry);

            // round capacity up to next prime
            capacity = UnsafeHashCollection.GetNextPrime(capacity);

            // this has to be true
            Assert.Check(entryStride == 16);

            var valAlignment = Native.GetAlignment(valStride);

            // the alignment for entry/key/val, we can't have less than ENTRY_ALIGNMENT
            // bytes alignment because entries are 16 bytes with 1 x pointer + 2 x 4 byte integers
            var alignment = Math.Max(UnsafeHashCollection.Entry.ALIGNMENT, valAlignment);

            // calculate strides for all elements
            valStride   = Native.RoundToAlignment(valStride, alignment);
            entryStride = Native.RoundToAlignment(sizeof(UnsafeHashCollection.Entry), alignment);

            // dictionary ptr
            UnsafeHashSet *set;

            if (fixedSize)
            {
                var sizeOfHeader        = Native.RoundToAlignment(sizeof(UnsafeHashSet), alignment);
                var sizeOfBucketsBuffer = Native.RoundToAlignment(sizeof(UnsafeHashCollection.Entry * *) * capacity, alignment);
                var sizeofEntriesBuffer = (entryStride + valStride) * capacity;

                // allocate memory
                var ptr = Native.MallocAndClear(sizeOfHeader + sizeOfBucketsBuffer + sizeofEntriesBuffer, alignment);

                // start of memory is the dict itself
                set = (UnsafeHashSet *)ptr;

                // buckets are offset by header size
                set->_collection.Buckets = (UnsafeHashCollection.Entry * *)((byte *)ptr + sizeOfHeader);

                // initialize fixed buffer
                UnsafeBuffer.InitFixed(&set->_collection.Entries, (byte *)ptr + (sizeOfHeader + sizeOfBucketsBuffer), capacity, entryStride + valStride);
            }
            else
            {
                // allocate dict, buckets and entries buffer separately
                set = Native.MallocAndClear <UnsafeHashSet>();
                set->_collection.Buckets = (UnsafeHashCollection.Entry * *)Native.MallocAndClear(sizeof(UnsafeHashCollection.Entry * *) * capacity, sizeof(UnsafeHashCollection.Entry * *));

                // init dynamic buffer
                UnsafeBuffer.InitDynamic(&set->_collection.Entries, capacity, entryStride + valStride);
            }

            set->_collection.FreeCount = 0;
            set->_collection.UsedCount = 0;
            set->_collection.KeyOffset = entryStride;

            return(set);
        }
示例#3
0
        public static UnsafeOrderedSet *Allocate(int capacity, int valStride, bool fixedSize = false)
        {
            var entryStride  = sizeof(UnsafeOrderedCollection.Entry);
            var valAlignment = Native.GetAlignment(valStride);

            // the alignment for entry/key/val, we can't have less than ENTRY_ALIGNMENT
            // bytes alignment because entries are 12 bytes with 3 x 32 bit integers
            var alignment = Math.Max(UnsafeOrderedCollection.Entry.ALIGNMENT, valAlignment);

            // calculate strides for all elements
            valStride   = Native.RoundToAlignment(valStride, alignment);
            entryStride = Native.RoundToAlignment(entryStride, alignment);

            // dictionary ptr
            UnsafeOrderedSet *set;

            if (fixedSize)
            {
                var sizeOfHeader        = Native.RoundToAlignment(sizeof(UnsafeOrderedSet), alignment);
                var sizeofEntriesBuffer = (entryStride + valStride) * capacity;

                // allocate memory
                var ptr = Native.MallocAndClear(sizeOfHeader + sizeofEntriesBuffer, alignment);

                // start of memory is the set itself
                set = (UnsafeOrderedSet *)ptr;

                // initialize fixed buffer
                UnsafeBuffer.InitFixed(&set->_collection.Entries, (byte *)ptr + sizeOfHeader, capacity, entryStride + valStride);
            }
            else
            {
                // allocate set separately
                set = Native.MallocAndClear <UnsafeOrderedSet>();

                // init dynamic buffer
                UnsafeBuffer.InitDynamic(&set->_collection.Entries, capacity, entryStride + valStride);
            }

            set->_collection.FreeCount = 0;
            set->_collection.UsedCount = 0;
            set->_collection.KeyOffset = entryStride;

            return(set);
        }
示例#4
0
        public static UnsafeStack *Allocate(int capacity, int stride, bool fixedSize = false)
        {
            Assert.Check(capacity > 0);
            Assert.Check(stride > 0);

            UnsafeStack *stack;

            // fixedSize stack means we are allocating the memory
            // for the stack header and the items in it as one block
            if (fixedSize)
            {
                var alignment = AllocHelper.GetAlignmentForArrayElement(stride);

                // align stack header size to the elements alignment
                var sizeOfStack = AllocHelper.RoundUpToAlignment(sizeof(UnsafeStack), alignment);
                var sizeOfArray = stride * capacity;

                // allocate memory for stack and array with the correct alignment
                var ptr = AllocHelper.MallocAndClear(sizeOfStack + sizeOfArray, alignment);

                // grab stack ptr
                stack = (UnsafeStack *)ptr;

                // initialize fixed buffer from same block of memory as the stack
                UnsafeBuffer.InitFixed(&stack->_items, (byte *)ptr + sizeOfStack, capacity, stride);
            }

            // dynamic sized stack means we're allocating the stack header
            // and its memory separately
            else
            {
                // allocate stack separately
                stack = AllocHelper.MallocAndClear <UnsafeStack>();

                // initialize dynamic buffer with separate memory
                UnsafeBuffer.InitDynamic(&stack->_items, capacity, stride);
            }

            // just safety, make sure count is 0
            stack->_count = 0;

            return(stack);
        }
示例#5
0
        public static UnsafeHeapMax *Allocate(int capacity, int keyStride, int valStride, bool fixedSize = false)
        {
            capacity += 1;

            // get alignment for key/val
            var keyAlignment = Native.GetAlignment(keyStride);
            var valAlignment = Native.GetAlignment(valStride);

            // pick the max one as our alignment
            var alignment = Math.Max(keyAlignment, valAlignment);

            // align sizes to their respective alignments
            keyStride = Native.RoundToAlignment(keyStride, alignment);
            valStride = Native.RoundToAlignment(valStride, alignment);

            UnsafeHeapMax *heap;

            if (fixedSize)
            {
                var sizeOfHeader = Native.RoundToAlignment(sizeof(UnsafeHeapMax), alignment);
                var sizeOfBuffer = (keyStride + valStride) * capacity;

                var ptr = Native.MallocAndClear(sizeOfHeader + sizeOfBuffer, alignment);

                // heap pointer
                heap = (UnsafeHeapMax *)ptr;

                // initialize our fixed buffer
                UnsafeBuffer.InitFixed(&heap->_items, (byte *)ptr + sizeOfHeader, capacity, keyStride + valStride);
            }
            else
            {
                heap = Native.MallocAndClear <UnsafeHeapMax>();

                // dynamic buffer (separate memory)
                UnsafeBuffer.InitDynamic(&heap->_items, capacity, keyStride + valStride);
            }

            heap->_count     = 1;
            heap->_keyStride = keyStride;
            return(heap);
        }
示例#6
0
        public static UnsafeQueue *Allocate(int capacity, int stride, bool fixedSize = false)
        {
            Assert.Check(capacity > 0);
            Assert.Check(stride > 0);

            UnsafeQueue *queue;

            // fixedSize queue means we are allocating the memory for the header and the items in it as one block
            if (fixedSize)
            {
                var alignment   = Native.GetAlignment(stride);
                var sizeOfQueue = Native.RoundToAlignment(sizeof(UnsafeQueue), alignment);
                var sizeOfArray = stride * capacity;

                var ptr = Native.MallocAndClear(sizeOfQueue + sizeOfArray, alignment);

                // cast ptr to queue
                queue = (UnsafeQueue *)ptr;

                // initialize fixed buffer from same block of memory as the stack
                UnsafeBuffer.InitFixed(&queue->_items, (byte *)ptr + sizeOfQueue, capacity, stride);
            }

            // dynamic sized queue means we're allocating the stack header and its memory separately
            else
            {
                // allocate memory for queue
                queue = Native.MallocAndClear <UnsafeQueue>();

                // initialize dynamic buffer with separate memory
                UnsafeBuffer.InitDynamic(&queue->_items, capacity, stride);
            }

            queue->_head  = 0;
            queue->_tail  = 0;
            queue->_count = 0;

            return(queue);
        }
示例#7
0
        public static UnsafeList *Allocate(int capacity, int stride, bool fixedSize = false)
        {
            Assert.Check(capacity > 0);
            Assert.Check(stride > 0);

            UnsafeList *list;

            // fixedSize means we are allocating the memory for the collection header and the items in it as one block
            if (fixedSize)
            {
                var alignment = AllocHelper.GetAlignmentForArrayElement(stride);

                // align header size to the elements alignment
                var sizeOfHeader = AllocHelper.RoundUpToAlignment(sizeof(UnsafeList), alignment);
                var sizeOfBuffer = stride * capacity;

                // allocate memory for list and array with the correct alignment
                var ptr = AllocHelper.MallocAndClear(sizeOfHeader + sizeOfBuffer, alignment);

                // grab header ptr
                list = (UnsafeList *)ptr;

                // initialize fixed buffer from same block of memory as the collection, offset by sizeOfHeader
                UnsafeBuffer.InitFixed(&list->_items, (byte *)ptr + sizeOfHeader, capacity, stride);
            }
            else
            {
                // allocate collection separately
                list = AllocHelper.MallocAndClear <UnsafeList>();

                // initialize dynamic buffer with separate memory
                UnsafeBuffer.InitDynamic(&list->_items, capacity, stride);
            }

            list->_count = 0;
            return(list);
        }
示例#8
0
        public static UnsafeHashMap *Allocate(int capacity, int keyStride, int valStride, bool fixedSize = false)
        {
            var entryStride = sizeof(UnsafeHashCollection.Entry);

            // round capacity up to next prime
            capacity = UnsafeHashCollection.GetNextPrime(capacity);

            // this has to be true
            Assert.Check(entryStride == 16);

            var keyAlignment = AllocHelper.GetAlignmentForArrayElement(keyStride);
            var valAlignment = AllocHelper.GetAlignmentForArrayElement(valStride);

            // the alignment for entry/key/val, we can't have less than ENTRY_ALIGNMENT
            // bytes alignment because entries are 8 bytes with 2 x 32 bit integers
            var alignment = Math.Max(UnsafeHashCollection.Entry.ALIGNMENT, Math.Max(keyAlignment, valAlignment));

            // calculate strides for all elements
            keyStride   = AllocHelper.RoundUpToAlignment(keyStride, alignment);
            valStride   = AllocHelper.RoundUpToAlignment(valStride, alignment);
            entryStride = AllocHelper.RoundUpToAlignment(sizeof(UnsafeHashCollection.Entry), alignment);

            // map ptr
            UnsafeHashMap *map;

            if (fixedSize)
            {
                var sizeOfHeader        = AllocHelper.RoundUpToAlignment(sizeof(UnsafeHashMap), alignment);
                var sizeOfBucketsBuffer = AllocHelper.RoundUpToAlignment(sizeof(UnsafeHashCollection.Entry * *) * capacity, alignment);
                var sizeofEntriesBuffer = (entryStride + keyStride + valStride) * capacity;

                // allocate memory
                var ptr = AllocHelper.MallocAndClear(sizeOfHeader + sizeOfBucketsBuffer + sizeofEntriesBuffer, alignment);

                // start of memory is the dict itself
                map = (UnsafeHashMap *)ptr;

                // buckets are offset by header size
                map->_collection.Buckets = (UnsafeHashCollection.Entry * *)((byte *)ptr + sizeOfHeader);

                // initialize fixed buffer
                UnsafeBuffer.InitFixed(&map->_collection.Entries, (byte *)ptr + (sizeOfHeader + sizeOfBucketsBuffer), capacity, entryStride + keyStride + valStride);
            }
            else
            {
                // allocate dict, buckets and entries buffer separately
                map = AllocHelper.MallocAndClear <UnsafeHashMap>();
                map->_collection.Buckets = (UnsafeHashCollection.Entry * *)AllocHelper.MallocAndClear(sizeof(UnsafeHashCollection.Entry * *) * capacity, sizeof(UnsafeHashCollection.Entry * *));

                // init dynamic buffer
                UnsafeBuffer.InitDynamic(&map->_collection.Entries, capacity, entryStride + keyStride + valStride);
            }

            // header init
            map->_collection.FreeCount = 0;
            map->_collection.UsedCount = 0;
            map->_collection.KeyOffset = entryStride;

            map->_valueOffset = entryStride + keyStride;

            return(map);
        }