• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

orion-ecs / keen-eye / 19994302530

06 Dec 2025 09:09PM UTC coverage: 97.886% (+2.0%) from 95.886%
19994302530

push

github

tyevco
Implement archetype chunk pooling for large-scale entity support (Issue #90)

Phase 2 - Performance & Storage implementation:

Core Architecture:
- Add Archetype, ArchetypeChunk, and ArchetypeId for type-based entity storage
- Add ArchetypeManager for archetype lifecycle and entity location tracking
- Add ComponentArray with ArrayPool integration for cache-friendly storage
- Add ChunkPool for reusing archetype chunks across entity lifecycle
- Add EntityPool for entity ID recycling with version tracking
- Add QueryManager and QueryDescriptor for efficient query caching

Performance Features:
- Chunk-based storage with configurable size (default 256 entities/chunk)
- Memory pooling reduces GC pressure for 100k+ entities
- O(1) component access via archetype-based lookups
- Query result caching with automatic invalidation

New Samples & Benchmarks:
- MassSimulation sample demonstrating 100k+ entities
- ChunkPoolingBenchmarks for performance validation

Testing:
- Comprehensive test coverage for all new components
- Edge case tests for error paths and boundary conditions
- Internal API tests for framework internals

Documentation:
- Add code coverage requirements to CLAUDE.md
- Add test quality standards and naming conventions

806 of 824 new or added lines in 14 files covered. (97.82%)

1574 of 1608 relevant lines covered (97.89%)

0.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.24
/src/KeenEyes.Core/Pooling/ComponentArrayPool.cs
1
using System.Buffers;
2
using System.Runtime.CompilerServices;
3

4
namespace KeenEyes;
5

6
/// <summary>
7
/// Provides pooled arrays for component storage, reducing garbage collection pressure.
8
/// Uses .NET's built-in ArrayPool&lt;T&gt;.Shared for efficient memory reuse.
9
/// </summary>
10
/// <typeparam name="T">The component type.</typeparam>
11
/// <remarks>
12
/// <para>
13
/// This pool is a thin wrapper around <see cref="ArrayPool{T}.Shared"/> that provides
14
/// ECS-specific functionality and tracking. It can be used independently of the
15
/// archetype system for custom storage scenarios.
16
/// </para>
17
/// <para>
18
/// Rented arrays may be larger than requested due to ArrayPool's bucketing strategy.
19
/// Always track the actual count of elements separately from the array length.
20
/// </para>
21
/// </remarks>
22
public static class ComponentArrayPool<T> where T : struct
23
{
24
    private static long totalRented;
25
    private static long totalReturned;
26

27
    /// <summary>
28
    /// Gets the total number of arrays rented from this pool.
29
    /// </summary>
30
    public static long TotalRented => Interlocked.Read(ref totalRented);
1✔
31

32
    /// <summary>
33
    /// Gets the total number of arrays returned to this pool.
34
    /// </summary>
35
    public static long TotalReturned => Interlocked.Read(ref totalReturned);
1✔
36

37
    /// <summary>
38
    /// Gets the number of arrays currently rented (not returned).
39
    /// </summary>
40
    public static long OutstandingCount => TotalRented - TotalReturned;
1✔
41

42
    /// <summary>
43
    /// Rents an array of at least the specified minimum length.
44
    /// </summary>
45
    /// <param name="minimumLength">The minimum required length.</param>
46
    /// <returns>An array of at least the specified length.</returns>
47
    /// <remarks>
48
    /// The returned array may be longer than requested. Track the actual
49
    /// element count separately. When done, return the array using
50
    /// <see cref="Return(T[], bool)"/>.
51
    /// </remarks>
52
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
53
    public static T[] Rent(int minimumLength)
54
    {
55
        Interlocked.Increment(ref totalRented);
1✔
56
        return ArrayPool<T>.Shared.Rent(minimumLength);
1✔
57
    }
58

59
    /// <summary>
60
    /// Returns an array to the pool.
61
    /// </summary>
62
    /// <param name="array">The array to return.</param>
63
    /// <param name="clearArray">Whether to clear the array contents before returning.</param>
64
    /// <remarks>
65
    /// <para>
66
    /// It is recommended to set <paramref name="clearArray"/> to true for
67
    /// reference types or when arrays may contain sensitive data.
68
    /// </para>
69
    /// <para>
70
    /// After calling this method, the caller should not access the array again.
71
    /// </para>
72
    /// </remarks>
73
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
74
    public static void Return(T[] array, bool clearArray = false)
75
    {
76
        ArrayPool<T>.Shared.Return(array, clearArray);
1✔
77
        Interlocked.Increment(ref totalReturned);
1✔
78
    }
1✔
79
}
80

81
/// <summary>
82
/// Non-generic helper for ComponentArrayPool operations.
83
/// Provides reflection-based access for dynamic component types.
84
/// </summary>
85
public static class ComponentArrayPool
86
{
NEW
87
    private static readonly Dictionary<Type, object> rentMethods = [];
×
NEW
88
    private static readonly Dictionary<Type, object> returnMethods = [];
×
89

90
    /// <summary>
91
    /// Rents an array for the specified component type.
92
    /// </summary>
93
    /// <param name="componentType">The component type.</param>
94
    /// <param name="minimumLength">The minimum required length.</param>
95
    /// <returns>A boxed array of the appropriate type.</returns>
96
    public static Array Rent(Type componentType, int minimumLength)
97
    {
98
        var poolType = typeof(ComponentArrayPool<>).MakeGenericType(componentType);
1✔
99
        var rentMethod = poolType.GetMethod("Rent")!;
1✔
100
        return (Array)rentMethod.Invoke(null, [minimumLength])!;
1✔
101
    }
102

103
    /// <summary>
104
    /// Returns an array to the pool for the specified component type.
105
    /// </summary>
106
    /// <param name="componentType">The component type.</param>
107
    /// <param name="array">The array to return.</param>
108
    /// <param name="clearArray">Whether to clear the array contents.</param>
109
    public static void Return(Type componentType, Array array, bool clearArray = false)
110
    {
111
        var poolType = typeof(ComponentArrayPool<>).MakeGenericType(componentType);
1✔
112
        var returnMethod = poolType.GetMethod("Return")!;
1✔
113
        returnMethod.Invoke(null, [array, clearArray]);
1✔
114
    }
1✔
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc