示例#1
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);
 }
 public static Entry *GetEntry(UnsafeHashCollection *collection, int index)
 {
     return((Entry *)UnsafeBuffer.Element(collection->Entries.Ptr, index, collection->Entries.Stride));
 }
示例#3
0
 public static void Free(UnsafeHashMap *map)
 {
     AllocHelper.Free(map->_collection.Buckets);
     AllocHelper.Free(map->_collection.FreeHead);
     UnsafeBuffer.Free(&map->_collection.Entries);
 }
示例#4
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);
        }
示例#5
0
 static K Key <K>(UnsafeHeapMin *heap, int index) where K : unmanaged
 {
     return(*(K *)UnsafeBuffer.Element(heap->_items.Ptr, index, heap->_items.Stride));
 }