AliasGenerator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / Utils / AliasGenerator.cs / 1305376 / AliasGenerator.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Text; 

namespace System.Data.Common.Utils 
{ 
    /// 
    /// Generates monotonically increasing names of the form PrefixCounter, where Prefix is an optional prefix string and Counter is the string representation of a monotonically increasing int value that wraps to zero at int.MaxValue 
    /// 
    internal sealed class AliasGenerator
    {
        // beyond this size - we recycle the cache and regenerate names 
        // this recycling is in place because CTreeGenerator.GenerateNameForVar has prefix of "columnName" which could be unbounded
        private const int MaxPrefixCount = 500; 
 
        // beyond this size per prefix, we don't cache the names (really large queries)
        private const int CacheSize = 250; 

        // this caches integer->string so that happens less fequently
        private readonly static string[] _counterNames = new string[CacheSize];
 
        // We are using a copy-on-write instead of lock-on-read because dictionary is not multi-reader/single-writer safe.
        // safe for frequent multi-thread reading by creating new instances (copy of previous instance) for uncommon writes. 
        private static Dictionary _prefixCounter; 

        private int _counter; 
        private readonly string _prefix;
        private string[] _cache;

        ///  
        /// Constructs a new AliasGenerator with the specified prefix string
        ///  
        /// The prefix string that will appear as the first part of all aliases generated by this AliasGenerator. May be null to indicate that no prefix should be used 
        internal AliasGenerator(string prefix) : this(prefix, CacheSize) { }
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1309:UseOrdinalStringComparison", MessageId = "System.Collections.Generic.Dictionary`2.#ctor(System.Int32,System.Collections.Generic.IEqualityComparer`1)")]
        internal AliasGenerator(string prefix, int cacheSize)
        {
            _prefix = prefix ?? String.Empty; 

            // don't cache all alias, some are truely unique like CommandTree.BindingAliases 
            if (0 < cacheSize) 
            {
                string[] cache = null; 
                Dictionary updatedCache;
                Dictionary prefixCounter;
                while ((null == (prefixCounter = _prefixCounter)) || !prefixCounter.TryGetValue(prefix, out _cache))
                { 
                    if (null == cache)
                    {   // we need to create an instance, but it a different thread may win 
                        cache = new string[cacheSize]; 
                    }
 
                    // grow the cache for prefixes
                    // We are using a copy-on-write instead of lock-on-read because dictionary is not multi-reader/single-writer safe.
                    //     a)Create a larger dictionary
                    //     b) Copy references from previous dictionary 
                    //     c) If previous dictionary changed references, repeat from (a)
                    //     d) We now know the individual cache 
                    int capacity = 1 + ((null != prefixCounter) ? prefixCounter.Count : 0); 
                    updatedCache = new Dictionary(capacity, StringComparer.InvariantCultureIgnoreCase);
                    if ((null != prefixCounter) && (capacity < MaxPrefixCount)) 
                    {
                        foreach (KeyValuePair entry in prefixCounter)
                        {
                            updatedCache.Add(entry.Key, entry.Value); 
                        }
                    } 
                    updatedCache.Add(prefix, cache); 
                    System.Threading.Interlocked.CompareExchange(ref _prefixCounter, updatedCache, prefixCounter);
                } 
            }
        }

        ///  
        /// Generates the next alias and increments the Counter.
        ///  
        /// The generated alias 
        internal string Next()
        { 
            _counter = Math.Max(unchecked(1+_counter), 0);
            return GetName(_counter);
        }
 
