IdentityManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DLinq / Dlinq / IdentityManager.cs / 1 / IdentityManager.cs

                            using System; 
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection; 
using System.Security;
using System.Security.Permissions; 
 
namespace System.Data.Linq {
    using System.Data.Linq.Mapping; 
    using System.Data.Linq.Provider;

    internal abstract class IdentityManager {
        internal abstract object InsertLookup(MetaType type, object instance); 
        internal abstract bool RemoveLike(MetaType type, object instance);
        internal abstract object Find(MetaType type, object[] keyValues); 
        internal abstract object FindLike(MetaType type, object instance); 

        internal static IdentityManager CreateIdentityManager(bool asReadOnly) { 
            if (asReadOnly) {
                return new ReadOnlyIdentityManager();
            }
            else { 
                return new StandardIdentityManager();
            } 
        } 

        class StandardIdentityManager : IdentityManager { 
            Dictionary caches;
            IdentityCache currentCache;
            MetaType currentType;
 
            internal StandardIdentityManager() {
                this.caches = new Dictionary(); 
            } 

            internal override object InsertLookup(MetaType type, object instance) { 
                this.SetCurrent(type);
                return this.currentCache.InsertLookup(instance);
            }
 
            internal override bool RemoveLike(MetaType type, object instance) {
                this.SetCurrent(type); 
                return this.currentCache.RemoveLike(instance); 
            }
 
            internal override object Find(MetaType type, object[] keyValues) {
                this.SetCurrent(type);
                return this.currentCache.Find(keyValues);
            } 

            internal override object FindLike(MetaType type, object instance) { 
                this.SetCurrent(type); 
                return this.currentCache.FindLike(instance);
            } 

            private void SetCurrent(MetaType type) {
                type = type.InheritanceRoot;
                if (this.currentType != type) { 
                    if (!this.caches.TryGetValue(type, out this.currentCache)) {
                        KeyManager km = GetKeyManager(type); 
                        this.currentCache = (IdentityCache)Activator.CreateInstance( 
                            typeof(IdentityCache<,>).MakeGenericType(type.Type, km.KeyType),
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, 
                            new object[] { km }, null
                            );
                        this.caches.Add(type, this.currentCache);
                    } 
                    this.currentType = type;
                } 
            } 

            static KeyManager GetKeyManager(MetaType type) { 
                int n = type.IdentityMembers.Count;
                MetaDataMember mm = type.IdentityMembers[0];

                KeyManager km = (KeyManager)Activator.CreateInstance( 
                            typeof(SingleKeyManager<,>).MakeGenericType(type.Type, mm.Type),
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, 
                            new object[] { mm.StorageAccessor, 0 }, null 
                            );
                for (int i = 1; i < n; i++) { 
                    mm = type.IdentityMembers[i];
                    km = (KeyManager)
                        Activator.CreateInstance(
                            typeof(MultiKeyManager<,,>).MakeGenericType(type.Type, mm.Type, km.KeyType), 
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
                            new object[] { mm.StorageAccessor, i, km }, null 
                            ); 
                }
 
                return km;
            }

            #region Nested type definitions 
            // These types are internal rather than private to work around
            // CLR bug #117419 related to type visibility under partial trust 
            // in nested class scenarios. 

            internal abstract class KeyManager { 
                internal abstract Type KeyType { get; }
            }

            internal abstract class KeyManager : KeyManager { 
                internal abstract K CreateKeyFromInstance(T instance);
                internal abstract bool TryCreateKeyFromValues(object[] values, out K k); 
                internal abstract IEqualityComparer Comparer { get; } 
            }
 
            internal class SingleKeyManager : KeyManager {
                bool isKeyNullAssignable;
                MetaAccessor accessor;
                int offset; 
                IEqualityComparer comparer;
 
