Beispiel #1
0
        public static UnsafeArray *Allocate <T>(int size) where T : unmanaged
        {
            if (size < 1)
            {
                throw new InvalidOperationException(ARRAY_SIZE_LESS_THAN_ONE);
            }

            var alignment = AllocHelper.GetAlignmentForArrayElement(sizeof(T));

            // pad the alignment of the array header
            var arrayStructSize = AllocHelper.RoundUpToAlignment(sizeof(UnsafeArray), alignment);
            var arrayMemorySize = size * sizeof(T);

            // allocate memory for header + elements, aligned to 'alignment'
            var ptr = AllocHelper.MallocAndClear(arrayStructSize + arrayMemorySize, alignment);

            UnsafeArray *array;

            array              = (UnsafeArray *)ptr;
            array->_buffer     = ((byte *)ptr) + arrayStructSize;
            array->_length     = size;
            array->_typeHandle = typeof(T).TypeHandle.Value;

            return(array);
        }
        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);
        }
        public static void Free(UnsafeHashCollection *collection)
        {
            Assert.Check(collection->Entries.Dynamic);

            AllocHelper.Free(collection->Buckets);
            AllocHelper.Free(collection->Entries.Ptr);
        }
Beispiel #4
0
 public static void Copy <T>(UnsafeArray *source, int sourceIndex, UnsafeArray *destination, int destinationIndex, int count) where T : unmanaged
 {
     Assert.Check(source != null);
     Assert.Check(destination != null);
     Assert.Check(typeof(T).TypeHandle.Value == source->_typeHandle);
     Assert.Check(typeof(T).TypeHandle.Value == destination->_typeHandle);
     AllocHelper.MemCpy((T *)destination->_buffer + destinationIndex, (T *)source->_buffer + sourceIndex, count * sizeof(T));
 }
        internal static void Free(UnsafeOrderedCollection *collection)
        {
            // free the buffer
            UnsafeBuffer.Free(&collection->Entries);

            // free collection header itself
            AllocHelper.Free(collection);
        }
        public static void Free(UnsafeBitSet *set)
        {
            // clear memory
            *set = default;

            // free memory
            AllocHelper.Free(set);
        }
Beispiel #7
0
 public static void Copy(UnsafeBuffer source, int sourceIndex, UnsafeBuffer destination, int destinationIndex, int count)
 {
     Assert.Check(source.Ptr != null);
     Assert.Check(source.Ptr != destination.Ptr);
     Assert.Check(source.Stride == destination.Stride);
     Assert.Check(source.Stride > 0);
     Assert.Check(destination.Ptr != null);
     AllocHelper.MemCpy((byte *)destination.Ptr + (destinationIndex * source.Stride), (byte *)source.Ptr + (sourceIndex * source.Stride), count * source.Stride);
 }
        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 = AllocHelper.GetAlignmentForArrayElement(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   = AllocHelper.RoundUpToAlignment(valStride, alignment);
            entryStride = AllocHelper.RoundUpToAlignment(sizeof(UnsafeHashCollection.Entry), alignment);

            // dictionary ptr
            UnsafeHashSet *set;

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

                // allocate memory
                var ptr = AllocHelper.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 = AllocHelper.MallocAndClear <UnsafeHashSet>();
                set->_collection.Buckets = (UnsafeHashCollection.Entry * *)AllocHelper.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);
        }
Beispiel #9
0
        public static void Free(UnsafeHashMap *set)
        {
            if (set->_collection.Entries.Dynamic)
            {
                UnsafeHashCollection.Free(&set->_collection);
            }

            AllocHelper.Free(set);
        }
        public static void Free(UnsafeRingBuffer *ring)
        {
            Assert.Check(ring != null);

            // clear memory just in case
            *ring = default;

            // release ring memory
            AllocHelper.Free(ring);
        }
        public static void Clear(UnsafeHashCollection *collection)
        {
            collection->FreeCount = 0;
            collection->UsedCount = 0;

            var length = collection->Entries.Length;

            AllocHelper.MemClear(collection->Buckets, length * sizeof(Entry * *));
            UnsafeBuffer.Clear(&collection->Entries);
        }
Beispiel #12
0
        public static void InitDynamic(UnsafeBuffer *buffer, int length, int stride)
        {
            Assert.Check(buffer != null);
            Assert.Check(length > 0);
            Assert.Check(stride > 0);

            buffer->Ptr     = AllocHelper.MallocAndClear(length * stride, AllocHelper.GetAlignmentForArrayElement(stride));
            buffer->Length  = length;
            buffer->Stride  = stride;
            buffer->Dynamic = true;
        }
Beispiel #13
0
        public static void Free(UnsafeOrderedSet *set)
        {
            if (set->_collection.Entries.Dynamic)
            {
                UnsafeBuffer.Free(&set->_collection.Entries);
            }

            // clear memory
            *set = default;

            // free it
            AllocHelper.Free(set);
        }
Beispiel #14
0
        static void Expand(UnsafeHashCollection *collection)
        {
            Assert.Check(collection->Entries.Dynamic);

            var capacity = GetNextPrime(collection->Entries.Length);

            Assert.Check(capacity >= collection->Entries.Length);

            var newBuckets = (Entry **)AllocHelper.MallocAndClear(capacity * sizeof(Entry * *), sizeof(Entry * *));
            var newEntries = default(UnsafeBuffer);

            UnsafeBuffer.InitDynamic(&newEntries, capacity, collection->Entries.Stride);
            UnsafeBuffer.Copy(collection->Entries, 0, newEntries, 0, collection->Entries.Length);

            collection->FreeHead  = null;
            collection->FreeCount = 0;

            for (int i = collection->Entries.Length - 1; i >= 0; --i)
            {
                var entry = (Entry *)((byte *)newEntries.Ptr + (i * newEntries.Stride));
                if (entry->State == EntryState.Used)
                {
                    var bucketHash = entry->Hash % capacity;

                    // assign current entry in buckets as next
                    entry->Next = newBuckets[bucketHash];

                    // assign entry as new bucket head
                    newBuckets[bucketHash] = entry;
                }

                // entry is in free list
                else if (entry->State == EntryState.Free)
                {
                    // assign free list as next
                    entry->Next = collection->FreeHead;

                    // re-assign free list to entry
                    collection->FreeHead  = entry;
                    collection->FreeCount = collection->FreeCount + 1;
                }
            }

            // free old memory
            AllocHelper.Free(collection->Buckets);
            UnsafeBuffer.Free(&collection->Entries);

            // new storage
            collection->Buckets = newBuckets;
            collection->Entries = newEntries;
        }
Beispiel #15
0
        public static void InitFixed(UnsafeBuffer *buffer, void *ptr, int length, int stride)
        {
            Assert.Check(buffer != null);
            Assert.Check(ptr != null);

            Assert.Check(length > 0);
            Assert.Check(stride > 0);

            // ensure alignment of fixed buffer
            Assert.Check((((IntPtr)ptr).ToInt64() % AllocHelper.GetAlignmentForArrayElement(stride)) == 0);

            buffer->Ptr     = ptr;
            buffer->Length  = length;
            buffer->Stride  = stride;
            buffer->Dynamic = false;
        }
Beispiel #16
0
        public static void Free(UnsafeStack *stack)
        {
            Assert.Check(stack != null);

            // if this is a dynamic sized stack, we need to free the buffer by hand
            if (stack->_items.Dynamic)
            {
                UnsafeBuffer.Free(&stack->_items);
            }

            // clear stack memory just in case
            *stack = default;

            // free stack memory (if this is a fixed size stack, it frees the _items memory also)
            AllocHelper.Free(stack);
        }
Beispiel #17
0
        public static UnsafeOrderedSet *Allocate(int capacity, int valStride, bool fixedSize = false)
        {
            var entryStride  = sizeof(UnsafeOrderedCollection.Entry);
            var valAlignment = AllocHelper.GetAlignmentForArrayElement(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   = AllocHelper.RoundUpToAlignment(valStride, alignment);
            entryStride = AllocHelper.RoundUpToAlignment(entryStride, alignment);

            // dictionary ptr
            UnsafeOrderedSet *set;

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

                // allocate memory
                var ptr = AllocHelper.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 = AllocHelper.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);
        }
