Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / FontCache / BufferCache.cs / 1305600 / BufferCache.cs
// -------------------------------------------------------------------------- // // File: BufferCache.cs // // Copyright (C) Microsoft Corporation. All rights reserved. // // Description: BufferCache class implementation. // //--------------------------------------------------------------------------- using System; using System.Threading; using MS.Internal.Text.TextInterface; namespace MS.Internal.FontCache { ////// A static, thread safe array cache used to minimize heap allocations. /// ////// Cached arrays are not zero initialized, and they may be larger than /// the requested number of elements. /// internal static class BufferCache { //----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- #region Internal Methods ////// Attempts to release all allocated memory. Has no effect if the cache /// is locked by another thread. /// internal static void Reset() { if (Interlocked.Increment(ref _mutex) == 1) { _buffers = null; } Interlocked.Decrement(ref _mutex); } ////// Returns a GlyphMetrics[]. /// /// /// Minimum number of elements in the array. /// internal static GlyphMetrics[] GetGlyphMetrics(int length) { GlyphMetrics[] glyphMetrics = (GlyphMetrics[])GetBuffer(length, GlyphMetricsIndex); if (glyphMetrics == null) { glyphMetrics = new GlyphMetrics[length]; } return glyphMetrics; } ////// Releases a previously allocated GlyphMetrics[], possibly adding it /// to the cache. /// ////// It is not strictly necessary to call this method after receiving an /// array. The penalty is the performance hit of doing a heap allocation /// on the next request if this method is not called. /// internal static void ReleaseGlyphMetrics(GlyphMetrics[] glyphMetrics) { ReleaseBuffer(glyphMetrics, GlyphMetricsIndex); } ////// Returns a ushort[]. /// /// /// Minimum number of elements in the array. /// internal static ushort[] GetUShorts(int length) { ushort[] ushorts = (ushort[])GetBuffer(length, UShortsIndex); if (ushorts == null) { ushorts = new ushort[length]; } return ushorts; } ////// Releases a previously allocated ushort[], possibly adding it /// to the cache. /// ////// It is not strictly necessary to call this method after receiving an /// array. The penalty is the performance hit of doing a heap allocation /// on the next request if this method is not called. /// internal static void ReleaseUShorts(ushort[] ushorts) { ReleaseBuffer(ushorts, UShortsIndex); } ////// Returns a uint[]. /// /// /// Minimum number of elements in the array. /// internal static uint[] GetUInts(int length) { uint[] uints = (uint[])GetBuffer(length, UIntsIndex); if (uints == null) { uints = new uint[length]; } return uints; } ////// Releases a previously allocated uint[], possibly adding it /// to the cache. /// ////// It is not strictly necessary to call this method after receiving an /// array. The penalty is the performance hit of doing a heap allocation /// on the next request if this method is not called. /// internal static void ReleaseUInts(uint[] uints) { ReleaseBuffer(uints, UIntsIndex); } #endregion Internal Methods //------------------------------------------------------ // // Private Methods // //----------------------------------------------------- #region Private Methods ////// Searches for an array in the cache. /// /// /// Minimum number of elements in the array. /// /// /// Specifies the type of array. /// ////// A matching array if present, otherwise null. /// private static Array GetBuffer(int length, int index) { Array buffer = null; if (Interlocked.Increment(ref _mutex) == 1) { if (_buffers != null && _buffers[index] != null && length <= _buffers[index].Length) { buffer = _buffers[index]; _buffers[index] = null; } } Interlocked.Decrement(ref _mutex); return buffer; } ////// Takes ownership of an array. /// /// /// The array. May be null. /// /// /// Specifies the type of array. /// private static void ReleaseBuffer(Array buffer, int index) { if (buffer != null) { if (Interlocked.Increment(ref _mutex) == 1) { if (_buffers == null) { _buffers = new Array[BuffersLength]; } if (_buffers[index] == null || (_buffers[index].Length < buffer.Length && buffer.Length <= MaxBufferLength)) { _buffers[index] = buffer; } } Interlocked.Decrement(ref _mutex); } } #endregion Private Methods //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ #region Private Fields // Max number of elements in any cached array. If a request if made for a larger array // it will always be allocated from the heap. private const int MaxBufferLength = 1024; // Indices in _buffers for each supported type. private const int GlyphMetricsIndex = 0; private const int UIntsIndex = 1; private const int UShortsIndex = 2; private const int BuffersLength = 3; // Guards access to _buffers. static private long _mutex; // Array of cached arrays, one bucker per supported type. // Currently, we cache just one array per type. A more general cache would hold N byte arrays. // However, we don't currently have any scenarios that hold more than one array of the same type // or more than two arrays of different types at the same time, so it is difficult to justify // making the implementation more complex. ComputeTypographyAvailabilities could benefit from // a more general cache (UnicodeRange.GetFullRange could use a cached array), but the savings // in profiled scenarios are small, ~16k for MSNBaml.exe. If we find a more compelling // scenario a change might be worthwhile. static private Array[] _buffers; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. // -------------------------------------------------------------------------- // // File: BufferCache.cs // // Copyright (C) Microsoft Corporation. All rights reserved. // // Description: BufferCache class implementation. // //--------------------------------------------------------------------------- using System; using System.Threading; using MS.Internal.Text.TextInterface; namespace MS.Internal.FontCache { ////// A static, thread safe array cache used to minimize heap allocations. /// ////// Cached arrays are not zero initialized, and they may be larger than /// the requested number of elements. /// internal static class BufferCache { //----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- #region Internal Methods ////// Attempts to release all allocated memory. Has no effect if the cache /// is locked by another thread. /// internal static void Reset() { if (Interlocked.Increment(ref _mutex) == 1) { _buffers = null; } Interlocked.Decrement(ref _mutex); } ////// Returns a GlyphMetrics[]. /// /// /// Minimum number of elements in the array. /// internal static GlyphMetrics[] GetGlyphMetrics(int length) { GlyphMetrics[] glyphMetrics = (GlyphMetrics[])GetBuffer(length, GlyphMetricsIndex); if (glyphMetrics == null) { glyphMetrics = new GlyphMetrics[length]; } return glyphMetrics; } ////// Releases a previously allocated GlyphMetrics[], possibly adding it /// to the cache. /// ////// It is not strictly necessary to call this method after receiving an /// array. The penalty is the performance hit of doing a heap allocation /// on the next request if this method is not called. /// internal static void ReleaseGlyphMetrics(GlyphMetrics[] glyphMetrics) { ReleaseBuffer(glyphMetrics, GlyphMetricsIndex); } ////// Returns a ushort[]. /// /// /// Minimum number of elements in the array. /// internal static ushort[] GetUShorts(int length) { ushort[] ushorts = (ushort[])GetBuffer(length, UShortsIndex); if (ushorts == null) { ushorts = new ushort[length]; } return ushorts; } ////// Releases a previously allocated ushort[], possibly adding it /// to the cache. /// ////// It is not strictly necessary to call this method after receiving an /// array. The penalty is the performance hit of doing a heap allocation /// on the next request if this method is not called. /// internal static void ReleaseUShorts(ushort[] ushorts) { ReleaseBuffer(ushorts, UShortsIndex); } ////// Returns a uint[]. /// /// /// Minimum number of elements in the array. /// internal static uint[] GetUInts(int length) { uint[] uints = (uint[])GetBuffer(length, UIntsIndex); if (uints == null) { uints = new uint[length]; } return uints; } ////// Releases a previously allocated uint[], possibly adding it /// to the cache. /// ////// It is not strictly necessary to call this method after receiving an /// array. The penalty is the performance hit of doing a heap allocation /// on the next request if this method is not called. /// internal static void ReleaseUInts(uint[] uints) { ReleaseBuffer(uints, UIntsIndex); } #endregion Internal Methods //------------------------------------------------------ // // Private Methods // //----------------------------------------------------- #region Private Methods ////// Searches for an array in the cache. /// /// /// Minimum number of elements in the array. /// /// /// Specifies the type of array. /// ////// A matching array if present, otherwise null. /// private static Array GetBuffer(int length, int index) { Array buffer = null; if (Interlocked.Increment(ref _mutex) == 1) { if (_buffers != null && _buffers[index] != null && length <= _buffers[index].Length) { buffer = _buffers[index]; _buffers[index] = null; } } Interlocked.Decrement(ref _mutex); return buffer; } ////// Takes ownership of an array. /// /// /// The array. May be null. /// /// /// Specifies the type of array. /// private static void ReleaseBuffer(Array buffer, int index) { if (buffer != null) { if (Interlocked.Increment(ref _mutex) == 1) { if (_buffers == null) { _buffers = new Array[BuffersLength]; } if (_buffers[index] == null || (_buffers[index].Length < buffer.Length && buffer.Length <= MaxBufferLength)) { _buffers[index] = buffer; } } Interlocked.Decrement(ref _mutex); } } #endregion Private Methods //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ #region Private Fields // Max number of elements in any cached array. If a request if made for a larger array // it will always be allocated from the heap. private const int MaxBufferLength = 1024; // Indices in _buffers for each supported type. private const int GlyphMetricsIndex = 0; private const int UIntsIndex = 1; private const int UShortsIndex = 2; private const int BuffersLength = 3; // Guards access to _buffers. static private long _mutex; // Array of cached arrays, one bucker per supported type. // Currently, we cache just one array per type. A more general cache would hold N byte arrays. // However, we don't currently have any scenarios that hold more than one array of the same type // or more than two arrays of different types at the same time, so it is difficult to justify // making the implementation more complex. ComputeTypographyAvailabilities could benefit from // a more general cache (UnicodeRange.GetFullRange could use a cached array), but the savings // in profiled scenarios are small, ~16k for MSNBaml.exe. If we find a more compelling // scenario a change might be worthwhile. static private Array[] _buffers; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Vector3D.cs
- RuntimeWrappedException.cs
- EndEvent.cs
- KnowledgeBase.cs
- RuntimeCompatibilityAttribute.cs
- ApplicationManager.cs
- StructuredProperty.cs
- SamlSubject.cs
- CodePageEncoding.cs
- XmlSerializerAssemblyAttribute.cs
- RegistryExceptionHelper.cs
- EditorPartCollection.cs
- log.cs
- RC2CryptoServiceProvider.cs
- HeaderCollection.cs
- ConfigurationCollectionAttribute.cs
- MetadataSerializer.cs
- RoleManagerEventArgs.cs
- TokenDescriptor.cs
- DeobfuscatingStream.cs
- FloaterParaClient.cs
- SQLString.cs
- PermissionSetTriple.cs
- ExpressionBindingCollection.cs
- InkCanvasSelection.cs
- CompilationSection.cs
- DynamicDataExtensions.cs
- ColorMap.cs
- ParameterCollection.cs
- EmptyStringExpandableObjectConverter.cs
- FormCollection.cs
- CompilerErrorCollection.cs
- BaseAddressElement.cs
- HostExecutionContextManager.cs
- CommandConverter.cs
- EngineSiteSapi.cs
- EncodingNLS.cs
- SchemaElement.cs
- GregorianCalendar.cs
- WindowsListViewGroupSubsetLink.cs
- ExecutionEngineException.cs
- _ConnectOverlappedAsyncResult.cs
- UserPersonalizationStateInfo.cs
- IPipelineRuntime.cs
- WindowsListViewItemCheckBox.cs
- MessageFilterException.cs
- PermissionSetTriple.cs
- MethodExpression.cs
- AsymmetricAlgorithm.cs
- LiteralDesigner.cs
- ClientRoleProvider.cs
- WebPartDisplayModeEventArgs.cs
- AdPostCacheSubstitution.cs
- AccessDataSource.cs
- SqlDataAdapter.cs
- SectionInformation.cs
- PromptStyle.cs
- NetStream.cs
- ConnectionPoolManager.cs
- DecodeHelper.cs
- objectresult_tresulttype.cs
- NullReferenceException.cs
- BatchStream.cs
- RuleRefElement.cs
- NetDataContractSerializer.cs
- TabControl.cs
- NameTable.cs
- PassportAuthentication.cs
- NullableLongSumAggregationOperator.cs
- DataControlCommands.cs
- FixedSOMPageConstructor.cs
- MemberDescriptor.cs
- GifBitmapEncoder.cs
- selecteditemcollection.cs
- WeakRefEnumerator.cs
- EventProviderWriter.cs
- DataControlCommands.cs
- List.cs
- XmlSchemaGroup.cs
- ListView.cs
- HostProtectionException.cs
- SqlDataSourceCommandEventArgs.cs
- BindingBase.cs
- TemplateComponentConnector.cs
- Rss20FeedFormatter.cs
- RijndaelManagedTransform.cs
- ScriptComponentDescriptor.cs
- Sentence.cs
- BuildManagerHost.cs
- CommandPlan.cs
- ImageListStreamer.cs
- LoadedOrUnloadedOperation.cs
- FigureParaClient.cs
- LoopExpression.cs
- ImmutableObjectAttribute.cs
- ToolBarPanel.cs
- MarkedHighlightComponent.cs
- VerticalAlignConverter.cs
- FormViewPagerRow.cs
- DbConnectionPoolOptions.cs