                internal SingleKeyManager(MetaAccessor accessor, int offset) { 
                    this.accessor = accessor;
                    this.offset = offset; 
                    this.isKeyNullAssignable = System.Data.Linq.SqlClient.TypeSystem.IsNullAssignable(typeof(V));
                }

                internal override V CreateKeyFromInstance(T instance) { 
                    return this.accessor.GetValue(instance);
                } 
 
                internal override bool TryCreateKeyFromValues(object[] values, out V v) {
                    object o = values[this.offset]; 
                    if (o == null && !this.isKeyNullAssignable) {
                        v = default(V);
                        return false;
                    } 
                    v = (V)o;
                    return true; 
                } 

                internal override Type KeyType { 
                    get { return typeof(V); }
                }

                internal override IEqualityComparer Comparer { 
                    get {
                        if (this.comparer == null) { 
                            this.comparer = EqualityComparer.Default; 
                        }
                        return this.comparer; 
                    }
                }
            }
 
            internal class MultiKeyManager : KeyManager> {
                MetaAccessor accessor; 
                int offset; 
                KeyManager next;
                IEqualityComparer> comparer; 

                internal MultiKeyManager(MetaAccessor accessor, int offset, KeyManager next) {
                    this.accessor = accessor;
                    this.next = next; 
                    this.offset = offset;
                } 
 
                internal override MultiKey CreateKeyFromInstance(T instance) {
                    return new MultiKey( 
                        this.accessor.GetValue(instance),
                        this.next.CreateKeyFromInstance(instance)
                        );
                } 

                internal override bool TryCreateKeyFromValues(object[] values, out MultiKey k) { 
                    System.Diagnostics.Debug.Assert(this.offset < values.Length, "offset is outside the bounds of the values array"); 

                    object o = values[this.offset]; 
                    if (o == null && typeof(V1).IsValueType) {
                        k = default(MultiKey);
                        return false;
                    } 
                    V2 v2;
                    if (!this.next.TryCreateKeyFromValues(values, out v2)) { 
                        k = default(MultiKey); 
                        return false;
                    } 
                    k = new MultiKey((V1)o, v2);
                    return true;
                }
 
                internal override Type KeyType {
                    get { return typeof(MultiKey); } 
                } 

                internal override IEqualityComparer> Comparer { 
                    get {
                        if (this.comparer == null) {
                            this.comparer = new MultiKey.Comparer(EqualityComparer.Default, next.Comparer);
                        } 
                        return this.comparer;
                    } 
                } 
            }
 
            internal struct MultiKey {
                T1 value1;
                T2 value2;
 
                internal MultiKey(T1 value1, T2 value2) {
                    this.value1 = value1; 
                    this.value2 = value2; 
                }
 
                internal class Comparer : IEqualityComparer>, IEqualityComparer {
                    IEqualityComparer comparer1;
                    IEqualityComparer comparer2;
 
                    internal Comparer(IEqualityComparer comparer1, IEqualityComparer comparer2) {
                        this.comparer1 = comparer1; 
                        this.comparer2 = comparer2; 
                    }
 
                    public bool Equals(MultiKey x, MultiKey y) {
                        return this.comparer1.Equals(x.value1, y.value1) &&
                               this.comparer2.Equals(x.value2, y.value2);
                    } 

                    public int GetHashCode(MultiKey x) { 
                        return this.comparer1.GetHashCode(x.value1) ^ this.comparer2.GetHashCode(x.value2); 
                    }
 
                    bool IEqualityComparer.Equals(object x, object y) {
                        return this.Equals((MultiKey)x, (MultiKey)y);
                    }
 
                    int IEqualityComparer.GetHashCode(object x) {
                        return this.GetHashCode((MultiKey)x); 
                    } 
                }
            } 

            internal abstract class IdentityCache {
                internal abstract object Find(object[] keyValues);
                internal abstract object FindLike(object instance); 
                internal abstract object InsertLookup(object instance);
                internal abstract bool RemoveLike(object instance); 
            } 

