Skip to content
This repository
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 134 lines (119 sloc) 3.33 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
using System;
using System.Collections.Generic;
using System.Net.Sockets;

namespace Firefly.Utils
{
    public class MemoryPool : IMemoryPool
    {
        static readonly byte[] EmptyArray = new byte[0];

        class Pool<T>
        {
            readonly Stack<T[]> _stack = new Stack<T[]>();
            readonly object _sync = new object();

            public T[] Alloc(int size)
            {
                lock (_sync)
                {
                    if (_stack.Count != 0)
                    {
                        return _stack.Pop();
                    }
                }
                return new T[size];
            }

            public void Free(T[] value, int limit)
            {
                lock (_sync)
                {
                    if (_stack.Count < limit)
                    {
                        _stack.Push(value);
                    }
                }
            }
        }

        readonly Pool<byte> _pool1 = new Pool<byte>();
        readonly Pool<byte> _pool2 = new Pool<byte>();
        readonly Pool<char> _pool3 = new Pool<char>();

        public byte[] Empty
        {
            get
            {
                return EmptyArray;
            }
        }

        public byte[] AllocByte(int minimumSize)
        {
            if (minimumSize == 0)
            {
                return EmptyArray;
            }
            if (minimumSize <= 1024)
            {
                return _pool1.Alloc(1024);
            }
            if (minimumSize <= 2048)
            {
                return _pool2.Alloc(2048);
            }
            return new byte[minimumSize];
        }

        public void FreeByte(byte[] memory)
        {
            if (memory == null)
            {
                return;
            }
            switch (memory.Length)
            {
            case 1024:
                _pool1.Free(memory, 256);
                break;
            case 2048:
                _pool2.Free(memory, 64);
                break;
            }
        }

        public char[] AllocChar(int minimumSize)
        {
            if (minimumSize == 0)
            {
                return new char[0];
            }
            if (minimumSize <= 128)
            {
                return _pool3.Alloc(128);
            }
            return new char[minimumSize];
        }

        public void FreeChar(char[] memory)
        {
            if (memory == null)
            {
                return;
            }
            switch (memory.Length)
            {
            case 128:
                _pool3.Free(memory, 256);
                break;
            }
        }

        public ArraySegment<byte> AllocSegment(int minimumSize)
        {
            return new ArraySegment<byte>(AllocByte(minimumSize));
        }

        public void FreeSegment(ArraySegment<byte> segment)
        {
            FreeByte(segment.Array);
        }

        public ISocketEvent AllocSocketEvent()
        {
            return new SocketEventWrapper(new SocketAsyncEventArgs());
        }

        public void FreeSocketEvent(ISocketEvent socketEvent)
        {
            socketEvent.Dispose();
        }
    }
}
Something went wrong with that request. Please try again.