Beispiel #1
0
        private static bool TryInsert <K, V>(UnsafeDictionary *map, K key, V value, MapInsertionBehaviour behaviour)
            where K : unmanaged, IEquatable <K>
            where V : unmanaged
        {
            UDebug.Assert(map != null);
            UDebug.Assert(typeof(K).TypeHandle.Value == map->_typeHandleKey);
            UDebug.Assert(typeof(V).TypeHandle.Value == map->_typeHandleValue);

            var hash  = key.GetHashCode();
            var entry = UnsafeHashCollection.Find <K>(&map->_collection, key, hash);

            // Entry is already present
            if (entry != null)
            {
                if (behaviour == MapInsertionBehaviour.Overwrite)
                {
                    *GetValue <V>(map->_valueOffset, entry) = value;
                    return(true);
                }

                if (behaviour == MapInsertionBehaviour.ThrowIfExists)
                {
                    throw new ArgumentException(string.Format(ThrowHelper.Arg_AddingDuplicateWithKey, key));
                }

                return(false);
            }
            // Create new entry
            else
            {
                entry = UnsafeHashCollection.Insert <K>(&map->_collection, key, hash);
                *GetValue <V>(map->_valueOffset, entry) = value;
                return(true);
            }
        }
Beispiel #2
0
        public static bool Add <T>(UnsafeHashSet *set, T key)
            where T : unmanaged, IEquatable <T>
        {
            UDebug.Assert(set != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == set->_typeHandle);

            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);
        }
Beispiel #3
0
        /// <summary>
        /// Modifies the current hashset to contain only elements that are present either in this hashset or in the specified hashset, but not both.
        /// </summary>
        public static void SymmetricExcept <T>(UnsafeHashSet *set, UnsafeHashSet *other)
            where T : unmanaged, IEquatable <T>
        {
            UDebug.Assert(set != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == set->_typeHandle);
            UDebug.Assert(other != null);
            UDebug.Assert(typeof(T).TypeHandle.Value == other->_typeHandle);

            // When this set has no elements, return
            if (GetCount(set) == 0)
            {
                return;
            }

            // A set except itself is an empty set.
            if (other == set)
            {
                Clear(set);
                return;
            }

            for (int i = other->_collection.UsedCount - 1; i >= 0; --i)
            {
                var entry = UnsafeHashCollection.GetEntry(&other->_collection, i);
                if (entry->State == UnsafeHashCollection.EntryState.Used)
                {
                    var key     = *(T *)((byte *)entry + other->_collection.KeyOffset);
                    var keyHash = key.GetHashCode();

                    if (!UnsafeHashCollection.Remove(&set->_collection, key, keyHash))
                    {
                        UnsafeHashCollection.Insert(&set->_collection, key, keyHash);
                    }
                }
            }
        }
Beispiel #4
0
        public static void AddOrGet <K, V>(UnsafeDictionary *map, K key, ref V value)
            where K : unmanaged, IEquatable <K>
            where V : unmanaged
        {
            UDebug.Assert(map != null);
            UDebug.Assert(typeof(K).TypeHandle.Value == map->_typeHandleKey);
            UDebug.Assert(typeof(V).TypeHandle.Value == map->_typeHandleValue);

            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
                *GetValue <V>(map->_valueOffset, entry) = value;
            }
            else
            {
                value = *GetValue <V>(map->_valueOffset, entry);
            }
        }