        /// 
        /// Generates the alias for the index. 
        ///  
        /// index to generate the alias for
        /// The generated alias 
        internal string GetName(int index)
        {
            string name;
            if ((null == _cache) || unchecked((uint)_cache.Length <= (uint)index)) 
            {   // names are not cached beyond a particlar size
                name = String.Concat(_prefix, index.ToString(CultureInfo.InvariantCulture)); 
            } 
            else if (null == (name = _cache[index]))
            {   // name has not been generated and cached yet 
                if (unchecked((uint)_counterNames.Length <= (uint)index))
                {   // integer->string are not cached beyond a particular size
                    name = index.ToString(CultureInfo.InvariantCulture);
                } 
                else if (null == (name = _counterNames[index]))
                {   // generate and cache the integer->string 
                    _counterNames[index] = name = index.ToString(CultureInfo.InvariantCulture); 
                }
                // generate and cache the prefix+integer 
                _cache[index] = name = String.Concat(_prefix, name);
            }
            return name;
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Text; 

namespace System.Data.Common.Utils 
{ 
    /// 
    /// Generates monotonically increasing names of the form PrefixCounter, where Prefix is an optional prefix string and Counter is the string representation of a monotonically increasing int value that wraps to zero at int.MaxValue 
    /// 
    internal sealed class AliasGenerator
    {
        // beyond this size - we recycle the cache and regenerate names 
        // this recycling is in place because CTreeGenerator.GenerateNameForVar has prefix of "columnName" which could be unbounded
        private const int MaxPrefixCount = 500; 
 
        // beyond this size per prefix, we don't cache the names (really large queries)
        private const int CacheSize = 250; 

        // this caches integer->string so that happens less fequently
        private readonly static string[] _counterNames = new string[CacheSize];
 
        // We are using a copy-on-write instead of lock-on-read because dictionary is not multi-reader/single-writer safe.
        // safe for frequent multi-thread reading by creating new instances (copy of previous instance) for uncommon writes. 
        private static Dictionary _prefixCounter; 

        private int _counter; 
        private readonly string _prefix;
        private string[] _cache;

        ///  
        /// Constructs a new AliasGenerator with the specified prefix string
        ///  
        /// The prefix string that will appear as the first part of all aliases generated by this AliasGenerator. May be null to indicate that no prefix should be used 
        internal AliasGenerator(string prefix) : this(prefix, CacheSize) { }
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1309:UseOrdinalStringComparison", MessageId = "System.Collections.Generic.Dictionary`2.#ctor(System.Int32,System.Collections.Generic.IEqualityComparer`1)")]
        internal AliasGenerator(string prefix, int cacheSize)
        {
            _prefix = prefix ?? String.Empty; 

            // don't cache all alias, some are truely unique like CommandTree.BindingAliases 
            if (0 < cacheSize) 
            {
                string[] cache = null; 
                Dictionary updatedCache;
                Dictionary prefixCounter;
                while ((null == (prefixCounter = _prefixCounter)) || !prefixCounter.TryGetValue(prefix, out _cache))
                { 
                    if (null == cache)
                    {   // we need to create an instance, but it a different thread may win 
                        cache = new string[cacheSize]; 
                    }
 
                    // grow the cache for prefixes
                    // We are using a copy-on-write instead of lock-on-read because dictionary is not multi-reader/single-writer safe.
                    //     a)Create a larger dictionary
                    //     b) Copy references from previous dictionary 
                    //     c) If previous dictionary changed references, repeat from (a)
                    //     d) We now know the individual cache 
                    int capacity = 1 + ((null != prefixCounter) ? prefixCounter.Count : 0); 
                    updatedCache = new Dictionary(capacity, StringComparer.InvariantCultureIgnoreCase);
                    if ((null != prefixCounter) && (capacity < MaxPrefixCount)) 
                    {
                        foreach (KeyValuePair entry in prefixCounter)
                        {
                            updatedCache.Add(entry.Key, entry.Value); 
                        }
                    } 
                    updatedCache.Add(prefix, cache); 
                    System.Threading.Interlocked.CompareExchange(ref _prefixCounter, updatedCache, prefixCounter);
                } 
            }
        }

        ///  
        /// Generates the next alias and increments the Counter.
        ///  
        /// The generated alias 
        internal string Next()
        { 
            _counter = Math.Max(unchecked(1+_counter), 0);
            return GetName(_counter);
        }
 
        /// 
        /// Generates the alias for the index. 
        ///  
        /// index to generate the alias for
        /// The generated alias 
        internal string GetName(int index)
        {
            string name;
            if ((null == _cache) || unchecked((uint)_cache.Length <= (uint)index)) 
            {   // names are not cached beyond a particlar size
                name = String.Concat(_prefix, index.ToString(CultureInfo.InvariantCulture)); 
            } 
            else if (null == (name = _cache[index]))
            {   // name has not been generated and cached yet 
                if (unchecked((uint)_counterNames.Length <= (uint)index))
                {   // integer->string are not cached beyond a particular size
                    name = index.ToString(CultureInfo.InvariantCulture);
                } 
                else if (null == (name = _counterNames[index]))
                {   // generate and cache the integer->string 
                    _counterNames[index] = name = index.ToString(CultureInfo.InvariantCulture); 
                }
                // generate and cache the prefix+integer 
                _cache[index] = name = String.Concat(_prefix, name);
            }
            return name;
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK