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
- Char.cs
- recordstatescratchpad.cs
- ECDsaCng.cs
- WebPartZoneAutoFormat.cs
- DataGridViewHeaderCell.cs
- InternalUserCancelledException.cs
- DynamicMethod.cs
- PageEventArgs.cs
- ObjectIDGenerator.cs
- CompiledXpathExpr.cs
- PropertyNames.cs
- ModulesEntry.cs
- METAHEADER.cs
- XmlLanguageConverter.cs
- ServiceDocumentFormatter.cs
- IApplicationTrustManager.cs
- DesignerResources.cs
- GridViewDeleteEventArgs.cs
- ComboBoxRenderer.cs
- RestHandler.cs
- InputEventArgs.cs
- XmlSerializableServices.cs
- XPathArrayIterator.cs
- IdentitySection.cs
- ACE.cs
- Section.cs
- FunctionQuery.cs
- RijndaelCryptoServiceProvider.cs
- ResolveNameEventArgs.cs
- FocusWithinProperty.cs
- WebControlAdapter.cs
- ComEventsSink.cs
- ParallelTimeline.cs
- BadImageFormatException.cs
- HScrollProperties.cs
- ToolStripDesigner.cs
- GenericTypeParameterBuilder.cs
- SqlDataSourceConfigureSelectPanel.cs
- LOSFormatter.cs
- BasicBrowserDialog.cs
- SignatureToken.cs
- XmlTextAttribute.cs
- SchemaDeclBase.cs
- AstNode.cs
- FileInfo.cs
- Membership.cs
- DocumentSequenceHighlightLayer.cs
- StateChangeEvent.cs
- DBCommandBuilder.cs
- RegionIterator.cs
- AttachInfo.cs
- ExpressionBinding.cs
- ButtonFlatAdapter.cs
- ApplyTemplatesAction.cs
- SpanIndex.cs
- XmlBinaryReader.cs
- FaultHandlingFilter.cs
- SQLSingle.cs
- XmlSerializerFaultFormatter.cs
- Vector3DCollectionValueSerializer.cs
- Message.cs
- Currency.cs
- Base64Decoder.cs
- ModelService.cs
- SiteMap.cs
- DataIdProcessor.cs
- OdbcStatementHandle.cs
- ScriptingWebServicesSectionGroup.cs
- DataGridViewControlCollection.cs
- SubclassTypeValidator.cs
- StreamUpdate.cs
- ViewCellSlot.cs
- UserNameSecurityTokenAuthenticator.cs
- BasePattern.cs
- ViewKeyConstraint.cs
- CheckBoxField.cs
- EncryptedData.cs
- BeginEvent.cs
- Calendar.cs
- DefaultPrintController.cs
- HttpPostServerProtocol.cs
- XmlSchemaAttributeGroup.cs
- LogicalExpressionEditor.cs
- TaiwanLunisolarCalendar.cs
- SecurityPolicySection.cs
- TextParaLineResult.cs
- UidManager.cs
- FontStretch.cs
- JpegBitmapDecoder.cs
- Binding.cs
- MenuScrollingVisibilityConverter.cs
- FileNameEditor.cs
- Lease.cs
- SchemaTypeEmitter.cs
- RestHandler.cs
- DataMisalignedException.cs
- GPPOINT.cs
- SspiSafeHandles.cs
- DiagnosticsConfigurationHandler.cs
- IsolatedStorage.cs