Merge pull request #5 from mlemanczyk/codex/zmodyfikuj-klase-chunk-i-zaktualizuj-agents.md

Polish chunk API docs and style
This commit is contained in:
Marek Lemańczyk authored and GitHub committed 2025-07-13 20:50:15 +02:00
commit e9887957f9
4 files changed
+93 -32

No files matched your search

+7
View File
@@ -2,6 +2,13 @@
This repository hosts various libraries distributed as NuGet packages. Keep these links up to date so contributors and tools can easily locate them. This repository hosts various libraries distributed as NuGet packages. Keep these links up to date so contributors and tools can easily locate them.
Only the .NET SDK **8.0** is available in the execution environment. Use this version when building or running tests.
All `*.csproj` files should enable nullable reference types with `<Nullable>enable</Nullable>`.
Indent code using four spaces or a single tab per level. Place one blank line after each closing curly brace of a code block, except when several closing braces appear sequentially. Always use braces for `if` and `else` bodies.
All tests must use **xUnit** together with **FluentAssertions**.
Implementations should be optimized for maximum performance even if that introduces some code duplication. Consider applying attributes such as `MethodImplOptions.AggressiveInlining` or faster alternatives to common operations when appropriate.
## NuGet packages ## NuGet packages
- [Recyclable.Collections](https://github.com/mlemanczyk/Recyclable.Collections) - [Recyclable.Collections](https://github.com/mlemanczyk/Recyclable.Collections)
- [Recyclable.Collections.Compatibility.List](https://github.com/mlemanczyk/Recyclable.Collections.Compatibility.List) - [Recyclable.Collections.Compatibility.List](https://github.com/mlemanczyk/Recyclable.Collections.Compatibility.List)
@@ -0,0 +1,19 @@
namespace Recyclable.Collections.Pools
{
public sealed class RecyclableArrayPoolChunk<T>
{
private static readonly T[] _empty = Array.Empty<T>();
internal static T[] Empty => _empty;
internal T[] Buffer;
internal int Index;
internal RecyclableArrayPoolChunk<T>? Previous;
internal RecyclableArrayPoolChunk<T>? Next;
public RecyclableArrayPoolChunk()
{
Buffer = _empty;
}
}
}
@@ -0,0 +1,34 @@
using Microsoft.Extensions.ObjectPool;
namespace Recyclable.Collections.Pools
{
public static class RecyclableArrayPoolChunkPool<T>
{
private static readonly ObjectPool<RecyclableArrayPoolChunk<T>> _pool =
new DefaultObjectPool<RecyclableArrayPoolChunk<T>>(new DefaultPooledObjectPolicy<RecyclableArrayPoolChunk<T>>());
public static RecyclableArrayPoolChunk<T> Rent() => _pool.Get();
public static void Return(RecyclableArrayPoolChunk<T> chunk)
{
chunk.Index = 0;
chunk.Previous = null;
chunk.Next = null;
_pool.Return(chunk);
}
public static void Dispose(RecyclableArrayPoolChunk<T> chunk, bool needsClearing)
{
var buffer = chunk.Buffer;
if (buffer.Length >= RecyclableDefaults.MinPooledArrayLength)
{
RecyclableArrayPool<T>.ReturnShared(buffer, needsClearing);
}
chunk.Buffer = RecyclableArrayPoolChunk<T>.Empty;
chunk.Index = 0;
chunk.Previous = null;
chunk.Next = null;
_pool.Return(chunk);
}
}
}
+33 -32
View File
@@ -1,6 +1,5 @@
using System.Collections; using System.Collections;
using System.Numerics; using System.Numerics;
using Microsoft.Extensions.ObjectPool;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Recyclable.Collections.Pools; using Recyclable.Collections.Pools;
@@ -9,23 +8,22 @@ namespace Recyclable.Collections
internal sealed class RecyclableStack<T> : IEnumerable<T>, IDisposable internal sealed class RecyclableStack<T> : IEnumerable<T>, IDisposable
{ {
private static readonly bool _needsClearing = !typeof(T).IsValueType; private static readonly bool _needsClearing = !typeof(T).IsValueType;
private static readonly ObjectPool<Chunk> _chunkPool = new DefaultObjectPool<Chunk>(new DefaultPooledObjectPolicy<Chunk>());
private sealed class Chunk
{
internal T[] Buffer = Array.Empty<T>();
internal int Index;
internal Chunk? Previous;
internal Chunk? Next;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Chunk RentChunk(int size, Chunk? previous) private static RecyclableArrayPoolChunk<T> RentChunk(int size, RecyclableArrayPoolChunk<T>? previous)
{ {
var chunk = _chunkPool.Get(); var chunk = RecyclableArrayPoolChunkPool<T>.Rent();
chunk.Buffer = size >= RecyclableDefaults.MinPooledArrayLength if (chunk.Buffer.Length < size)
? RecyclableArrayPool<T>.RentShared(size) {
: new T[size]; if (chunk.Buffer.Length >= RecyclableDefaults.MinPooledArrayLength)
{
RecyclableArrayPool<T>.ReturnShared(chunk.Buffer, _needsClearing);
}
chunk.Buffer = size >= RecyclableDefaults.MinPooledArrayLength
? RecyclableArrayPool<T>.RentShared(size)
: new T[size];
}
chunk.Index = 0; chunk.Index = 0;
chunk.Previous = previous; chunk.Previous = previous;
chunk.Next = null; chunk.Next = null;
@@ -33,22 +31,19 @@ namespace Recyclable.Collections
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReturnChunk(Chunk chunk) private static void ReturnChunk(RecyclableArrayPoolChunk<T> chunk)
{ {
var buffer = chunk.Buffer; RecyclableArrayPoolChunkPool<T>.Return(chunk);
if (buffer.Length >= RecyclableDefaults.MinPooledArrayLength)
{
RecyclableArrayPool<T>.ReturnShared(buffer, _needsClearing);
}
chunk.Buffer = Array.Empty<T>();
chunk.Index = 0;
chunk.Previous = null;
chunk.Next = null;
_chunkPool.Return(chunk);
} }
private Chunk _current; [MethodImpl(MethodImplOptions.AggressiveInlining)]
private Chunk _bottom; private static void DisposeChunk(RecyclableArrayPoolChunk<T> chunk)
{
RecyclableArrayPoolChunkPool<T>.Dispose(chunk, _needsClearing);
}
private RecyclableArrayPoolChunk<T> _current;
private RecyclableArrayPoolChunk<T> _bottom;
private bool _disposed; private bool _disposed;
private long _capacity; private long _capacity;
private long _count; private long _count;
@@ -179,16 +174,22 @@ namespace Recyclable.Collections
return; return;
} }
Clear(); var chunk = _current;
ReturnChunk(_current); while (chunk != null)
{
var previous = chunk.Previous;
DisposeChunk(chunk);
chunk = previous;
}
_disposed = true; _disposed = true;
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
public struct Enumerator : IEnumerator<T> public struct Enumerator : IEnumerator<T>
{ {
private readonly Chunk? _start; private readonly RecyclableArrayPoolChunk<T>? _start;
private Chunk? _chunk; private RecyclableArrayPoolChunk<T>? _chunk;
private int _index; private int _index;
private T? _current; private T? _current;