Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .jules/codex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2026-06-10 - Architectural Execution Flow Articulation
**Observation:** The README.md documentation exhibited a deficit regarding the explicit articulation of the underlying multi-tiered allocation strategy (TLS cache, fast slot, shared array, and fallback). It lacked a clear delineation of the internal mechanics and did not explicitly state the absence of planned hypothetical enhancements, leaving room for speculative assumptions. Code examples were also not utilizing contemporary .NET features like target-typed `new()`.
**Strategic Action:** Synchronized the README.md to explicitly articulate the architectural execution flow, separating implemented capabilities from hypotheses. Updated code examples to leverage modern C# syntax.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ using Tedd;
using System.Text;

var pool = new ObjectPool<StringBuilder>(
factory: () => new StringBuilder(capacity: 256),
factory: () => new(capacity: 256),
cleanup: sb => sb.Clear(), // reset before publishing back
size: 64 // total pool slots
Comment on lines 36 to 39
);
Expand Down Expand Up @@ -139,7 +139,7 @@ pool.Prefill(count: 32);

```csharp
var socketPool = new ObjectPool<System.Net.Sockets.Socket>(
factory: () => new System.Net.Sockets.Socket(System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp),
factory: () => new(System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp),
cleanup: s => { /* reset if applicable */ },
size: 32,
disposeWhenFull: true // overflowed sockets are disposed instead of dropped
Comment on lines 141 to 145
Expand All @@ -163,6 +163,15 @@ var socketPool = new ObjectPool<System.Net.Sockets.Socket>(
- The pool does not own lifetime of items except when `disposeWhenFull: true` is enabled for overflow.
- `Dispose()` only tears down internal thread-local storage; it does not dispose pooled items.

## Architectural Execution Flow

Tedd.ObjectPool utilizes a multi-tiered allocation strategy designed to minimize lock contention and interlocked operations on hot paths:

2. **Fast Slot (`_firstItem`):** If the TLS cache is empty during allocation, the pool attempts an optimistic read and a single CAS operation against a dedicated, highly-contended "fast slot". During deallocation (when TLS is already occupied), the pool publishes to the fast slot using `Volatile.Read`/`Volatile.Write` when it is observed empty.
4. **Factory Fallback / Overflow:** If the array is exhausted during allocation, a new instance is instantiated via the provided delegate. During deallocation, if the pool is at maximum capacity, the object is either dropped for garbage collection or explicitly disposed (if `disposeWhenFull` is configured and the type implements `IDisposable`).

*Note: The architecture described above reflects the current implementation. There are currently no speculative future enhancements (hypotheses) planned for the core execution flow.*

## Implementation and performance details

- **Fast paths kept tiny**: `Allocate`/`Free` are aggressively inlined; slow paths are marked `NoInlining` to keep the I-cache hot.
Expand Down
Loading