            internal class IdentityCache : IdentityCache { 
                int[] buckets;
                Slot[] slots;
                int count;
                int freeList; 
                KeyManager keyManager;
                IEqualityComparer comparer; 
 
                public IdentityCache(KeyManager keyManager) {
                    this.keyManager = keyManager; 
                    this.comparer = keyManager.Comparer;
                    buckets = new int[7];
                    slots = new Slot[7];
                    freeList = -1; 
                }
 
                internal override object InsertLookup(object instance) { 
                    T value = (T)instance;
                    K key = this.keyManager.CreateKeyFromInstance(value); 
                    Find(key, ref value, true);
                    return value;
                }
 
                internal override bool RemoveLike(object instance) {
                    T value = (T)instance; 
                    K key = this.keyManager.CreateKeyFromInstance(value); 

                    int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; 
                    int bucket = hashCode % buckets.Length;
                    int last = -1;
                    for (int i = buckets[bucket] - 1; i >= 0; last = i, i = slots[i].next) {
                        if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].key, key)) { 
                            if (last < 0) {
                                buckets[bucket] = slots[i].next + 1; 
                            } 
                            else {
                                slots[last].next = slots[i].next; 
                            }
                            slots[i].hashCode = -1;
                            slots[i].value = default(T);
                            slots[i].next = freeList; 
                            freeList = i;
                            return true; 
                        } 
                    }
                    return false; 
                }

                internal override object Find(object[] keyValues) {
                    K key; 
                    if (this.keyManager.TryCreateKeyFromValues(keyValues, out key)) {
                        T value = default(T); 
                        if (Find(key, ref value, false)) 
                            return value;
                    } 
                    return null;
                }

                internal override object FindLike(object instance) { 
                    T value = (T)instance;
                    K key = this.keyManager.CreateKeyFromInstance(value); 
                    if (Find(key, ref value, false)) 
                        return value;
                    return null; 
                }

                bool Find(K key, ref T value, bool add) {
                    int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; 
                    for (int i = buckets[hashCode % buckets.Length] - 1; i >= 0; i = slots[i].next) {
                        if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].key, key)) { 
                            value = slots[i].value; 
                            return true;
                        } 
                    }
                    if (add) {
                        int index;
                        if (freeList >= 0) { 
                            index = freeList;
                            freeList = slots[index].next; 
                        } 
                        else {
                            if (count == slots.Length) Resize(); 
                            index = count;
                            count++;
                        }
                        int bucket = hashCode % buckets.Length; 
                        slots[index].hashCode = hashCode;
                        slots[index].key = key; 
                        slots[index].value = value; 
                        slots[index].next = buckets[bucket] - 1;
                        buckets[bucket] = index + 1; 
                    }
                    return false;
                }
 
                void Resize() {
                    int newSize = checked(count * 2 + 1); 
                    int[] newBuckets = new int[newSize]; 
                    Slot[] newSlots = new Slot[newSize];
                    Array.Copy(slots, 0, newSlots, 0, count); 
                    for (int i = 0; i < count; i++) {
                        int bucket = newSlots[i].hashCode % newSize;
                        newSlots[i].next = newBuckets[bucket] - 1;
                        newBuckets[bucket] = i + 1; 
                    }
                    buckets = newBuckets; 
                    slots = newSlots; 
                }
 
                internal struct Slot {
                    internal int hashCode;
                    internal K key;
                    internal T value; 
                    internal int next;
                } 
            } 
            #endregion
        } 

        /// 
        /// This is the noop implementation used when object tracking is disabled.
        ///  
        class ReadOnlyIdentityManager : IdentityManager {
            internal ReadOnlyIdentityManager() { } 
            internal override object InsertLookup(MetaType type, object instance) { return instance; } 
            internal override bool RemoveLike(MetaType type, object instance) { return false; }
            internal override object Find(MetaType type, object[] keyValues) { return null; } 
            internal override object FindLike(MetaType type, object instance) { return null; }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection; 
using System.Security;
using System.Security.Permissions; 
 
namespace System.Data.Linq {
    using System.Data.Linq.Mapping; 
    using System.Data.Linq.Provider;

    internal abstract class IdentityManager {
        internal abstract object InsertLookup(MetaType type, object instance); 
        internal abstract bool RemoveLike(MetaType type, object instance);
        internal abstract object Find(MetaType type, object[] keyValues); 
        internal abstract object FindLike(MetaType type, object instance); 

        internal static IdentityManager CreateIdentityManager(bool asReadOnly) { 
            if (asReadOnly) {
                return new ReadOnlyIdentityManager();
            }
            else { 
                return new StandardIdentityManager();
            } 
        } 

        class StandardIdentityManager : IdentityManager { 
            Dictionary caches;
            IdentityCache currentCache;
            MetaType currentType;
 
            internal StandardIdentityManager() {
                this.caches = new Dictionary(); 
            } 

            internal override object InsertLookup(MetaType type, object instance) { 
                this.SetCurrent(type);
                return this.currentCache.InsertLookup(instance);
            }
 
            internal override bool RemoveLike(MetaType type, object instance) {
                this.SetCurrent(type); 
                return this.currentCache.RemoveLike(instance); 
            }
 
            internal override object Find(MetaType type, object[] keyValues) {
                this.SetCurrent(type);
                return this.currentCache.Find(keyValues);
            } 

            internal override object FindLike(MetaType type, object instance) { 
                this.SetCurrent(type); 
                return this.currentCache.FindLike(instance);
            } 

            private void SetCurrent(MetaType type) {
                type = type.InheritanceRoot;
                if (this.currentType != type) { 
                    if (!this.caches.TryGetValue(type, out this.currentCache)) {
                        KeyManager km = GetKeyManager(type); 
                        this.currentCache = (IdentityCache)Activator.CreateInstance( 
                            typeof(IdentityCache<,>).MakeGenericType(type.Type, km.KeyType),
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, 
                            new object[] { km }, null
                            );
                        this.caches.Add(type, this.currentCache);
                    } 
                    this.currentType = type;
                } 
            } 

            static KeyManager GetKeyManager(MetaType type) { 
                int n = type.IdentityMembers.Count;
                MetaDataMember mm = type.IdentityMembers[0];

                KeyManager km = (KeyManager)Activator.CreateInstance( 
                            typeof(SingleKeyManager<,>).MakeGenericType(type.Type, mm.Type),
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, 
                            new object[] { mm.StorageAccessor, 0 }, null 
                            );
                for (int i = 1; i < n; i++) { 
                    mm = type.IdentityMembers[i];
                    km = (KeyManager)
                        Activator.CreateInstance(
                            typeof(MultiKeyManager<,,>).MakeGenericType(type.Type, mm.Type, km.KeyType), 
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
                            new object[] { mm.StorageAccessor, i, km }, null 
                            ); 
                }
 
                return km;
            }

            #region Nested type definitions 
            // These types are internal rather than private to work around
            // CLR bug #117419 related to type visibility under partial trust 
            // in nested class scenarios. 

            internal abstract class KeyManager { 
                internal abstract Type KeyType { get; }
            }

            internal abstract class KeyManager : KeyManager { 
                internal abstract K CreateKeyFromInstance(T instance);
                internal abstract bool TryCreateKeyFromValues(object[] values, out K k); 
                internal abstract IEqualityComparer Comparer { get; } 
            }
 
            internal class SingleKeyManager : KeyManager {
                bool isKeyNullAssignable;
                MetaAccessor accessor;
                int offset; 
                IEqualityComparer comparer;
 
                internal SingleKeyManager(MetaAccessor accessor, int offset) { 
                    this.accessor = accessor;
                    this.offset = offset; 
                    this.isKeyNullAssignable = System.Data.Linq.SqlClient.TypeSystem.IsNullAssignable(typeof(V));
                }

                internal override V CreateKeyFromInstance(T instance) { 
                    return this.accessor.GetValue(instance);
                } 
 
                internal override bool TryCreateKeyFromValues(object[] values, out V v) {
                    object o = values[this.offset]; 
                    if (o == null && !this.isKeyNullAssignable) {
                        v = default(V);
                        return false;
                    } 
                    v = (V)o;
                    return true; 
                } 

                internal override Type KeyType { 
                    get { return typeof(V); }
                }

                internal override IEqualityComparer Comparer { 
                    get {
                        if (this.comparer == null) { 
                            this.comparer = EqualityComparer.Default; 
                        }
                        return this.comparer; 
                    }
                }
            }
 
            internal class MultiKeyManager : KeyManager> {
                MetaAccessor accessor; 
                int offset; 
                KeyManager next;
                IEqualityComparer> comparer; 

                internal MultiKeyManager(MetaAccessor accessor, int offset, KeyManager next) {
                    this.accessor = accessor;
                    this.next = next; 
                    this.offset = offset;
                } 
 
                internal override MultiKey CreateKeyFromInstance(T instance) {
                    return new MultiKey( 
                        this.accessor.GetValue(instance),
                        this.next.CreateKeyFromInstance(instance)
                        );
                } 

                internal override bool TryCreateKeyFromValues(object[] values, out MultiKey k) { 
                    System.Diagnostics.Debug.Assert(this.offset < values.Length, "offset is outside the bounds of the values array"); 

                    object o = values[this.offset]; 
                    if (o == null && typeof(V1).IsValueType) {
                        k = default(MultiKey);
                        return false;
                    } 
                    V2 v2;
                    if (!this.next.TryCreateKeyFromValues(values, out v2)) { 
                        k = default(MultiKey); 
                        return false;
                    } 
                    k = new MultiKey((V1)o, v2);
                    return true;
                }
 
                internal override Type KeyType {
                    get { return typeof(MultiKey); } 
                } 

                internal override IEqualityComparer> Comparer { 
                    get {
                        if (this.comparer == null) {
                            this.comparer = new MultiKey.Comparer(EqualityComparer.Default, next.Comparer);
                        } 
                        return this.comparer;
                    } 
                } 
            }
 
            internal struct MultiKey {
                T1 value1;
                T2 value2;
 
                internal MultiKey(T1 value1, T2 value2) {
                    this.value1 = value1; 
                    this.value2 = value2; 
                }
 
                internal class Comparer : IEqualityComparer>, IEqualityComparer {
                    IEqualityComparer comparer1;
                    IEqualityComparer comparer2;
 
                    internal Comparer(IEqualityComparer comparer1, IEqualityComparer comparer2) {
                        this.comparer1 = comparer1; 
                        this.comparer2 = comparer2; 
                    }
 
                    public bool Equals(MultiKey x, MultiKey y) {
                        return this.comparer1.Equals(x.value1, y.value1) &&
                               this.comparer2.Equals(x.value2, y.value2);
                    } 

                    public int GetHashCode(MultiKey x) { 
                        return this.comparer1.GetHashCode(x.value1) ^ this.comparer2.GetHashCode(x.value2); 
                    }
 
                    bool IEqualityComparer.Equals(object x, object y) {
                        return this.Equals((MultiKey)x, (MultiKey)y);
                    }
 
                    int IEqualityComparer.GetHashCode(object x) {
                        return this.GetHashCode((MultiKey)x); 
                    } 
                }
            } 

            internal abstract class IdentityCache {
                internal abstract object Find(object[] keyValues);
                internal abstract object FindLike(object instance); 
                internal abstract object InsertLookup(object instance);
                internal abstract bool RemoveLike(object instance); 
            } 

            internal class IdentityCache : IdentityCache { 
                int[] buckets;
                Slot[] slots;
                int count;
                int freeList; 
                KeyManager keyManager;
                IEqualityComparer comparer; 
 
                public IdentityCache(KeyManager keyManager) {
                    this.keyManager = keyManager; 
                    this.comparer = keyManager.Comparer;
                    buckets = new int[7];
                    slots = new Slot[7];
                    freeList = -1; 
                }
 
                internal override object InsertLookup(object instance) { 
                    T value = (T)instance;
                    K key = this.keyManager.CreateKeyFromInstance(value); 
                    Find(key, ref value, true);
                    return value;
                }
 
                internal override bool RemoveLike(object instance) {
                    T value = (T)instance; 
                    K key = this.keyManager.CreateKeyFromInstance(value); 

                    int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; 
                    int bucket = hashCode % buckets.Length;
                    int last = -1;
                    for (int i = buckets[bucket] - 1; i >= 0; last = i, i = slots[i].next) {
                        if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].key, key)) { 
                            if (last < 0) {
                                buckets[bucket] = slots[i].next + 1; 
                            } 
                            else {
                                slots[last].next = slots[i].next; 
                            }
                            slots[i].hashCode = -1;
                            slots[i].value = default(T);
                            slots[i].next = freeList; 
                            freeList = i;
                            return true; 
                        } 
                    }
                    return false; 
                }

                internal override object Find(object[] keyValues) {
                    K key; 
                    if (this.keyManager.TryCreateKeyFromValues(keyValues, out key)) {
                        T value = default(T); 
                        if (Find(key, ref value, false)) 
                            return value;
                    } 
                    return null;
                }

                internal override object FindLike(object instance) { 
                    T value = (T)instance;
                    K key = this.keyManager.CreateKeyFromInstance(value); 
                    if (Find(key, ref value, false)) 
                        return value;
                    return null; 
                }

                bool Find(K key, ref T value, bool add) {
                    int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; 
                    for (int i = buckets[hashCode % buckets.Length] - 1; i >= 0; i = slots[i].next) {
                        if (slots[i].hashCode == hashCode && comparer.Equals(slots[i].key, key)) { 
                            value = slots[i].value; 
                            return true;
                        } 
                    }
                    if (add) {
                        int index;
                        if (freeList >= 0) { 
                            index = freeList;
                            freeList = slots[index].next; 
                        } 
                        else {
                            if (count == slots.Length) Resize(); 
                            index = count;
                            count++;
                        }
                        int bucket = hashCode % buckets.Length; 
                        slots[index].hashCode = hashCode;
                        slots[index].key = key; 
                        slots[index].value = value; 
                        slots[index].next = buckets[bucket] - 1;
                        buckets[bucket] = index + 1; 
                    }
                    return false;
                }
 
                void Resize() {
                    int newSize = checked(count * 2 + 1); 
                    int[] newBuckets = new int[newSize]; 
                    Slot[] newSlots = new Slot[newSize];
                    Array.Copy(slots, 0, newSlots, 0, count); 
                    for (int i = 0; i < count; i++) {
                        int bucket = newSlots[i].hashCode % newSize;
                        newSlots[i].next = newBuckets[bucket] - 1;
                        newBuckets[bucket] = i + 1; 
                    }
                    buckets = newBuckets; 
                    slots = newSlots; 
                }
 
                internal struct Slot {
                    internal int hashCode;
                    internal K key;
                    internal T value; 
                    internal int next;
                } 
            } 
            #endregion
        } 

        /// 
        /// This is the noop implementation used when object tracking is disabled.
        ///  
        class ReadOnlyIdentityManager : IdentityManager {
            internal ReadOnlyIdentityManager() { } 
            internal override object InsertLookup(MetaType type, object instance) { return instance; } 
            internal override bool RemoveLike(MetaType type, object instance) { return false; }
            internal override object Find(MetaType type, object[] keyValues) { return null; } 
            internal override object FindLike(MetaType type, object instance) { return null; }
        }
    }
} 

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