Beispiel #18
0
        public static void Free(UnsafeBuffer *buffer)
        {
            Assert.Check(buffer != null);

            if (buffer->Dynamic == false)
            {
                throw new InvalidOperationException("Can't free a fixed buffer");
            }

            // buffer ptr can't be null
            Assert.Check(buffer->Ptr != null);

            // free memory of ptr
            AllocHelper.Free(buffer->Ptr);

            // clear buffer itself
            *buffer = default;
        }
Beispiel #19
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);
        }
Beispiel #20
0
        public static void Free(UnsafeQueue *queue)
        {
            if (queue == null)
            {
                return;
            }

            // not fixed, we need to free items separtely
            if (queue->_items.Dynamic)
            {
                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
            AllocHelper.Free(queue);
        }
Beispiel #21
0
        public static void Free(UnsafeHeapMax *heap)
        {
            if (heap == null)
            {
                return;
            }

            // free dynamic items separately
            if (heap->_items.Dynamic)
            {
                UnsafeBuffer.Free(&heap->_items);
            }

            // clear memory
            *heap = default;

            // free heap
            AllocHelper.Free(heap);
        }
Beispiel #22
0
        public static UnsafeHeapMax *Allocate(int capacity, int keyStride, int valStride, bool fixedSize = false)
        {
            capacity += 1;

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

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

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

            UnsafeHeapMax *heap;

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

                var ptr = AllocHelper.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 = AllocHelper.MallocAndClear <UnsafeHeapMax>();

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

            heap->_count     = 1;
            heap->_keyStride = keyStride;
            return(heap);
        }
Beispiel #23
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   = AllocHelper.GetAlignmentForArrayElement(stride);
                var sizeOfQueue = AllocHelper.RoundUpToAlignment(sizeof(UnsafeQueue), alignment);
                var sizeOfArray = stride * capacity;

                var ptr = AllocHelper.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 = AllocHelper.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);
        }
        public static UnsafeBitSet *Alloc(int size)
        {
            if (size < 1)
            {
                throw new InvalidOperationException(SET_SIZE_LESS_THAN_ONE);
            }

            // round to WORD_BIT_SIZE alignment, as we operate on the bitset using WORD_SIZE
            size = AllocHelper.RoundUpToAlignment(size, WORD_SIZE_BITS);

            var sizeOfHeader = AllocHelper.RoundUpToAlignment(sizeof(UnsafeBitSet), WORD_SIZE);
            var sizeOfBuffer = size / 8; // 8 bits per byte

            var ptr = AllocHelper.MallocAndClear(sizeOfHeader + sizeOfBuffer);
            var set = (UnsafeBitSet *)ptr;

            // set bit capacity
            set->_sizeBits    = size;
            set->_sizeBuckets = size / WORD_SIZE_BITS;
            set->_bits        = (ulong *)((byte *)ptr + sizeOfHeader);

            return(set);
        }
Beispiel #25
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);
        }
        internal static UnsafeOrderedCollection *Allocate(int capacity, int valStride)
        {
            var entryStride  = sizeof(Entry);
            var valAlignment = AllocHelper.GetAlignmentForArrayElement(valStride);

            // alignment we need is max of the two alignments
            var alignment = Math.Max(Entry.ALIGNMENT, valAlignment);

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

            // allocate dict, buckets and entries buffer separately
            var collection = AllocHelper.MallocAndClear <UnsafeOrderedCollection>();

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

            collection->FreeCount = 0;
            collection->UsedCount = 0;
            collection->KeyOffset = entryStride;

            return(collection);
        }
 public static void Clear(UnsafeBitSet *set)
 {
     AllocHelper.MemClear(set->_bits, set->_sizeBuckets * WORD_SIZE);
 }
Beispiel #28
0
 public static void Clear(UnsafeBuffer *buffer)
 {
     AllocHelper.MemClear(buffer->Ptr, buffer->Length * buffer->Stride);
 }
Beispiel #29
0
 public static void Free(UnsafeList *list)
 {
     AllocHelper.Free(list);
 }
Beispiel #30
0
 public static void Move(UnsafeBuffer source, int fromIndex, int toIndex, int count)
 {
     Assert.Check(source.Ptr != null);
     AllocHelper.MemMove((byte *)source.Ptr + (toIndex * source.Stride), (byte *)source.Ptr + (fromIndex * source.Stride), count * source.Stride);
 }