| File: Contracts\SHash_1.cs | Web Access |
| Project: src\runtime\src\native\managed\cdac\Microsoft.Diagnostics.DataContractReader.Contracts\Microsoft.Diagnostics.DataContractReader.Contracts.csproj (Microsoft.Diagnostics.DataContractReader.Contracts) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using Microsoft.Diagnostics.DataContractReader.Data; namespace Microsoft.Diagnostics.DataContractReader.Contracts; internal readonly partial struct SHash_1 : ISHash { internal readonly Target _target; public SHash_1(Target target) { _target = target; } private class SHash<TKey, TEntry> : ISHash<TKey, TEntry> where TEntry : IData<TEntry> { public TargetPointer Table { get; set; } public uint TableSize { get; set; } public uint EntrySize { get; set; } public List<TEntry>? Entries { get; set; } public ITraits<TKey, TEntry>? Traits { get; set; } } ISHash<TKey, TEntry> ISHash.CreateSHash<TKey, TEntry>(Target target, TargetPointer address, Target.TypeInfo type, ITraits<TKey, TEntry> traits) { TargetPointer table = target.ReadPointer(address + (ulong)type.Fields[nameof(SHash<TKey, TEntry>.Table)].Offset); uint tableSize = target.Read<uint>(address + (ulong)type.Fields[nameof(SHash<TKey, TEntry>.TableSize)].Offset); uint entrySize = type.Size ?? 0; List<TEntry> entries = []; for (int i = 0; i < tableSize; i++) { TargetPointer entryAddress = table + (ulong)(i * entrySize); TEntry entry = target.ProcessedData.GetOrAdd<TEntry>(entryAddress); entries.Add(entry); } return new SHash<TKey, TEntry> { Table = table, TableSize = tableSize, EntrySize = entrySize, Traits = traits, Entries = entries }; } TEntry ISHash.LookupSHash<TKey, TEntry>(ISHash<TKey, TEntry> hashTable, TKey key) { SHash<TKey, TEntry> shashTable = (SHash<TKey, TEntry>)hashTable; if (shashTable.TableSize == 0) return shashTable.Traits!.Null(); uint hash = shashTable.Traits!.Hash(key); uint index = hash % shashTable.TableSize; uint increment = 0; while (true) { TEntry current = shashTable.Entries![(int)index]; if (shashTable.Traits.IsNull(current)) return shashTable.Traits.Null(); // we don't support the removal of entries if (!shashTable.Traits.IsDeleted(current) && shashTable.Traits.Equals(key, shashTable.Traits.GetKey(current))) return current; if (increment == 0) increment = (hash % (shashTable.TableSize - 1)) + 1; index += increment; if (index >= shashTable.TableSize) index -= shashTable.TableSize; } } }