internal static unsafe void Remove(UnsafeHashMapData *data, NativeMultiHashMapIterator <TKey> it) { // First find the slot based on the hash int *buckets = (int *)data->buckets; int *pNextIndexChain = (int *)data->next; int bucket = it.key.GetHashCode() & data->bucketCapacityMask; int entryIdx = buckets[bucket]; if (entryIdx == it.EntryIndex) { buckets[bucket] = pNextIndexChain[entryIdx]; } else { while (entryIdx >= 0 && pNextIndexChain[entryIdx] != it.EntryIndex) { entryIdx = pNextIndexChain[entryIdx]; } if (entryIdx < 0) { throw new InvalidOperationException("Invalid iterator passed to HashMap remove"); } pNextIndexChain[entryIdx] = pNextIndexChain[it.EntryIndex]; } // And free the index pNextIndexChain[it.EntryIndex] = data->firstFreeTLS[0]; data->firstFreeTLS[0] = it.EntryIndex; }
internal static unsafe bool SetValue(UnsafeHashMapData *data, ref NativeMultiHashMapIterator <TKey> it, ref TValue item) { int entryIdx = it.EntryIndex; if (entryIdx < 0 || entryIdx >= data->keyCapacity) { return(false); } UnsafeUtility.WriteArrayElement(data->values, entryIdx, item); return(true); }
internal static unsafe bool TryGetNextValueAtomic(UnsafeHashMapData *data, out TValue item, ref NativeMultiHashMapIterator <TKey> it) { int entryIdx = it.NextEntryIndex; it.NextEntryIndex = -1; it.EntryIndex = -1; item = default; if (entryIdx < 0 || entryIdx >= data->keyCapacity) { return(false); } int *pNextIndexChain = (int *)data->next; while (!UnsafeUtility.ReadArrayElement <TKey>(data->keys, entryIdx).Equals(it.key)) { entryIdx = pNextIndexChain[entryIdx]; if (entryIdx < 0 || entryIdx >= data->keyCapacity) { return(false); } } it.NextEntryIndex = pNextIndexChain[entryIdx]; it.EntryIndex = entryIdx; // Read the value item = UnsafeUtility.ReadArrayElement <TValue>(data->values, entryIdx); return(true); }
internal static unsafe bool TryGetFirstValueAtomic(UnsafeHashMapData *data, TKey key, out TValue item, out NativeMultiHashMapIterator <TKey> it) { it.key = key; if (data->allocatedIndexLength <= 0) { it.EntryIndex = it.NextEntryIndex = -1; item = default; return(false); } // First find the slot based on the hash int *buckets = (int *)data->buckets; int bucket = key.GetHashCode() & data->bucketCapacityMask; it.EntryIndex = it.NextEntryIndex = buckets[bucket]; return(TryGetNextValueAtomic(data, out item, ref it)); }