//****************************************************************************************************** // BufferPool.cs - Gbtc // // Copyright © 2010, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/eclipse-1.0.php // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 10/27/2011 - J. Ritchie Carroll // Initial version of source generated. // 10/8/2012 - Danyelle Gilliam // Modified Header // //****************************************************************************************************** #region [ Contributor License Agreements ] //****************************************************************************************************** // // Copyright © 2011, Grid Protection Alliance. All Rights Reserved. // // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/eclipse-1.0.php // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // //****************************************************************************************************** #endregion using System; using System.Collections.Concurrent; //using System.ServiceModel.Channels; namespace GSF { /// /// Represents a common buffer pool that can be used by an application. /// /// /// /// The buffer pool is statically created at application startup and is available for all components and classes /// within an application domain. Every time you need to use a buffer, you take one from the pool, use it, and /// return it to the pool when done. This process is much faster than creating and destroying a buffer every /// time you need to use one. /// /// /// It is very imporant to return the buffer to the pool when you are finished using it. If you are using a buffer /// scoped within a method, make sure to use a try/finally so that you can take the buffer within the try and /// return the buffer within the finally. If you are using a buffer as a member scoped class field, make sure /// you use the standard dispose pattern and return the buffer in the method. /// /// public static class BufferPool { // Note that the buffer manager will create an queue buffers as needed during run-time, the default maximum // pool size and default maximum buffer sizes are set to int max. Even if an application should max the pool // size, the buffer manager will still sucessfully provide and manage buffers - they simply won't be cached. private static ConcurrentDictionary> m_bufferPools = new ConcurrentDictionary>(); private static int GetStandardBufferSize(int bufferSize) { int exponent = 10; long size = (long)Math.Pow(2, exponent); while (size <= int.MaxValue) { if (bufferSize <= size) return (int)size; exponent++; size = (long)Math.Pow(2, exponent); } return int.MaxValue; } private static ConcurrentQueue CreateQueue(int bufferSize) { return new ConcurrentQueue(); } /// /// Gets a buffer of at least the specified size from the pool. /// /// The size, in bytes, of the requested buffer. /// A byte array that is the requested size of the buffer. /// cannot be less than zero. public static byte[] TakeBuffer(int bufferSize) { bufferSize = GetStandardBufferSize(bufferSize); ConcurrentQueue pool = m_bufferPools.GetOrAdd(bufferSize, CreateQueue); byte[] buffer; // Attempt to provide user with a queued buffer if (!pool.TryDequeue(out buffer)) { // No buffers are available, create a new buffer for the pool buffer = new byte[bufferSize]; } return buffer; } /// /// Returns a buffer to the pool. /// /// A reference to the buffer being returned. /// reference cannot be null. /// Length of does not match the pool's buffer length property. public static void ReturnBuffer(byte[] buffer) { int bufferSize = buffer.Length; if (bufferSize != GetStandardBufferSize(bufferSize)) throw new InvalidOperationException("Attempt was amde to return an invalid buffer to buffer pool."); ConcurrentQueue pool = m_bufferPools[bufferSize]; if ((object)buffer != null) pool.Enqueue(buffer); } /// /// Releases all the buffers currently cached in the pool. /// public static void Clear() { m_bufferPools.Clear(); } } }