Pārlūkot izejas kodu

2005-10-25 Carlo Kok <[email protected]>

	* Collection.cs :
	  Added virtual ClearItems, InsertItem, RemoveItem, SetITem.
	* KeyedCollection.cs : Implemented.

2005-10-25  Atsushi Enomoto  <[email protected]>

	* corlib_test.dll.sources : added System.Collections.ObjectModel/KeyedCollectionTest.cs.

	* KeyedCollectionTest.cs : new file by Carlo Kok ([email protected]).


svn path=/trunk/mcs/; revision=52203
Atsushi Eno 20 gadi atpakaļ
vecāks
revīzija
b5b6edd5d5

+ 4 - 0
mcs/class/corlib/ChangeLog

@@ -1,3 +1,7 @@
+2005-10-25  Atsushi Enomoto  <[email protected]>
+
+	* corlib_test.dll.sources : added System.Collections.ObjectModel/KeyedCollectionTest.cs.
+
 2005-10-07  Zoltan Varga  <[email protected]>
 
 	* corlib.dll.sources: Add System.Runtime.CompilerServices/{RuntimeCompatibilityAttribute.cs, RuntimeWrappedException.cs}.

+ 6 - 0
mcs/class/corlib/System.Collections.ObjectModel/ChangeLog

@@ -1,3 +1,9 @@
+2005-10-25  Carlo Kok  <[email protected]>
+
+	* Collection.cs :
+	  Added virtual ClearItems, InsertItem, RemoveItem, SetITem.
+	* KeyedCollection.cs : Implemented.
+
 2005-06-19  David Waite  <[email protected]>
 
         * Collection.cs ReadonlyCollection.cs: Implement all methods

+ 40 - 8
mcs/class/corlib/System.Collections.ObjectModel/Collection.cs

@@ -68,10 +68,16 @@ namespace System.Collections.ObjectModel
 
 		public void Add (T item)
 		{
-			list.Add (item);			
+			int idx = list.Count;
+			InsertItem (idx, item);
 		}
 
 		public void Clear ()
+		{
+			ClearItems ();
+		}
+
+		protected virtual void ClearItems ()
 		{
 			list.Clear ();
 		}
@@ -97,16 +103,32 @@ namespace System.Collections.ObjectModel
 		}
 
 		public void Insert (int index, T item)
+		{
+			InsertItem (index, item);
+		}
+
+		protected virtual void InsertItem (int index, T item)
 		{
 			list.Insert (index, item);
 		}
 
 		public bool Remove (T item)
 		{
-			return list.Remove (item);
+			int idx = IndexOf (item);
+			if (idx == -1) 
+				return false;
+			
+			RemoveItem (idx);
+			
+			return true;
 		}
 
 		public void RemoveAt (int index)
+		{
+			RemoveItem (index);
+		}
+
+		protected virtual void RemoveItem (int index)
 		{
 			list.RemoveAt (index);
 		}
@@ -117,12 +139,18 @@ namespace System.Collections.ObjectModel
 
 		public virtual T this [int index] {
 			get { return list [index]; }
-			set { list [index] = value; }
+			set { SetItem (index, value); }
 		}
 
 		public bool IsReadOnly {
 			get { return list.IsReadOnly; }
 		}
+
+		protected virtual void SetItem (int index, T item)
+		{
+			list[index] = item;
+		}
+
 		
 #region Helper methods for non-generic interfaces
 		
@@ -173,8 +201,9 @@ namespace System.Collections.ObjectModel
 				
 		int IList.Add (object item)
 		{
-			list.Add (ConvertItem (item));
-			return list.Count - 1;
+			int idx = list.Count;
+			InsertItem (idx, ConvertItem (item));
+			return idx;
 		}
 		
 		bool IList.Contains (object item)
@@ -193,13 +222,16 @@ namespace System.Collections.ObjectModel
 		
 		void IList.Insert (int index, object item)
 		{
-			list.Insert (index, ConvertItem (item));
+			InsertItem (index, ConvertItem (item));
 		}
 		
 		void IList.Remove (object item)
 		{
 			CheckWritable (list);
-			list.Remove (ConvertItem (item));
+
+			int idx = IndexOf (ConvertItem (item));
+
+			RemoveItem (idx);
 		}
 		
 		bool ICollection.IsSynchronized {
@@ -219,7 +251,7 @@ namespace System.Collections.ObjectModel
 		
 		object IList.this [int index] {
 			get { return list [index]; }
-			set { list [index] = ConvertItem (value); }
+			set { SetItem (index, ConvertItem (value)); }
 		}
 #endregion
 	}

+ 124 - 15
mcs/class/corlib/System.Collections.ObjectModel/KeyedCollection.cs

