Skip to content

Commit 3d5039e

Browse files
committed
Improve caching in XmlToDescriptionGenerator
1 parent 80e1882 commit 3d5039e

File tree

3 files changed

+773
-171
lines changed

3 files changed

+773
-171
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Collections;
5+
using System.Collections.Immutable;
6+
7+
namespace ModelContextProtocol.Analyzers;
8+
9+
/// <summary>An immutable, equatable array.</summary>
10+
/// <typeparam name="T">The type of values in the array.</typeparam>
11+
internal readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>, IEnumerable<T>
12+
where T : IEquatable<T>
13+
{
14+
/// <summary>
15+
/// The underlying <typeparamref name="T"/> array.
16+
/// </summary>
17+
private readonly ImmutableArray<T> _array;
18+
19+
/// <param name="source">The source to enumerate and wrap.</param>
20+
public EquatableArray(IEnumerable<T> source) => _array = source.ToImmutableArray();
21+
22+
/// <param name="source">The source to wrap.</param>
23+
public EquatableArray(ImmutableArray<T> array) => _array = array;
24+
25+
/// <summary>An empty <see cref="EquatableArray{T}"/>.</summary>
26+
public static EquatableArray<T> Empty => new(ImmutableArray<T>.Empty);
27+
28+
/// <summary>
29+
/// Gets a reference to an item at a specified position within the array.
30+
/// </summary>
31+
/// <param name="index">The index of the item to retrieve a reference to.</param>
32+
/// <returns>A reference to an item at a specified position within the array.</returns>
33+
public ref readonly T this[int index] => ref _array.ItemRef(index);
34+
35+
/// <summary>
36+
/// Gets a value indicating whether the current array is empty.
37+
/// </summary>
38+
public bool IsEmpty => _array.IsEmpty;
39+
40+
/// <summary>
41+
/// Gets a value indicating whether the current array is default or empty.
42+
/// </summary>
43+
public bool IsDefaultOrEmpty => _array.IsDefaultOrEmpty;
44+
45+
/// <summary>
46+
/// Gets the length of the current array.
47+
/// </summary>
48+
public int Length => _array.Length;
49+
50+
/// <inheritdoc/>
51+
public bool Equals(EquatableArray<T> other) => _array.SequenceEqual(other._array);
52+
53+
/// <inheritdoc/>
54+
public override bool Equals(object? obj) => obj is EquatableArray<T> array && Equals(array);
55+
56+
/// <inheritdoc/>
57+
public override int GetHashCode()
58+
{
59+
if (_array.IsDefault)
60+
{
61+
return 0;
62+
}
63+
64+
int hash = 17;
65+
foreach (T item in _array)
66+
{
67+
hash = hash * 31 + (item?.GetHashCode() ?? 0);
68+
}
69+
70+
return hash;
71+
}
72+
73+
/// <summary>
74+
/// Gets an <see cref="ImmutableArray{T}.Enumerator"/> value to traverse items in the current array.
75+
/// </summary>
76+
/// <returns>An <see cref="ImmutableArray{T}.Enumerator"/> value to traverse items in the current array.</returns>
77+
public ImmutableArray<T>.Enumerator GetEnumerator() => _array.GetEnumerator();
78+
79+
/// <inheritdoc/>
80+
IEnumerator<T> IEnumerable<T>.GetEnumerator() => ((IEnumerable<T>)_array).GetEnumerator();
81+
82+
/// <inheritdoc/>
83+
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_array).GetEnumerator();
84+
85+
/// <summary>
86+
/// Implicitly converts an <see cref="ImmutableArray{T}"/> to <see cref="EquatableArray{T}"/>.
87+
/// </summary>
88+
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns>
89+
public static implicit operator EquatableArray<T>(ImmutableArray<T> array) => new(array);
90+
91+
/// <summary>
92+
/// Implicitly converts an <see cref="EquatableArray{T}"/> to <see cref="ImmutableArray{T}"/>.
93+
/// </summary>
94+
/// <returns>An <see cref="ImmutableArray{T}"/> instance from a given <see cref="EquatableArray{T}"/>.</returns>
95+
public static implicit operator ImmutableArray<T>(EquatableArray<T> array) => array._array;
96+
97+
/// <summary>
98+
/// Checks whether two <see cref="EquatableArray{T}"/> values are the same.
99+
/// </summary>
100+
/// <param name="left">The first <see cref="EquatableArray{T}"/> value.</param>
101+
/// <param name="right">The second <see cref="EquatableArray{T}"/> value.</param>
102+
/// <returns>Whether <paramref name="left"/> and <paramref name="right"/> are equal.</returns>
103+
public static bool operator ==(EquatableArray<T> left, EquatableArray<T> right) => left.Equals(right);
104+
105+
/// <summary>
106+
/// Checks whether two <see cref="EquatableArray{T}"/> values are not the same.
107+
/// </summary>
108+
/// <param name="left">The first <see cref="EquatableArray{T}"/> value.</param>
109+
/// <param name="right">The second <see cref="EquatableArray{T}"/> value.</param>
110+
/// <returns>Whether <paramref name="left"/> and <paramref name="right"/> are not equal.</returns>
111+
public static bool operator !=(EquatableArray<T> left, EquatableArray<T> right) => !left.Equals(right);
112+
}

0 commit comments

Comments
 (0)