Ejemplo n.º 1
0
        public static void SetCapacity(UnsafeList *list, int capacity)
        {
            Assert.Check(list != null);

            if (list->_items.Dynamic == false)
            {
                throw new InvalidOperationException(LIST_FIXED_CANT_CHANGE_CAPACITY);
            }

            // no change in capacity
            if (capacity == list->_items.Length)
            {
                return;
            }

            // tried to set to zero or negative, so free items
            if (capacity <= 0)
            {
                // have to make sure to set count to 0
                list->_count = 0;

                // and clear memory for items
                if (list->_items.Ptr != null)
                {
                    UnsafeBuffer.Free(&list->_items);
                }

                return;
            }

            // allocate new items
            UnsafeBuffer newItems = default;

            UnsafeBuffer.InitDynamic(&newItems, capacity, list->_items.Stride);

            // if have anything in list, copy it
            if (list->_count > 0)
            {
                // also make sure that count is
                // not larger than the new capacity
                if (list->_count > capacity)
                {
                    list->_count = capacity;
                }

                // copy over elements
                UnsafeBuffer.Copy(list->_items, 0, newItems, 0, list->_count);
            }

            // if an existing buffer was here, free it
            if (list->_items.Ptr != null)
            {
                UnsafeBuffer.Free(&list->_items);
            }

            // assign new buffer
            list->_items = newItems;
        }
        static void Expand(UnsafeHashCollection *collection)
        {
            Assert.Check(collection->Entries.Dynamic == 1);

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

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

            var newBuckets = (Entry **)Native.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
            Native.Free(collection->Buckets);
            UnsafeBuffer.Free(&collection->Entries);

            // new storage
            collection->Buckets = newBuckets;
            collection->Entries = newEntries;
        }
Ejemplo n.º 3
0
        static void Expand(UnsafeStack *stack)
        {
            // new buffer for elements
            UnsafeBuffer newItems = default;

            // initialize to double size of existing one
            UnsafeBuffer.InitDynamic(&newItems, stack->_items.Length * 2, stack->_items.Stride);

            // copy memory over from previous items
            UnsafeBuffer.Copy(stack->_items, 0, newItems, 0, stack->_items.Length);

            // free old buffer
            UnsafeBuffer.Free(&stack->_items);

            // replace buffer with new
            stack->_items = newItems;
        }
        static void Expand(UnsafeOrderedCollection *collection)
        {
            Assert.Check(collection->Entries.Dynamic == 1);
            Assert.Check(collection->FreeCount == 0);
            Assert.Check(collection->FreeHead == 0);

            var capacity   = collection->Entries.Length * 2;
            var newEntries = default(UnsafeBuffer);

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

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

            // new storage
            collection->Entries = newEntries;
        }
Ejemplo n.º 5
0
        static void ExpandHeap(UnsafeHeapMin *heap)
        {
            Assert.Check(heap->_items.Dynamic == 1);

            // new buffer for elements
            UnsafeBuffer newItems = default;

            // initialize to double size of existing one
            UnsafeBuffer.InitDynamic(&newItems, heap->_items.Length * 2, heap->_items.Stride);

            // copy memory over from previous items
            UnsafeBuffer.Copy(heap->_items, 0, newItems, 0, heap->_items.Length);

            // free old buffer
            UnsafeBuffer.Free(&heap->_items);

            // replace buffer with new
            heap->_items = newItems;
        }
Ejemplo n.º 6
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;
        }