Skip to content

Commit

Permalink
Switch source generator cache to ArrayPool<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed May 16, 2023
1 parent eef21e2 commit f87610a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Helpers\EquatableArray{T}.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\HashCode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ImmutableArrayBuilder{T}.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ObjectPool{T}.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Input\Models\CanExecuteExpressionType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Input\Models\CommandInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Input\RelayCommandGenerator.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// more info in ThirdPartyNotices.txt in the root of the project.

using System;
using System.Buffers;
using System.Collections.Immutable;
using System.Runtime.CompilerServices;

Expand All @@ -17,11 +18,6 @@ namespace CommunityToolkit.Mvvm.SourceGenerators.Helpers;
/// <typeparam name="T">The type of items to create sequences for.</typeparam>
internal struct ImmutableArrayBuilder<T> : IDisposable
{
/// <summary>
/// The shared <see cref="ObjectPool{T}"/> instance to share <see cref="Writer"/> objects.
/// </summary>
private static readonly ObjectPool<Writer> SharedObjectPool = new(static () => new Writer());

/// <summary>
/// The rented <see cref="Writer"/> instance to use.
/// </summary>
Expand All @@ -33,7 +29,7 @@ internal struct ImmutableArrayBuilder<T> : IDisposable
/// <returns>A <see cref="ImmutableArrayBuilder{T}"/> instance to write data to.</returns>
public static ImmutableArrayBuilder<T> Rent()
{
return new(SharedObjectPool.Allocate());
return new(new Writer());
}

/// <summary>
Expand Down Expand Up @@ -103,23 +99,18 @@ public void Dispose()

this.writer = null;

if (writer is not null)
{
writer.Clear();

SharedObjectPool.Free(writer);
}
writer?.Dispose();
}

/// <summary>
/// A class handling the actual buffer writing.
/// </summary>
private sealed class Writer
private sealed class Writer : IDisposable
{
/// <summary>
/// The underlying <typeparamref name="T"/> array.
/// </summary>
private T[] array;
private T?[]? array;

/// <summary>
/// The starting offset within <see cref="array"/>.
Expand All @@ -131,15 +122,7 @@ private sealed class Writer
/// </summary>
public Writer()
{
if (typeof(T) == typeof(char))
{
this.array = new T[1024];
}
else
{
this.array = new T[8];
}

this.array = ArrayPool<T?>.Shared.Rent(typeof(T) == typeof(char) ? 1024 : 8);
this.index = 0;
}

Expand All @@ -154,38 +137,38 @@ public int Count
public ReadOnlySpan<T> WrittenSpan
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(this.array, 0, this.index);
get => new(this.array!, 0, this.index);
}

/// <inheritdoc cref="ImmutableArrayBuilder{T}.Add"/>
public void Add(T value)
{
EnsureCapacity(1);

this.array[this.index++] = value;
this.array![this.index++] = value;
}

/// <inheritdoc cref="ImmutableArrayBuilder{T}.AddRange"/>
public void AddRange(ReadOnlySpan<T> items)
{
EnsureCapacity(items.Length);

items.CopyTo(this.array.AsSpan(this.index));
items.CopyTo(this.array.AsSpan(this.index)!);

this.index += items.Length;
}

/// <summary>
/// Clears the items in the current writer.
/// </summary>
public void Clear()
/// <inheritdoc/>
public void Dispose()
{
if (typeof(T) != typeof(char))
T?[]? array = this.array;

this.array = null;

if (array is not null)
{
this.array.AsSpan(0, this.index).Clear();
ArrayPool<T?>.Shared.Return(array, clearArray: typeof(T) != typeof(char));
}

this.index = 0;
}

/// <summary>
Expand All @@ -195,7 +178,7 @@ public void Clear()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void EnsureCapacity(int requestedSize)
{
if (requestedSize > this.array.Length - this.index)
if (requestedSize > this.array!.Length - this.index)
{
ResizeBuffer(requestedSize);
}
Expand All @@ -209,13 +192,15 @@ private void EnsureCapacity(int requestedSize)
private void ResizeBuffer(int sizeHint)
{
int minimumSize = this.index + sizeHint;
int requestedSize = Math.Max(this.array.Length * 2, minimumSize);

T[] newArray = new T[requestedSize];
T?[] oldArray = this.array!;
T?[] newArray = ArrayPool<T?>.Shared.Rent(minimumSize);

Array.Copy(this.array, newArray, this.index);
Array.Copy(oldArray, newArray, this.index);

this.array = newArray;

ArrayPool<T?>.Shared.Return(oldArray, clearArray: typeof(T) != typeof(char));
}
}
}
Expand Down
163 changes: 0 additions & 163 deletions src/CommunityToolkit.Mvvm.SourceGenerators/Helpers/ObjectPool{T}.cs

This file was deleted.

0 comments on commit f87610a

Please sign in to comment.