2008-05-23 Miguel de Icaza <miguel@novell.com>
authorMiguel de Icaza <miguel@gnome.org>
Fri, 23 May 2008 16:27:58 +0000 (16:27 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Fri, 23 May 2008 16:27:58 +0000 (16:27 -0000)
* Hashtable.cs: Implement a faster clone that does not use an
enumerator to iterate over the values, this doubles the speed of
Clone.

The use of an internal constructor that builds from a Hashtable is
done to avoid populating a Hashtable and then updating every field
and structure with new data.

svn path=/trunk/mcs/; revision=103926

mcs/class/corlib/System.Collections/ChangeLog
mcs/class/corlib/System.Collections/Hashtable.cs
mcs/class/corlib/Test/System.Collections/HashtableTest.cs

index 45deb94bdb4a24ca685ba79c3cc42fb0a5df5b6c..cf9097739f6513f43a121e5fd8f870782ac99b1a 100644 (file)
@@ -1,3 +1,13 @@
+2008-05-23  Miguel de Icaza  <miguel@novell.com>
+
+       * Hashtable.cs: Implement a faster clone that does not use an
+       enumerator to iterate over the values, this doubles the speed of
+       Clone.
+
+       The use of an internal constructor that builds from a Hashtable is
+       done to avoid populating a Hashtable and then updating every field
+       and structure with new data. 
+
 2008-05-08  Robert Jordan  <robertj@gmx.net>
 
        * DictionaryEntry.cs: Rename fields for serialization
index b3a894bb28ea7d33f087a8c141a3fdb1664f9e65..cb1e2842e42604093c80dc79ba38332c79912f4b 100644 (file)
@@ -175,6 +175,26 @@ namespace System.Collections {
                {
                }
 
+               //
+               // Used as a faster Clone
+               //
+               internal Hashtable (Hashtable source)
+               {
+                       inUse = source.inUse;
+                       loadFactor = source.loadFactor;
+
+                       table = (Slot []) source.table.Clone ();
+                       hashes = (int []) source.hashes.Clone ();
+                       threshold = source.threshold;
+                       hcpRef = source.hcpRef;
+                       comparerRef = source.comparerRef;
+                       serializationInfo = source.serializationInfo;
+
+#if NET_2_0
+                       equalityComparer = source.equalityComparer;
+#endif
+               }
+                       
 #if NET_2_0
                [Obsolete ("Please use Hashtable(int, IEqualityComparer) instead")]
 #endif
@@ -519,25 +539,7 @@ namespace System.Collections {
 
                public virtual object Clone ()
                {
-#if NET_2_0
-                       Hashtable ht = new Hashtable (Count, equalityComparer);
-                       ht.hcp = this.hcp;
-                       ht.comparer = this.comparer;
-#else
-                       Hashtable ht = new Hashtable (Count, hcp, comparer);
-#endif
-                       ht.inUse = 0;
-                       ht.loadFactor = this.loadFactor;
-
-                       // FIXME: maybe it's faster to simply
-                       //        copy the back-end array?
-
-                       IDictionaryEnumerator it = GetEnumerator ();
-                       while (it.MoveNext ()) {
-                               ht [it.Key] = it.Value;
-                       }
-
-                       return ht;
+                       return new Hashtable (this);
                }
 
                public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
index dc4e817d2a3391b2926c5ff6221744b03f9c5b06..ca0766a8cdedbfd724ecb1c0e9bed48cdb77b6d3 100644 (file)
@@ -292,6 +292,23 @@ public class HashtableTest : Assertion {
                             0, h.Count);\r
        }\r
 \r
+#if NET_2_0\r
+       public class MyEqualityComparer : IEqualityComparer {\r
+               public bool Equals (object x, object y) { return x == y; }\r
+               public int GetHashCode (object obj) { return 1; }\r
+       }\r
+\r
+       public class MyHashtable : Hashtable {\r
+               public MyHashtable (IEqualityComparer c): base (c){}\r
+\r
+               public IEqualityComparer GetComparer ()\r
+               {\r
+                       return EqualityComparer;\r
+               }\r
+       }\r
+       \r
+#endif\r
+       \r
         [Test]\r
        public void TestClone() {\r
                {\r
@@ -329,6 +346,15 @@ public class HashtableTest : Assertion {
 \r
                        ((char[])h1[c1[0]])[0] = 'z';\r
                        AssertEquals("shallow copy", h1[c1[0]], h2[c1[0]]);\r
+\r
+#if NET_2_0\r
+                       // NET 2.0 stuff\r
+                       MyEqualityComparer a = new MyEqualityComparer ();\r
+                       MyHashtable mh1 = new MyHashtable (a);\r
+                       MyHashtable mh2 = (MyHashtable) h1.Clone ();\r
+                       \r
+                       AssertEquals ("EqualityComparer", mh1.GetComparer (), mh2.GetComparer ());\r
+#endif\r
                }\r
        }\r
 \r