Skip to content

Instantly share code, notes, and snippets.

@simonwittber
Created August 20, 2021 08:31
Show Gist options
  • Select an option

  • Save simonwittber/015c15ca92c2e0090c1198383ce72484 to your computer and use it in GitHub Desktop.

Select an option

Save simonwittber/015c15ca92c2e0090c1198383ce72484 to your computer and use it in GitHub Desktop.

Revisions

  1. simonwittber created this gist Aug 20, 2021.
    48 changes: 48 additions & 0 deletions ByteArrayPool.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    using System;
    using System.Collections.Generic;

    public static class ByteArrayPool
    {
    private static Queue<WeakReference> pool = new Queue<WeakReference>();

    public static ArraySegment<byte> Take(int count)
    {
    // if there are any items to check in the pool
    if (pool.Count > 0)
    {
    for (int i = 0; i < pool.Count; i++)
    {
    // get the weakreference to the item
    var item = pool.Dequeue();

    // if the item is alive, someone is using it,
    // so put it back in the pool and try the next one.
    if (item.IsAlive)
    {
    pool.Enqueue(item);
    continue;
    }

    // if the item has actually been garbage collected, then skip it and
    // keep searching.
    var bytes = item.Target as byte[];
    if (bytes == null)
    continue;

    // if we get to here, the item is good, so keep it in the pool
    pool.Enqueue(item);

    // if it has enough capacity, return it.
    if (bytes.Length >= count)
    {
    return new ArraySegment<byte>(bytes, 0, count);
    }
    }
    }

    // nothing was found, so create a new array and track it in the pool.
    var segment = new ArraySegment<byte>(new byte[count]);
    pool.Enqueue(new WeakReference(segment));
    return segment;
    }
    }