NameTable.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Xml / System / Xml / NameTable.cs / 1 / NameTable.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System; 

namespace System.Xml { 

    /// 
    /// 
    ///     
    ///       XmlNameTable implemented as a simple hash table.
    ///     
    ///  
    public class NameTable : XmlNameTable {
// 
// Private types
//
        class Entry {
            internal string str; 
            internal int    hashCode;
            internal Entry  next; 
 
            internal Entry( string str, int hashCode, Entry next ) {
                this.str = str; 
                this.hashCode = hashCode;
                this.next = next;
            }
        } 

// 
// Fields 
//
        Entry[] entries; 
        int     count;
        int     mask;
        int     hashCodeRandomizer;
 
//
// Constructor 
// 
        /// 
        ///  
        ///      Public constructor.
        /// 
        public NameTable() {
            mask = 31; 
            entries = new Entry[mask+1];
            hashCodeRandomizer = Environment.TickCount; 
        } 

// 
// XmlNameTable public methods
//
        /// 
        ///  
        ///      Add the given string to the NameTable or return
        ///      the existing string if it is already in the NameTable. 
        ///  
        public override string Add( string key ) {
            if ( key == null ) { 
                throw new ArgumentNullException( "key" );
            }
            int len = key.Length;
            if ( len == 0 ) { 
                return string.Empty;
            } 
            int hashCode = len + hashCodeRandomizer; 
            // use key.Length to eliminate the rangecheck
            for ( int i = 0; i < key.Length; i++ ) { 
                hashCode += ( hashCode << 7 ) ^ key[i];
            }
            // mix it a bit more
            hashCode -= hashCode >> 17; 
            hashCode -= hashCode >> 11;
            hashCode -= hashCode >> 5; 
 
            for ( Entry e = entries[hashCode & mask]; e != null; e = e.next ) {
                if ( e.hashCode == hashCode && e.str.Equals( key ) ) { 
                    return e.str;
                }
            }
            return AddEntry( key, hashCode ); 
        }
 
        ///  
        /// 
        ///      Add the given string to the NameTable or return 
        ///      the existing string if it is already in the NameTable.
        /// 
        public override string Add( char[] key, int start, int len ) {
            if ( len == 0 ) { 
                return string.Empty;
            } 
 
            int hashCode = len + hashCodeRandomizer;
            hashCode += ( hashCode << 7 ) ^ key[start];   // this will throw IndexOutOfRangeException in case the start index is invalid 
            int end = start+len;
            for ( int i = start + 1; i < end; i++) {
                hashCode += ( hashCode << 7 ) ^ key[i];
            } 
            // mix it a bit more
            hashCode -= hashCode >> 17; 
            hashCode -= hashCode >> 11; 
            hashCode -= hashCode >> 5;
 
            for ( Entry e = entries[hashCode & mask]; e != null; e = e.next ) {
                if ( e.hashCode == hashCode && TextEquals( e.str, key, start ) ) {
                    return e.str;
                } 
            }
            return AddEntry( new string( key, start, len ), hashCode ); 
        } 

        ///  
        /// 
        ///      Find the matching string in the NameTable.
        /// 
        public override string Get( string value ) { 
            if ( value == null ) {
                throw new ArgumentNullException("value"); 
            } 
            if ( value.Length == 0 ) {
                return string.Empty; 
            }

            int len = value.Length + hashCodeRandomizer;
            int hashCode = len; 
            // use value.Length to eliminate the rangecheck
            for ( int i = 0; i < value.Length; i++ ) { 
                hashCode += ( hashCode << 7 ) ^ value[i]; 
            }
            // mix it a bit more 
            hashCode -= hashCode >> 17;
            hashCode -= hashCode >> 11;
            hashCode -= hashCode >> 5;
 
            for ( Entry e = entries[hashCode & mask]; e != null; e = e.next ) {
                if ( e.hashCode == hashCode && e.str.Equals( value ) ) { 
                    return e.str; 
                }
            } 
            return null;
        }

        ///  
        /// 
        ///      Find the matching string atom given a range of 
        ///      characters. 
        /// 
        public override string Get( char[] key, int start, int len ) { 
            if ( len == 0 ) {
                return string.Empty;
            }
 
            int hashCode = len + hashCodeRandomizer;
            hashCode += ( hashCode << 7 ) ^ key[start];   // this will throw IndexOutOfRangeException in case the start index is invalid 
            int end = start+len; 
            for ( int i = start + 1; i < end; i++) {
                hashCode += ( hashCode << 7 ) ^ key[i]; 
            }
            // mix it a bit more
            hashCode -= hashCode >> 17;
            hashCode -= hashCode >> 11; 
            hashCode -= hashCode >> 5;
 
            for ( Entry e = entries[hashCode & mask]; e != null; e = e.next ) { 
                if ( e.hashCode == hashCode && TextEquals( e.str, key, start ) ) {
                    return e.str; 
                }
            }
            return null;
        } 

// 
// Private methods 
//
 
        private string AddEntry( string str, int hashCode ) {
            int index = hashCode & mask;
            Entry e = new Entry( str, hashCode, entries[index] );
            entries[index] = e; 
            if ( count++ == mask ) {
                Grow(); 
            } 
            return e.str;
        } 

        private void Grow() {
            int newMask = mask * 2 + 1;
            Entry[] oldEntries = entries; 
            Entry[] newEntries = new Entry[newMask+1];
 
            // use oldEntries.Length to eliminate the rangecheck 
            for ( int i = 0; i < oldEntries.Length; i++ ) {
                Entry e = oldEntries[i]; 
                while ( e != null ) {
                    int newIndex = e.hashCode & newMask;
                    Entry tmp = e.next;
                    e.next = newEntries[newIndex]; 
                    newEntries[newIndex] = e;
                    e = tmp; 
                } 
            }
 
            entries = newEntries;
            mask = newMask;
        }
 
        private static bool TextEquals( string array, char[] text, int start ) {
            // use array.Length to eliminate the rangecheck 
            for ( int i = 0; i < array.Length; i++ ) { 
                if ( array[i] != text[start+i] ) {
                    return false; 
                }
            }
            return true;
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

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