示例#1
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);
        }
示例#2
0
        public static void Free(UnsafeHashMap *set)
        {
            if (set->_collection.Entries.Dynamic)
            {
                UnsafeHashCollection.Free(&set->_collection);
            }

            AllocHelper.Free(set);
        }
示例#3
0
        public static void Free(UnsafeHashMap *set)
        {
            if (set->_collection.Entries.Dynamic == 1)
            {
                UnsafeHashCollection.Free(&set->_collection);
            }

            Native.Free(set);
        }
示例#4
0
 public static void Or <T>(UnsafeHashSet *set, UnsafeHashSet *other) where T : unmanaged, IEquatable <T>
 {
     for (int i = other->_collection.UsedCount - 1; i >= 0; --i)
     {
         var entry = UnsafeHashCollection.GetEntry(&other->_collection, i);
         if (entry->State == UnsafeHashCollection.EntryState.Used)
         {
             // always add to this collection
             Add <T>(set, *(T *)((byte *)entry + other->_collection.KeyOffset));
         }
     }
 }
示例#5
0
        public static void *GetPtr <K>(UnsafeHashMap *map, K key)
            where K : unmanaged, IEquatable <K>
        {
            var entry = UnsafeHashCollection.Find(&map->_collection, key, key.GetHashCode());

            if (entry == null)
            {
                throw new KeyNotFoundException(key.ToString());
            }

            return(GetValue(map, entry));
        }
示例#6
0
        public static void Set <K>(UnsafeHashMap *map, K key, void *value, int size)
            where K : unmanaged, IEquatable <K>
        {
            var hash  = key.GetHashCode();
            var entry = UnsafeHashCollection.Find(&map->_collection, key, hash);

            if (entry == null)             // insert new entry for key
            {
                entry = UnsafeHashCollection.Insert(&map->_collection, key, hash);
            }

            // assign value to entry
            UnsafeUtility.MemCpy(GetValue(map, entry), value, size);
        }
示例#7
0
        public static bool Add <T>(UnsafeHashSet *set, T key)
            where T : unmanaged, IEquatable <T>
        {
            var hash  = key.GetHashCode();
            var entry = UnsafeHashCollection.Find <T>(&set->_collection, key, hash);

            if (entry == null)
            {
                UnsafeHashCollection.Insert <T>(&set->_collection, key, hash);
                return(true);
            }

            return(false);
        }
            public bool Next()
            {
                while (++_index < Collection->UsedCount)
                {
                    var entry = UnsafeHashCollection.GetEntry(Collection, _index);
                    if (entry->State == EntryState.Used)
                    {
                        Current = entry;
                        return(true);
                    }
                }

                Current = null;
                return(false);
            }
示例#9
0
        public static void Set <K, V>(UnsafeHashMap *map, K key, V value)
            where K : unmanaged, IEquatable <K>
            where V : unmanaged
        {
            var hash  = key.GetHashCode();
            var entry = UnsafeHashCollection.Find(&map->_collection, key, hash);

            if (entry == null)             // insert new entry for key
            {
                entry = UnsafeHashCollection.Insert(&map->_collection, key, hash);
            }

            // assign value to entry
            *(V *)GetValue(map, entry) = value;
        }
示例#10
0
        public static bool TryGetValuePtr <K, V>(UnsafeHashMap *map, K key, out V *val)
            where K : unmanaged, IEquatable <K>
            where V : unmanaged
        {
            var entry = UnsafeHashCollection.Find <K>(&map->_collection, key, key.GetHashCode());

            if (entry != null)
            {
                val = (V *)GetValue(map, entry);
                return(true);
            }

            val = null;
            return(false);
        }
示例#11
0
        public static void And <T>(UnsafeHashSet *set, UnsafeHashSet *other) where T : unmanaged, IEquatable <T>
        {
            for (int i = set->_collection.UsedCount - 1; i >= 0; --i)
            {
                var entry = UnsafeHashCollection.GetEntry(&set->_collection, i);
                if (entry->State == UnsafeHashCollection.EntryState.Used)
                {
                    var key     = *(T *)((byte *)entry + set->_collection.KeyOffset);
                    var keyHash = key.GetHashCode();

                    // if we don't find this in other collection, remove it (And)
                    if (UnsafeHashCollection.Find <T>(&other->_collection, key, keyHash) == null)
                    {
                        UnsafeHashCollection.Remove <T>(&set->_collection, key, keyHash);
                    }
                }
            }
        }
示例#12
0
        public static void Add <K, V>(UnsafeHashMap *map, K key, V value)
            where K : unmanaged, IEquatable <K>
            where V : unmanaged
        {
            var hash  = key.GetHashCode();
            var entry = UnsafeHashCollection.Find <K>(&map->_collection, key, hash);

            if (entry == null)
            {
                // insert new entry for key
                entry = UnsafeHashCollection.Insert <K>(&map->_collection, key, hash);

                // assign value to entry
                *(V *)GetValue(map, entry) = value;
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
示例#13
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);
        }
示例#14
0
 public static bool Remove <K>(UnsafeHashMap *map, K key) where K : unmanaged, IEquatable <K>
 {
     return(UnsafeHashCollection.Remove <K>(&map->_collection, key, key.GetHashCode()));
 }
示例#15
0
 public static bool ContainsKey <K>(UnsafeHashMap *map, K key) where K : unmanaged, IEquatable <K>
 {
     return(UnsafeHashCollection.Find <K>(&map->_collection, key, key.GetHashCode()) != null);
 }
示例#16
0
 public static bool Contains <T>(UnsafeHashSet *set, T key) where T : unmanaged, IEquatable <T>
 {
     return(UnsafeHashCollection.Find <T>(&set->_collection, key, key.GetHashCode()) != null);
 }
示例#17
0
 public static bool Remove <T>(UnsafeHashSet *set, T key) where T : unmanaged, IEquatable <T>
 {
     return(UnsafeHashCollection.Remove <T>(&set->_collection, key, key.GetHashCode()));
 }
示例#18
0
 public static void Clear(UnsafeHashMap *set)
 {
     UnsafeHashCollection.Clear(&set->_collection);
 }