@@ -42,58 +42,167 @@ namespace System.Collections.ObjectModel
 	[Serializable]
 	public abstract class KeyedCollection<TKey, TItem> : Collection<TItem>
 	{
+		private Dictionary<TKey, TItem> dictionary;
+		private IEqualityComparer<TKey> comparer;
+		private int dictionaryCreationThreshold;
+
+		protected KeyedCollection ()
+			: this (null, 0)
+		{ 
+		}
+
+		protected KeyedCollection (IEqualityComparer<TKey> comparer)
+			: this(comparer, 0)
+		{
+		}
+
+		protected KeyedCollection (IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold)
+		{
+			if (comparer != null)
+				this.comparer = comparer;
+			else
+				this.comparer = EqualityComparer<TKey>.Default;
+
+			this.dictionaryCreationThreshold = dictionaryCreationThreshold;
+
+			if (dictionaryCreationThreshold == 0)
+				dictionary = new Dictionary<TKey, TItem> (this.comparer);
+		}
+
 		public bool Contains (TKey key)
 		{
-			throw new NotImplementedException ();
+			if (dictionary != null)
+				return dictionary.ContainsKey (key);
+			return IndexOfKey (key) >= 0;
+		}
+
+		private int IndexOfKey (TKey key)
+		{
+			for (int i = Count - 1; i >= 0; i--)
+			{
+				TKey lkey = GetKeyForItem (this [i]);
+				if (comparer.Equals (key, lkey))
+					return i;
+			}
+			return -1;
 		}
 
 		public bool Remove (TKey key)
 		{
-			throw new NotImplementedException ();
+			TItem item;
+			if (dictionary != null)
+			{
+				if (dictionary.TryGetValue (key, out item))
+					return base.Remove(item);
+				else
+					return false;
+			}
+
+			int idx = IndexOfKey (key);
+
+			if (idx == -1)
+				return false;
+			
+			RemoveAt(idx);
+			return true;
 		}
 
 		public IEqualityComparer<TKey> Comparer {
 			get {
-				throw new NotImplementedException ();
+				return comparer;
 			}
 		}
 
-		public TItem this[TKey key] {
+		public TItem this [TKey key] {
 			get {
-				throw new NotImplementedException ();
+				if (dictionary != null)
+					return dictionary [key];
+
+				int idx = IndexOfKey (key);
+				if (idx >= 0)
+					return base [idx];
+				else
+					throw new KeyNotFoundException();
 			}
 		}
 
 		protected void ChangeItemKey (TItem item, TKey newKey)
 		{
-			throw new NotImplementedException ();
+			if (!Contains(item)) throw new ArgumentException();
+
+			TKey oldKey = GetKeyForItem (item);
+			if (comparer.Equals (oldKey, newKey)) return;
+
+			if (Contains (newKey)) throw new ArgumentException();
+			if (dictionary != null)
+			{
+
+				if (!dictionary.Remove (oldKey))
+					throw new ArgumentException();
+
+				dictionary.Add (newKey, item);
+			}
 		}
 
-		protected void ClearItems ()
+		protected override void ClearItems ()
 		{
-			throw new NotImplementedException ();
+			if (dictionary != null)
+			{
+				dictionary.Clear();
+			}
+
+			base.ClearItems ();
 		}
 
 		protected abstract TKey GetKeyForItem (TItem item);
 
-		protected virtual void InsertItem (int index, TItem item)
+		protected override void InsertItem (int index, TItem item)
 		{
-			throw new NotImplementedException ();
+			if (dictionary != null)
+			{
+				dictionary.Add (GetKeyForItem (item), item);
+			}
+			else
+			{
+				if (dictionaryCreationThreshold != -1 && Count + 1 > dictionaryCreationThreshold)
+				{
+					dictionary = new Dictionary<TKey, TItem> (comparer);
+
+					for (int i = Count - 1; i >= 0; i--)
+					{
+						TItem dictitem = this[i];
+						dictionary.Add(GetKeyForItem(dictitem), dictitem);
+					}
+
+					dictionary.Add (GetKeyForItem (item), item);
+				}
+			}
+			base.InsertItem (index, item);
 		}
 
-		protected virtual void RemoveItem (int index)
+		protected override void RemoveItem (int index)
 		{
-			throw new NotImplementedException ();
+			if (dictionary != null)
+			{
+				TKey key = GetKeyForItem (this [index]);
+				dictionary.Remove (key);
+			}
+			base.RemoveItem (index);
 		}
 
-		protected virtual void SetItem (int index, TItem item)
+		protected override void SetItem (int index, TItem item)
 		{
-			throw new NotImplementedException ();
+			if (dictionary != null)
+			{
+				dictionary.Remove (GetKeyForItem (this [index]));
+				dictionary.Add (GetKeyForItem (item), item);
+			}
+			base.SetItem (index, item);
 		}
 
 		protected IDictionary<TKey, TItem> Dictionary {
 			get {
-				throw new NotImplementedException ();
+				return dictionary;
 			}
 		}
 	}

+ 4 - 0
mcs/class/corlib/Test/System.Collections.ObjectModel/ChangeLog

@@ -1,3 +1,7 @@
+2005-10-25  Atsushi Enomoto  <[email protected]>
+
+	* KeyedCollectionTest.cs : new file by Carlo Kok ([email protected]).
+
 2005-06-21  Raja R Harinath  <[email protected]>
 
 	* CollectionTest.cs (IEnumerable.GetEnumerator): Don't prefix with

+ 1 - 0
mcs/class/corlib/corlib_test.dll.sources

@@ -32,6 +32,7 @@ System.Collections/StackTest.cs
 System.Collections.Generic/DictionaryTest.cs
 System.Collections.Generic/ListTest.cs
 System.Collections.ObjectModel/CollectionTest.cs
+System.Collections.ObjectModel/KeyedCollectionTest.cs
 System/ConsoleTest.cs
 System/ConvertTest.cs
 System/DateTimeTest.cs