// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Runtime.InteropServices;
-
namespace System.Xml
{
/// <devdoc>
{
internal string str;
internal int hashCode;
- internal Entry next;
+ internal Entry? next;
- internal Entry(string str, int hashCode, Entry next)
+ internal Entry(string str, int hashCode, Entry? next)
{
this.str = str;
this.hashCode = hashCode;
//
// Fields
//
- private Entry[] _entries;
+ private Entry?[] _entries;
private int _count;
private int _mask;
public NameTable()
{
_mask = 31;
- _entries = new Entry[_mask + 1];
+ _entries = new Entry?[_mask + 1];
}
//
int hashCode = ComputeHash32(key);
- for (Entry e = _entries[hashCode & _mask]; e != null; e = e.next)
+ for (Entry? e = _entries[hashCode & _mask]; e != null; e = e.next)
{
if (e.hashCode == hashCode && e.str.Equals(key))
{
throw new ArgumentOutOfRangeException(nameof(len));
}
- int hashCode = ComputeHash32(key, start, len);
+ int hashCode = string.GetHashCode(key.AsSpan(start, len));
- for (Entry e = _entries[hashCode & _mask]; e != null; e = e.next)
+ for (Entry? e = _entries[hashCode & _mask]; e != null; e = e.next)
{
- if (e.hashCode == hashCode && TextEquals(e.str, key, start, len))
+ if (e.hashCode == hashCode && e.str.AsSpan().SequenceEqual(key.AsSpan(start, len)))
{
return e.str;
}
int hashCode = ComputeHash32(value);
- for (Entry e = _entries[hashCode & _mask]; e != null; e = e.next)
+ for (Entry? e = _entries[hashCode & _mask]; e != null; e = e.next)
{
if (e.hashCode == hashCode && e.str.Equals(value))
{
return null;
}
- int hashCode = ComputeHash32(key, start, len);
+ int hashCode = string.GetHashCode(key.AsSpan(start, len));
- for (Entry e = _entries[hashCode & _mask]; e != null; e = e.next)
+ for (Entry? e = _entries[hashCode & _mask]; e != null; e = e.next)
{
- if (e.hashCode == hashCode && TextEquals(e.str, key, start, len))
+ if (e.hashCode == hashCode && e.str.AsSpan().SequenceEqual(key.AsSpan(start, len)))
{
return e.str;
}
internal string GetOrAddEntry(string str, int hashCode)
{
- for (Entry e = _entries[hashCode & _mask]; e != null; e = e.next)
+ for (Entry? e = _entries[hashCode & _mask]; e != null; e = e.next)
{
if (e.hashCode == hashCode && e.str.Equals(str))
{
private void Grow()
{
int newMask = _mask * 2 + 1;
- Entry[] oldEntries = _entries;
- Entry[] newEntries = new Entry[newMask + 1];
+ Entry?[] oldEntries = _entries;
+ Entry?[] newEntries = new Entry?[newMask + 1];
// use oldEntries.Length to eliminate the range check
for (int i = 0; i < oldEntries.Length; i++)
{
- Entry e = oldEntries[i];
+ Entry? e = oldEntries[i];
while (e != null)
{
int newIndex = e.hashCode & newMask;
- Entry tmp = e.next;
+ Entry? tmp = e.next;
e.next = newEntries[newIndex];
newEntries[newIndex] = e;
e = tmp;
_entries = newEntries;
_mask = newMask;
}
-
- private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length)
- {
- if (str1.Length != str2Length)
- {
- return false;
- }
-
- // use array.Length to eliminate the range check
- for (int i = 0; i < str1.Length; i++)
- {
- if (str1[i] != str2[str2Start + i])
- {
- return false;
- }
- }
- return true;
- }
-
- private static int ComputeHash32(char[] key, int start, int len)
- {
- // We rely on string.GetHashCode(ROS<char>) being randomized.
-
- return string.GetHashCode(key.AsSpan(start, len));
- }
}
}