From 3d4b2aec114ce1ca20e046ef458e8376ec9e1903 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 20:57:03 +0300 Subject: [PATCH 1/3] Initial commit with task details for issue #96 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/linksplatform/Collections/issues/96 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..98361043 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/linksplatform/Collections/issues/96 +Your prepared branch: issue-96-c549fe2e +Your prepared working directory: /tmp/gh-issue-solver-1757786216276 + +Proceed. \ No newline at end of file From 230959ba57fc414f5a960b165bc35b614be4f625 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 21:05:17 +0300 Subject: [PATCH 2/3] Fix ArrayPool Resize method when old and new sizes are the same MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added optimization to return the same object when resizing to identical size - Prevents unnecessary memory allocation and data copying - Added comprehensive unit tests to verify the fix and prevent regressions - All existing tests continue to pass Fixes #96 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../ArrayPoolTests.cs | 117 ++++++++++++++++++ .../Arrays/ArrayPool[T].cs | 7 +- experiments/Experiments.csproj | 14 +++ 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 csharp/Platform.Collections.Tests/ArrayPoolTests.cs create mode 100644 experiments/Experiments.csproj diff --git a/csharp/Platform.Collections.Tests/ArrayPoolTests.cs b/csharp/Platform.Collections.Tests/ArrayPoolTests.cs new file mode 100644 index 00000000..956c825b --- /dev/null +++ b/csharp/Platform.Collections.Tests/ArrayPoolTests.cs @@ -0,0 +1,117 @@ +using Xunit; +using Platform.Collections.Arrays; + +namespace Platform.Collections.Tests +{ + public class ArrayPoolTests + { + [Fact] + public void Resize_WhenSizesAreSame_ShouldReturnSameObject() + { + var pool = new ArrayPool(); + var originalArray = pool.AllocateDisposable(5); + int[] arr = originalArray; + + // Fill with test data + for (int i = 0; i < arr.Length; i++) + { + arr[i] = i + 1; + } + + // Resize to the same size + var resizedArray = pool.Resize(originalArray, 5); + int[] newArr = resizedArray; + + // Should be the same object reference + Assert.True(object.ReferenceEquals(arr, newArr)); + + // Data should remain unchanged + Assert.Equal(new int[] { 1, 2, 3, 4, 5 }, newArr); + + resizedArray.Dispose(); + } + + [Fact] + public void Resize_WhenSizesDiffer_ShouldCreateNewObject() + { + var pool = new ArrayPool(); + var originalArray = pool.AllocateDisposable(5); + int[] arr = originalArray; + + // Fill with test data + for (int i = 0; i < arr.Length; i++) + { + arr[i] = i + 1; + } + + // Resize to different size (smaller) + var resizedArray = pool.Resize(originalArray, 3); + int[] newArr = resizedArray; + + // Should be different object reference + Assert.False(object.ReferenceEquals(arr, newArr)); + + // Data should be copied (first 3 elements) + Assert.Equal(new int[] { 1, 2, 3 }, newArr); + + resizedArray.Dispose(); + } + + [Fact] + public void Resize_WhenResizingToLarger_ShouldCopyAllOriginalData() + { + var pool = new ArrayPool(); + var originalArray = pool.AllocateDisposable(3); + int[] arr = originalArray; + + // Fill with test data + for (int i = 0; i < arr.Length; i++) + { + arr[i] = i + 1; + } + + // Resize to larger size + var resizedArray = pool.Resize(originalArray, 5); + int[] newArr = resizedArray; + + // Should be different object reference + Assert.False(object.ReferenceEquals(arr, newArr)); + + // Original data should be copied, new elements should be default (0) + Assert.Equal(new int[] { 1, 2, 3, 0, 0 }, newArr); + + resizedArray.Dispose(); + } + + [Fact] + public void Resize_WithEmptyArray_ShouldAllocateNewArray() + { + var pool = new ArrayPool(); + var emptyArray = pool.AllocateDisposable(0); + + // Resize empty array to size 3 + var resizedArray = pool.Resize(emptyArray, 3); + int[] newArr = resizedArray; + + Assert.Equal(3, newArr.Length); + Assert.All(newArr, x => Assert.Equal(0, x)); // All elements should be default + + resizedArray.Dispose(); + } + + [Fact] + public void Resize_ToZeroSize_ShouldReturnEmptyArray() + { + var pool = new ArrayPool(); + var originalArray = pool.AllocateDisposable(5); + + // Resize to zero size + var resizedArray = pool.Resize(originalArray, 0); + int[] newArr = resizedArray; + + Assert.Equal(0, newArr.Length); + + resizedArray.Dispose(); + } + } +} \ No newline at end of file diff --git a/csharp/Platform.Collections/Arrays/ArrayPool[T].cs b/csharp/Platform.Collections/Arrays/ArrayPool[T].cs index c1143e4b..31c7f277 100644 --- a/csharp/Platform.Collections/Arrays/ArrayPool[T].cs +++ b/csharp/Platform.Collections/Arrays/ArrayPool[T].cs @@ -75,8 +75,13 @@ public ArrayPool() : this(ArrayPool.DefaultMaxArraysPerSize) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Disposable Resize(Disposable source, long size) { - var destination = AllocateDisposable(size); T[] sourceArray = source; + if (!sourceArray.IsNullOrEmpty() && sourceArray.LongLength == size) + { + // If the size is the same, return the source without any allocation or copying + return source; + } + var destination = AllocateDisposable(size); if (!sourceArray.IsNullOrEmpty()) { T[] destinationArray = destination; diff --git a/experiments/Experiments.csproj b/experiments/Experiments.csproj new file mode 100644 index 00000000..c91ea78a --- /dev/null +++ b/experiments/Experiments.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8 + latest + enable + + + + + + + \ No newline at end of file From 0fd204285bc241c8be24b04368a0c41ca9ef43a3 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 21:06:12 +0300 Subject: [PATCH 3/3] Remove CLAUDE.md - Claude command completed --- CLAUDE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 98361043..00000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/linksplatform/Collections/issues/96 -Your prepared branch: issue-96-c549fe2e -Your prepared working directory: /tmp/gh-issue-solver-1757786216276 - -Proceed. \ No newline at end of file