SecondaryIndexList.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / SecondaryIndexList.cs / 1 / SecondaryIndexList.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards
{ 
    using System;
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Runtime.InteropServices;
    using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace; 

    //
    // Summary:
    //  Class to wrap and manage all indexes for a given file store. 
    //
    // Remarks: 
    //  This class is internal to the file store 
    //
    internal unsafe class SecondaryIndexList 
    {
        Hashtable m_indexes;
        bool m_isOpen;
 
        IComparer m_searchComparer;
        IComparer m_sortComparer; 
 

        // 
        // Summary:
        //
        // Remarks:
        //  the value passed in to this method should be SecondaryIndexDefinition.MasterIndex 
        //
        // Parameters: 
        //  definitions:        The definitions to use for each SecondaryIndex 
        //                      object that is created internally.
        // 
        public SecondaryIndexList( SecondaryIndexDefinition[] definitions )
        {
            if( null == definitions || 0 == definitions.Length )
            { 
                throw IDT.ThrowHelperArgumentNull( "definitions" );
            } 
 
            m_indexes = new Hashtable(
                definitions.Length, 
                StringComparer.Create(
                    System.Globalization.CultureInfo.InvariantCulture, false ) );

            m_sortComparer = new SortComparer( ); 
            m_searchComparer = new SearchComparer( );
 
            for( int i = 0; i < definitions.Length; i++ ) 
            {
                m_indexes.Add( 
                            definitions[ i ].Name,
                            new SecondaryIndex(
                                    definitions[ i ],
                                    m_searchComparer, 
                                    m_sortComparer ) );
            } 
 
            m_isOpen = true;
        } 

        //
        // Summary:
        //  Gets the current count of indexes in the list 
        //
        public int Count 
        { 
            get
            { 
                ThrowIfNotOpen( );
                return m_indexes.Count;
            }
        } 

        // 
        // Summary: 
        //  Gets the hashtable used to contain the indexes
        // 
        // Remarks:
        //  This is intended for use by tools only.
        //
        internal Hashtable InnerIndexes 
        {
            get 
            { 
                ThrowIfNotOpen( );
                return m_indexes; 
            }
        }

 
        //
        // Summary: 
        //  Initializes a specific SecondaryIndex with the given data. 
        //
        // Remarks: 
        //  indexId must be found in the indexDefinitions used to construct this class
        //
        // Parameters:
        //  indexId:        the name of the index to initialize 
        //  buffer:         the raw buffer to use
        //  lastIndex:      the last used index in that buffer. 
        // 
        public void SetBuffer( string indexId, byte[] buffer, Int32 lastIndex )
        { 
            ThrowIfNotOpen( );
            if( !m_indexes.ContainsKey( indexId ) )
            {
                throw IDT.ThrowHelperError( new ArgumentOutOfRangeException( 
                                        "indexId",
                                        indexId, 
                                        SR.GetString( SR.StoreIndexNameInvalid ) ) ); 
            }
 
            if( null == buffer || 0 == buffer.Length )
            {
                throw IDT.ThrowHelperArgumentNull( "buffer" );
            } 

            // 
            // -1 is valid becuase that means not initialized. 
            //
            if( (UInt32)lastIndex > (UInt32)buffer.Length && lastIndex != -1) 
            {
                throw IDT.ThrowHelperError( new ArgumentOutOfRangeException(
                                    "lastIndex",
                                    lastIndex, 
                                    SR.GetString( SR.StoreLastIndexOutOfRange ) ) );
            } 
 

            ((SecondaryIndex)m_indexes[ indexId ]).SetBuffer( buffer, lastIndex ); 
        }

        //
        // Summary: 
        //  Updates all indexes mapping the specified localId
        // 
        // Parameters: 
        //  localId:        localId to update the index data for
        //  indexBuffer:    Buffer containing all of the index information. 
        //  remove:         boolean indicated if all should be remove before insert.
        //
        public void SetValuesForId( Int32 localId, DataRowIndexBuffer indexBuffer, bool remove )
        { 
            ThrowIfNotOpen( );
 
            if( localId < 0 ) 
            {
                throw IDT.ThrowHelperError( new ArgumentOutOfRangeException( 
                                "localId",
                                localId,
                                SR.GetString( SR.StoreLocalIdOutOfRange ) ) );
            } 

            if( null == indexBuffer ) 
            { 
                throw IDT.ThrowHelperArgumentNull( "indexBuffer" );
            } 

            PreValidateIndexBuffer( indexBuffer );

            foreach( string key in m_indexes.Keys ) 
            {
                SecondaryIndex index = (SecondaryIndex)m_indexes[ key ]; 
 
                index.SetValuesForId( localId, indexBuffer, remove );
            } 
        }

        //
        // Summary: 
        //  Performs a match of the parameter, storing the results in the specified collection
        // 
        // Parameters: 
        //  match:          the values to match against.
        //  localIds:       the collection to add the results too 
        //
        // Returns:
        //
        // 
        public bool Match( QueryParameter match, LocalIdCollection localIds )
        { 
            ThrowIfNotOpen( ); 

            if( null == localIds ) 
            {
                throw IDT.ThrowHelperArgumentNull( "localIds" );
            }
 
            if( null == match )
            { 
                throw IDT.ThrowHelperArgumentNull( "match" ); 
            }
            if( !m_indexes.ContainsKey( match.IndexName ) ) 
            {
                throw IDT.ThrowHelperError( new ArgumentOutOfRangeException(
                                        "match",
                                        match.IndexName, 
                                        SR.GetString( SR.StoreIndexNameInvalid ) ) );
            } 
 

            SecondaryIndex indexToSearch = (SecondaryIndex)m_indexes[ match.IndexName ]; 

            //
            // Just return if the index is empty.
            // 
            if( -1 == indexToSearch.LastIndex )
            { 
                return false; 
            }
 
            IndexObject obj = null;
            int foundAt = -1;
            bool found = false;
 
            for( int i = 0; i < match.Count; i++ )
            { 
                obj = match[ i ]; 

                foundAt = indexToSearch.Match( obj, localIds, 0, indexToSearch.LastIndex ); 

                if( foundAt >= 0 )
                {
                    found = true; 
                }
 
            } 

            return found; 

        }

        // 
        // Summary:
        //  Populates the index information for the specified data row 
        // 
        // Remarks:
        //  All index values are precompiled, and are NOT reversed back to objects. 
        //
        // Parameters:
        //  row:        The data row to populate.
        // 
        //
        public void PopulateRowIndexBuffer( DataRow row ) 
        { 
            ThrowIfNotOpen();
            DataRowIndexBuffer b = row.IndexBuffer; 
            foreach( string key in m_indexes.Keys )
            {
                SecondaryIndex index = (SecondaryIndex)m_indexes[ key ];
                index.PopulateRowIndexBuffer( row.IndexBuffer,row.LocalId ); 
            }
 
        } 

        // 
        // Summary:
        //  Remove all values in all indexes for the specified local id
        //
        // Parameters: 
        //  id:         the localId to remove all data for
        // 
        public void RemoveAllValuesForId( Int32 id ) 
        {
            foreach( string key in m_indexes.Keys ) 
            {
                RemoveAllValuesForId( key, id );
            }
 
        }
 
        // 
        // Summary:
        //  Remove all values the specified index for the specified local id 
        //
        // Parameters:
        //  indexId:    the name of the index to remove the data from
        //  id:         the localId to remove all data for 
        //
        public void RemoveAllValuesForId( string indexId, Int32 id ) 
        { 
            ThrowIfNotOpen( );
            if( !m_indexes.ContainsKey( indexId ) ) 
            {
                throw IDT.ThrowHelperError( new ArgumentOutOfRangeException(
                                        "indexId",
                                        indexId, 
                                        SR.GetString( SR.StoreIndexNameInvalid ) ) );
            } 
 

            ((SecondaryIndex)m_indexes[ indexId ]).RemoveAllValuesForId( id ); 
        }

        //
        // Summary: 
        //  This will Zero all memory by default when it closes the indexes.
        //  Close all indexes and release all resources. 
        // 
        public void Close()
        { 
            if( m_isOpen )
            {
                foreach( string key in m_indexes.Keys )
                { 
                    ((SecondaryIndex)m_indexes[ key ]).Close( );
                } 
 
                m_isOpen = false;
            } 
        }


        // 
        // Summary:
        //  Performs pre-validation of data agains all index definitions. 
        // 
        // Remarks:
        //  Only non data scanning validation can be performed. 
        //  We make sure all required index values are present,
        //      there form will be validated later.
        //
        // Parameters: 
        //  buffer:         The index data buffer to validate.
        // 
        void PreValidateIndexBuffer( DataRowIndexBuffer buffer ) 
        {
            foreach( string key in m_indexes.Keys ) 
            {
                SecondaryIndex index = (SecondaryIndex)m_indexes[ key ];
                if( SecondaryIndexSettings.Nullable != (  index.Definition.Settings & SecondaryIndexSettings.Nullable ) )
                { 
                    if( null == buffer[ key ] || 0 == buffer.GetValueCount( key ) )
                    { 
                        throw IDT.ThrowHelperError( new InvalidOperationException( 
                                        SR.GetString( SR.StoreIndexValueCanNotBeNull,index.Definition.Name ) ) );
                    } 
                }
            }
        }
 

        void ThrowIfNotOpen() 
        { 
            if( !m_isOpen )
            { 
                throw IDT.ThrowHelperError( new ObjectDisposedException( "SecondaryIndexList" ) );
            }
        }
 
        unsafe class SearchComparer : IComparer
        { 
            public int Compare( IntPtr x, IntPtr y ) 
            {
                if( IntPtr.Zero == x ) 
                {
                    throw IDT.ThrowHelperArgumentNull( "x" );
                }
                if( IntPtr.Zero == y ) 
                {
                    throw IDT.ThrowHelperArgumentNull( "y" ); 
                } 
                return SearchComparer.Compare( (SecondaryIndexItem*)x, (SecondaryIndexItem*)y );
            } 
            public static int Compare( SecondaryIndexItem obj1, SecondaryIndexItem obj2 )
            {
                return Compare( &obj1, &obj2 );
            } 

            public static int Compare( SecondaryIndexItem* pObj1, SecondaryIndexItem* pObj2 ) 
            { 

                if( null == pObj1 ) 
                {
                    throw IDT.ThrowHelperArgumentNull( "pObj1" );
                }
                if( null == pObj2 ) 
                {
                    throw IDT.ThrowHelperArgumentNull( "pObj2" ); 
                } 
                byte* pHash1 = &pObj1->HashValue;
                byte* pHash2 = &pObj2->HashValue; 
                for( int i = 0; i < SecondaryIndexItem.HashValueSize; i++ )
                {
                    int diff = pHash1[ i ] - pHash2[ i ];
                    if( 0 != diff ) 
                    {
                        return diff; 
                    } 
                }
 
                return 0;
            }
        }
        unsafe class SortComparer : IComparer 
        {
            public int Compare( IntPtr x, IntPtr y ) 
            { 
                if( IntPtr.Zero == x )
                { 
                    throw IDT.ThrowHelperArgumentNull( "x" );
                }
                if( IntPtr.Zero == y )
                { 
                    throw IDT.ThrowHelperArgumentNull( "y" );
                } 
                return SortComparer.Compare( (SecondaryIndexItem*)x, (SecondaryIndexItem*)y ); 
            }
 
            public static int Compare( SecondaryIndexItem obj1, SecondaryIndexItem obj2 )
            {
                return SortComparer.Compare( &obj1, &obj2 );
            } 

 
            public static int Compare( SecondaryIndexItem* pObj1, SecondaryIndexItem* pObj2 ) 
            {
                if( null == pObj1 ) 
                {
                    throw IDT.ThrowHelperArgumentNull( "pObj1" );
                }
                if( null == pObj2 ) 
                {
                    throw IDT.ThrowHelperArgumentNull( "pObj2" ); 
                } 
                byte* pHash1 = &pObj1->HashValue;
                byte* pHash2 = &pObj2->HashValue; 
                for( int i = 0; i < SecondaryIndexItem.HashValueSize; i++ )
                {
                    int diff = pHash1[ i ] - pHash2[ i ];
                    if( 0 != diff ) 
                    {
                        return diff; 
                    } 
                }
 
                return pObj1->LocalId - pObj2->LocalId;
            }
        }
 
    }
} 

// 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