From: Michael D. <mik...@us...> - 2004-07-22 13:31:46
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Util In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11682/NHibernate/Util Modified Files: IdentityMap.cs Log Message: Added HashCodeProvider.dll reference to project and using it in IdentityMap. Index: IdentityMap.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Util/IdentityMap.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** IdentityMap.cs 28 Jun 2004 03:41:34 -0000 1.9 --- IdentityMap.cs 22 Jul 2004 13:31:37 -0000 1.10 *************** *** 13,20 **** /// </summary> /// <remarks> ! /// Do NOT use a struct/System.Value type as the key for this Hashtable - only classes. See /// the google thread /// http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=bds2rm%24ruc%241%40charly.heeg.de&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26q%3DSystem.Runtime.CompilerServices.RuntimeHelpers.GetHashCode%26sa%3DN%26tab%3Dwg ! /// about why using Structs is a bad thing. /// <p> /// If I understand it correctly, the first call to get an object defined by a DateTime("2003-01-01") --- 13,20 ---- /// </summary> /// <remarks> ! /// Do NOT use a System.Value type as the key for this Hashtable - only classes. See /// the google thread /// http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=bds2rm%24ruc%241%40charly.heeg.de&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26q%3DSystem.Runtime.CompilerServices.RuntimeHelpers.GetHashCode%26sa%3DN%26tab%3Dwg ! /// about why using System.Value is a bad thing. /// <p> /// If I understand it correctly, the first call to get an object defined by a DateTime("2003-01-01") *************** *** 28,31 **** --- 28,32 ---- public sealed class IdentityMap : IDictionary { + private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(IdentityMap)); // key = IdentityKey of the passed in Key *************** *** 33,39 **** IDictionary map; ! private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(IdentityMap)); ! ! /// <summary> /// Create a new instance of the IdentityMap that has no --- 34,38 ---- IDictionary map; ! /// <summary> /// Create a new instance of the IdentityMap that has no *************** *** 43,47 **** public static IDictionary Instantiate() { ! return new IdentityMap(new Hashtable()); } --- 42,48 ---- public static IDictionary Instantiate() { ! IHashCodeProvider ihcp = new HashCodeProvider.IdentityHashCodeProvider(); ! IComparer comp = new IdentityMap.IdentityComparer(); ! return new IdentityMap(new Hashtable(ihcp, comp)); } *************** *** 54,58 **** public static IDictionary InstantiateSequenced() { ! return new IdentityMap(new SequencedHashMap()); } --- 55,61 ---- public static IDictionary InstantiateSequenced() { ! IHashCodeProvider ihcp = new HashCodeProvider.IdentityHashCodeProvider(); ! IComparer comp = new IdentityMap.IdentityComparer(); ! return new IdentityMap(new SequencedHashMap(ihcp, comp)); } *************** *** 109,114 **** public void Add(object key, object val) { ! IdentityKey identityKey = new IdentityMap.IdentityKey(key); ! map.Add(identityKey, val); } --- 112,116 ---- public void Add(object key, object val) { ! map.Add(VerifyValidKey(key), val); } *************** *** 126,131 **** public bool Contains(object key) { ! IdentityKey identityKey = new IdentityMap.IdentityKey(key); ! return map.Contains(identityKey); } --- 128,133 ---- public bool Contains(object key) { ! if(key==null) return false; ! return map.Contains(VerifyValidKey(key)); } *************** *** 170,180 **** get { ! ArrayList keyObjects = new ArrayList(map.Keys.Count); ! foreach(IdentityKey key in map.Keys) ! { ! keyObjects.Add(key.Key); ! } ! ! return keyObjects; } } --- 172,176 ---- get { ! return map.Keys; } } *************** *** 185,190 **** public void Remove(object key) { ! IdentityKey identityKey = new IdentityMap.IdentityKey(key); ! map.Remove(identityKey); } --- 181,186 ---- public void Remove(object key) { ! if(key==null) return; ! map.Remove(VerifyValidKey(key)); } *************** *** 196,206 **** get { ! IdentityKey identityKey = new IdentityMap.IdentityKey(key); ! return map[identityKey]; } set { ! IdentityKey identityKey = new IdentityMap.IdentityKey(key); ! map[identityKey] = value; } } --- 192,201 ---- get { ! if(key==null) return null; ! return map[VerifyValidKey(key)]; } set { ! map[VerifyValidKey(key)] = value; } } *************** *** 238,244 **** foreach(DictionaryEntry de in map) { ! // add the underlying Key behind the IdentityKey.Key and the Value (the value ! // is not wrapping anything) to the List ! DictionaryEntry newEntry = new DictionaryEntry(((IdentityKey)de.Key).Key, de.Value); list.Add(newEntry); } --- 233,237 ---- foreach(DictionaryEntry de in map) { ! DictionaryEntry newEntry = new DictionaryEntry(de.Key, de.Value); list.Add(newEntry); } *************** *** 248,289 **** } ! ! [Serializable] ! public sealed class IdentityKey { ! private object key; ! ! internal IdentityKey(Object key) { ! if(key is System.ValueType) { ! throw new ArgumentException("A ValueType can not be used with IdentityKey. " + ! "The thread at google has a good description about what happens with boxing " + ! "and unboxing ValueTypes and why they can not be used as an IdentityKey: " + ! "http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=bds2rm%24ruc%241%40charly.heeg.de&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26q%3DSystem.Runtime.CompilerServices.RuntimeHelpers.GetHashCode%26sa%3DN%26tab%3Dwg" ! ,"key"); - } - this.key=key; } ! public override bool Equals(Object other) ! { ! return key == ((IdentityKey) other).Key; ! } ! public override int GetHashCode() ! { ! return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(key); ! } ! public object Key { ! get {return key;} } } - - - } } --- 241,316 ---- } ! /// <summary> ! /// Verifies that we are not using a System.ValueType as the Key in the Dictionary ! /// </summary> ! /// <param name="obj">The object that will be the key.</param> ! /// <returns>An object that is safe to be a key.</returns> ! /// <exception cref="ArgumentException">Thrown when the obj is a System.ValueType</exception> ! private object VerifyValidKey(object obj) { ! if(obj is System.ValueType) { ! throw new ArgumentException("A ValueType can not be used with IdentityKey. " + ! "The thread at google has a good description about what happens with boxing " + ! "and unboxing ValueTypes and why they can not be used as an IdentityKey: " + ! "http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=bds2rm%24ruc%241%40charly.heeg.de&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26q%3DSystem.Runtime.CompilerServices.RuntimeHelpers.GetHashCode%26sa%3DN%26tab%3Dwg" ! ,"key"); } ! return obj; ! } ! /// <summary> ! /// Compares two objects for Equality using "==" instead of Object.Equals ! /// </summary> ! /// <remarks> ! /// Only for use in IdentityMap. ! /// </remarks> ! private class IdentityComparer : IComparer ! { ! #region IComparer Members ! /// <summary> ! /// Performs a null safe comparison using "==" instead of Object.Equals() ! /// </summary> ! /// <param name="x">First object to compare.</param> ! /// <param name="y">Second object to compare.</param> ! /// <remarks> ! /// This is Lazy collection safe since it uses <c>==</c>, unlike <c>Object.Equals()</c> ! /// which currently causes NHibernate to load up the collection. This behaivior of ! /// Collections is likely to change because Java's collections override Equals() and ! /// .net's collections don't. So in .net there is no need to override Equals() and ! /// GetHashCode() on the NHibernate Collection implementations. ! /// </remarks> ! /// <returns> ! /// Unlike the standard IComparer interface this will not return a <c>1</c> or <c>-1</c> ! /// to indicate which is Greater Than or Less Than. It always returns <c>-1</c> to ! /// indicate the two are not Equal. ! /// </returns> ! public int Compare(object x, object y) { ! if(x==null && y==null) ! { ! return 0; ! } ! ! if(x==null || y==null) ! { ! return -1; ! } ! ! if(x==y) ! { ! return 0; ! } ! else ! { ! return -1; ! } } + #endregion } } } |