コード例 #1
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
        public static void Pop <K, V>(UnsafeHeapMin *heap, out K key, out V val)
            where K : unmanaged, IComparable <K>
            where V : unmanaged
        {
            if (heap->_count <= 1)
            {
                throw new InvalidOperationException(HEAP_EMPTY);
            }

            heap->_count = heap->_count - 1;

            GetKeyVal(heap, 1, out key, out val);
            //the last node will be placed on top and then swapped downwards as far as necessarry
            GetKeyVal(heap, heap->_count, out K evacuateKey, out V evacuateVal);
            SetKeyVal(heap, 1, evacuateKey, evacuateVal);

            var swapItem = 1;
            var parent   = 1;

            do
            {
                parent = swapItem;

                if ((2 * parent + 1) <= heap->_count)
                {
                    // both children exist
                    if (Key <K>(heap, parent).CompareTo(Key <K>(heap, 2 * parent)) >= 0)
                    {
                        swapItem = 2 * parent;
                    }

                    if (Key <K>(heap, swapItem).CompareTo(Key <K>(heap, 2 * parent + 1)) >= 0)
                    {
                        swapItem = 2 * parent + 1;
                    }
                }
                else if ((2 * parent) <= heap->_count)
                {
                    // only one child exists
                    if (Key <K>(heap, parent).CompareTo(Key <K>(heap, 2 * parent)) >= 0)
                    {
                        swapItem = 2 * parent;
                    }
                }

                // one if the parent's children are smaller or equal, swap them
                if (parent != swapItem)
                {
                    // pull parent/swapItem values
                    GetKeyVal <K, V>(heap, parent, out K tmpParentKey, out V tmpParentVal);
                    GetKeyVal <K, V>(heap, swapItem, out K tmpSwapItemKey, out V tmpSwapItemVal);

                    // switch them
                    SetKeyVal(heap, swapItem, tmpParentKey, tmpParentVal);
                    SetKeyVal(heap, parent, tmpSwapItemKey, tmpSwapItemVal);
                }
            } while (parent != swapItem);
        }
コード例 #2
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
        static void SetKeyVal <K, V>(UnsafeHeapMin *heap, int index, K key, V val)
            where K : unmanaged
            where V : unmanaged
        {
            var ptr = UnsafeBuffer.Element(heap->_items.Ptr, index, heap->_items.Stride);

            // write key
            *(K *)(ptr) = key;

            // write val, offset by keyStride
            *(V *)((byte *)ptr + heap->_keyStride) = val;
        }
コード例 #3
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
        static void GetKeyVal <K, V>(UnsafeHeapMin *heap, int index, out K key, out V val)
            where K : unmanaged
            where V : unmanaged
        {
            var ptr = UnsafeBuffer.Element(heap->_items.Ptr, index, heap->_items.Stride);

            // read key
            key = *(K *)(ptr);

            // read val, offset by keyStride
            val = *(V *)((byte *)ptr + heap->_keyStride);
        }
コード例 #4
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
        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;
        }
コード例 #5
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
        public static void Free(UnsafeHeapMin *heap)
        {
            if (heap == null)
            {
                return;
            }

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

            // clear memory
            *heap = default;

            // free heap
            Native.Free(heap);
        }
コード例 #6
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
        public static void Push <K, V>(UnsafeHeapMin *heap, K key, V val)
            where K : unmanaged, IComparable <K>
            where V : unmanaged
        {
            if (heap->_count == heap->_items.Length)
            {
                if (heap->_items.Dynamic == 1)
                {
                    ExpandHeap(heap);
                }
                else
                {
                    throw new InvalidOperationException(HEAP_FULL);
                }
            }

            // index we're bubbling up from
            var bubbleIndex = heap->_count;

            // assign new key/val to it
            SetKeyVal(heap, bubbleIndex, key, val);

            while (bubbleIndex != 1)
            {
                var parentIndex    = bubbleIndex / 2;
                var parentIndexKey = *(K *)UnsafeBuffer.Element(heap->_items.Ptr, parentIndex, heap->_items.Stride);
                if (parentIndexKey.CompareTo(key) > 0)
                {
                    GetKeyVal(heap, parentIndex, out K parentKey, out V parentVal);
                    SetKeyVal(heap, bubbleIndex, parentKey, parentVal);
                    SetKeyVal(heap, parentIndex, key, val);

                    bubbleIndex = parentIndex;
                }
                else
                {
                    break;
                }
            }

            heap->_count = heap->_count + 1;
        }
コード例 #7
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
 public static UnsafeList.Iterator <T> GetIterator <T>(UnsafeHeapMin *heap) where T : unmanaged
 {
     return(new UnsafeList.Iterator <T>(heap->_items, 1, heap->_count - 1));
 }
コード例 #8
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
 static K Key <K>(UnsafeHeapMin *heap, int index) where K : unmanaged
 {
     return(*(K *)UnsafeBuffer.Element(heap->_items.Ptr, index, heap->_items.Stride));
 }
コード例 #9
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
 public static void Clear(UnsafeHeapMin *heap)
 {
     heap->_count = 1;
 }
コード例 #10
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
 public static int Count(UnsafeHeapMin *heap)
 {
     return(heap->_count - 1);
 }
コード例 #11
0
ファイル: UnsafeHeap.cs プロジェクト: fholm/UnsafeCollections
 public static int Capacity(UnsafeHeapMin *heap)
 {
     return(heap->_items.Length - 1);
 }