Core.Buffers 1.0.29

There is a newer version of this package available.
See the version list below for details.
dotnet add package Core.Buffers --version 1.0.29
                    
NuGet\Install-Package Core.Buffers -Version 1.0.29
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Core.Buffers" Version="1.0.29" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Core.Buffers" Version="1.0.29" />
                    
Directory.Packages.props
<PackageReference Include="Core.Buffers" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Core.Buffers --version 1.0.29
                    
#r "nuget: Core.Buffers, 1.0.29"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Core.Buffers@1.0.29
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Core.Buffers&version=1.0.29
                    
Install as a Cake Addin
#tool nuget:?package=Core.Buffers&version=1.0.29
                    
Install as a Cake Tool

Core.Buffers

A .NET library for efficient buffer management that provides thread-safe, modern, and fast buffer functionality currently missing in vanilla .NET.

Installation

dotnet add package Core.Buffers

Features

  • DoubleBuffer<TEntity>: A double-buffering mechanism for unmanaged types, allowing for concurrent read and write operations.
  • DoubleBufferQueue<TEntity>: A queue implementation built on top of a double buffer, allowing for concurrent enqueue operations while maintaining the ability to swap buffers atomically.

Usage

DoubleBuffer<TEntity>

The DoubleBuffer<TEntity> class provides a double-buffering mechanism that allows for concurrent read and write operations. This is particularly useful in scenarios where you need to write to a buffer while reading from another buffer.

using Core.Buffers;

// Create a double buffer with a size of 1024 elements * 2  ( double buffer )
using var buffer = new DoubleBuffer<int>(MemoryPool<int>.Shared, 1024);

// Write to the active buffer
for (int i = 0; i < buffer.Size; i++)
{
    buffer.Active.Span[i] = i;
}

// Swap buffers atomically and get the previous buffer as ReadOnlyMemory
ReadOnlyMemory<int> previousBuffer = buffer.Swap();

// Now you can read from the previous buffer while writing to the new active buffer
// The previousBuffer can be used directly for reading

// Write to the (next) active buffer
for (int i = 0; i < buffer.Size; i++)
{
    buffer.Active.Span[i] = i;
}

// You can also access the shadow (inactive) buffer
Console.WriteLine($"Active buffer offset: {buffer.ActiveOffset}");
Console.WriteLine($"Shadow buffer offset: {buffer.ShadowOffset}");

// Read from the shadow buffer (read-only)
for (int i = 0; i < buffer.Size; i++)
{
    Console.WriteLine(buffer.Shadow.Span[i]);
}


DoubleBufferQueue<TEntity>

The DoubleBufferQueue<TEntity> class extends the DoubleBuffer<TEntity> class to provide a queue implementation that allows for concurrent enqueue operations while maintaining the ability to swap buffers atomically.

using Core.Buffers;

// Create a double buffer queue with a size of 1024 elements * 2 ( double buffer )
using var queue = new DoubleBufferQueue<int>(MemoryPool<int>.Shared, 1024);

// Enqueue items to the active buffer
for (int i = 0; i < 100; i++)
{
    queue.Enqueue(i);
    // or 
    if (!queue.TryEnqueue(i)) break;


}

// Check if the queue is full
if (queue.Exhausted)
{
    Console.WriteLine("Queue is full!");
}

// Get the count of items in the active buffer
Console.WriteLine($"Items in queue: {queue.Count}");

// Swap buffers atomically and get the previous buffer as ReadOnlyMemory, with the lenght of the commited items
ReadOnlyMemory<int> previousBuffer = queue.Swap();

// Now you can process the items in the previous buffer
// while new items are being enqueued to the new active buffer
// The previousBuffer contains only the valid items (sliced to the count)

API Reference

DoubleBuffer<TEntity>

  • Constructor: DoubleBuffer<TEntity>(MemoryPool<TEntity> memoryPool, int size)

    • Creates a new double buffer with the specified size.
  • Properties:

    • Memory<TEntity> Active: Gets the currently active buffer, from the perspective of the writer.
    • ReadOnlyMemory<TEntity> Shadow: Gets the current shadow (inactive) buffer, from the perspective of the writer.
    • ReadOnlyMemory<TEntity> Raw: Gets the complete double buffer (primary+secondary) as ReadOnlyMemory.
    • int Size: Gets the size of each individual buffer.
    • int ActiveOffset: Gets the current offset for the Active buffer, from the perspective of the writer.
    • int ShadowOffset: Gets the current offset for the readonly Shadow buffer, from the perspective of the writer.
  • Methods:

    • ReadOnlyMemory<TEntity> Swap(): Swaps the active/shadow buffers atomically and returns new Shadow buffer as a ReadOnlyMemory.
    • void Dispose(): Releases all resources used by the double buffer.

DoubleBufferQueue<TEntity>

  • Constructor: DoubleBufferQueue<TEntity>(MemoryPool<TEntity> memoryPool, int size)

    • Creates a new double buffer queue with the specified size.
  • Properties:

    • int Count: Gets the number of items in the currently active queue.
    • bool Exhausted: Gets a value indicating whether the current active buffer is full.
  • Methods:

    • ReadOnlyMemory<TEntity> Swap(): Swaps the active/shadow buffers atomically and returns new Shadow buffer as a ReadOnlyMemory, sliced to contain only the valid items.
    • ref TEntity Next(): Gets a reference to the next available position in the active buffer and increments the count.
    • void Enqueue(TEntity value): Adds an item to the end of the queue in the active buffer.
    • bool TryEnqueue(TEntity value): Tries to add an item to the end of the queue in the active buffer, returning false if the buffer is full.

Requirements

  • .NET 7.0, .NET 8.0, or .NET 9.0

License

This project is licensed under the MIT License - see the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.36 224 3/5/2025
1.0.29 206 3/5/2025