diff options
author | Matthias Zenger <mzenger@gmail.com> | 2004-05-03 20:17:00 +0000 |
---|---|---|
committer | Matthias Zenger <mzenger@gmail.com> | 2004-05-03 20:17:00 +0000 |
commit | 0c42b4a80bdd112f14925ef5d2e202575536e307 (patch) | |
tree | d3c40d6b0a35605c7fb38a706efc9570284478bb | |
parent | c7ce40c3c7041bdc018e4054e634f061537b15e2 (diff) | |
download | scala-0c42b4a80bdd112f14925ef5d2e202575536e307.tar.gz scala-0c42b4a80bdd112f14925ef5d2e202575536e307.tar.bz2 scala-0c42b4a80bdd112f14925ef5d2e202575536e307.zip |
Refactored library.
-rw-r--r-- | sources/scala/collection/Map.scala | 2 | ||||
-rw-r--r-- | sources/scala/collection/immutable/ListSet.scala | 91 | ||||
-rw-r--r-- | sources/scala/collection/immutable/Map.scala | 25 | ||||
-rw-r--r-- | sources/scala/collection/immutable/Queue.scala | 20 | ||||
-rw-r--r-- | sources/scala/collection/immutable/Set.scala | 16 | ||||
-rw-r--r-- | sources/scala/collection/immutable/Tree.scala | 256 | ||||
-rw-r--r-- | sources/scala/collection/immutable/TreeMap.scala | 187 | ||||
-rw-r--r-- | sources/scala/collection/immutable/TreeSet.scala | 108 | ||||
-rw-r--r-- | sources/scala/collection/mutable/ArrayBuffer.scala | 56 | ||||
-rw-r--r-- | sources/scala/collection/mutable/Buffer.scala | 8 | ||||
-rw-r--r-- | sources/scala/collection/mutable/BufferProxy.scala | 6 | ||||
-rw-r--r-- | sources/scala/collection/mutable/ListBuffer.scala | 10 | ||||
-rw-r--r-- | sources/scala/collection/mutable/MutableList.scala | 2 | ||||
-rw-r--r-- | sources/scala/collection/mutable/Queue.scala | 8 | ||||
-rw-r--r-- | sources/scala/collection/mutable/Stack.scala | 14 | ||||
-rw-r--r-- | sources/scala/collection/mutable/SynchronizedBuffer.scala | 8 |
16 files changed, 412 insertions, 405 deletions
diff --git a/sources/scala/collection/Map.scala b/sources/scala/collection/Map.scala index 1d226b4560..b0accaeb50 100644 --- a/sources/scala/collection/Map.scala +++ b/sources/scala/collection/Map.scala @@ -22,7 +22,7 @@ package scala.collection; * immutable data structures. * * @author Matthias Zenger - * @version 1.0, 08/07/2003 + * @version 1.1, 02/05/2004 */ trait Map[A, +B] with PartialFunction[A, B] with Iterable[Pair[A, B]] { diff --git a/sources/scala/collection/immutable/ListSet.scala b/sources/scala/collection/immutable/ListSet.scala index 67bf86c1c2..fa87d40cd9 100644 --- a/sources/scala/collection/immutable/ListSet.scala +++ b/sources/scala/collection/immutable/ListSet.scala @@ -14,9 +14,9 @@ object ListSet { /** constructs an empty ListSet */ def Empty[A] = new ListSet[A]; - } + /** This class implements immutable sets using a list-based data * structure. Instances of <code>ListSet</code> represent * empty sets; they can be either created by calling the constructor @@ -28,16 +28,16 @@ object ListSet { class ListSet[A] with Set[A] { /** Returns the number of elements in this set. - * - * @return number of set elements. - */ + * + * @return number of set elements. + */ def size: Int = 0; /** Checks if this set contains element <code>elem</code>. - * - * @param elem the element to check for membership. - * @return true, iff <code>elem</code> is contained in this set. - */ + * + * @param elem the element to check for membership. + * @return true, iff <code>elem</code> is contained in this set. + */ def contains(elem: A): Boolean = false; /** This method creates a new set with an additional element. @@ -63,8 +63,8 @@ class ListSet[A] with Set[A] { override def toList: List[A] = Nil; /** Compares two sets for equality. - * Two set are equal iff they contain the same elements. - */ + * Two set are equal iff they contain the same elements. + */ override def equals(obj: Any): Boolean = if (obj.isInstanceOf[scala.collection.Set[A]]) { val that = obj.asInstanceOf[scala.collection.Set[A]]; @@ -75,39 +75,42 @@ class ListSet[A] with Set[A] { override def hashCode(): Int = 0; protected class Node(elem: A) extends ListSet[A] { - /** Returns the number of elements in this set. - * - * @return number of set elements. - */ - override def size = ListSet.this.size + 1; - /** Checks if this set is empty. - * - * @return true, iff there is no element in the set. - */ - override def isEmpty: Boolean = false; - - /** Checks if this set contains element <code>elem</code>. - * - * @param elem the element to check for membership. - * @return true, iff <code>elem</code> is contained in this set. - */ - override def contains(e: A) = (e == elem) || ListSet.this.contains(e); - - /** This method creates a new set with an additional element. - */ - override def +(e: A): ListSet[A] = if (contains(e)) this else new Node(e); - /** <code>-</code> can be used to remove a single element from - * a set. - */ - override def -(e: A): ListSet[A] = if (e == elem) ListSet.this else { - val tail = ListSet.this - e; new tail.Node(elem) - } - - /** Transform this set into a list of all elements. - * - * @return a list which enumerates all elements of this set. - */ - override def toList: List[A] = elem :: ListSet.this.toList; - override def hashCode(): Int = elem.hashCode() + ListSet.this.hashCode(); + /** Returns the number of elements in this set. + * + * @return number of set elements. + */ + override def size = ListSet.this.size + 1; + + /** Checks if this set is empty. + * + * @return true, iff there is no element in the set. + */ + override def isEmpty: Boolean = false; + + /** Checks if this set contains element <code>elem</code>. + * + * @param elem the element to check for membership. + * @return true, iff <code>elem</code> is contained in this set. + */ + override def contains(e: A) = (e == elem) || ListSet.this.contains(e); + + /** This method creates a new set with an additional element. + */ + override def +(e: A): ListSet[A] = if (contains(e)) this else new Node(e); + + /** <code>-</code> can be used to remove a single element from + * a set. + */ + override def -(e: A): ListSet[A] = if (e == elem) ListSet.this else { + val tail = ListSet.this - e; new tail.Node(elem) + } + + /** Transform this set into a list of all elements. + * + * @return a list which enumerates all elements of this set. + */ + override def toList: List[A] = elem :: ListSet.this.toList; + + override def hashCode(): Int = elem.hashCode() + ListSet.this.hashCode(); } } diff --git a/sources/scala/collection/immutable/Map.scala b/sources/scala/collection/immutable/Map.scala index 405e054763..c6639fb49a 100644 --- a/sources/scala/collection/immutable/Map.scala +++ b/sources/scala/collection/immutable/Map.scala @@ -9,6 +9,7 @@ package scala.collection.immutable; + /** This trait extends the Map interface of collections that unambiguously map * keys to values (i.e. a key is mapped to at least one value). * This trait defines the interface for functional map implementations @@ -17,8 +18,9 @@ package scala.collection.immutable; * abstract methods in scala.collection.Map as well as for * <code>factory</code>, <code>update</code>, and -. * - * @author Matthias Zenger, Erik Stenman - * @version 1.0, 03/12/2003 + * @author Matthias Zenger + * @author Erik Stenman + * @version 1.1, 22/03/2004 */ trait Map[A, B] with scala.collection.Map[A, B] { @@ -126,25 +128,6 @@ trait Map[A, B] with scala.collection.Map[A, B] { res; } + "}"; - /** Compares two maps for equality. - * Two maps are equal iff they contain exactly the - * same key-value pairs. - */ - override def equals(obj: Any): Boolean = - if (obj.isInstanceOf[scala.collection.Map[A, B]]) { - val that = obj.asInstanceOf[scala.collection.Map[A, B]]; - if (size != that.size) - false - else - elements forall { - case Pair(key, value) => that.get(key) match { - case None => false; - case Some(v) => v == value; - } - } - } else - false; - override def hashCode() = { elements.foldLeft(0)((hash:Int,pair:Object) => hash + pair.hashCode()); } diff --git a/sources/scala/collection/immutable/Queue.scala b/sources/scala/collection/immutable/Queue.scala index 6368f71928..1859fec631 100644 --- a/sources/scala/collection/immutable/Queue.scala +++ b/sources/scala/collection/immutable/Queue.scala @@ -27,13 +27,13 @@ class Queue[+A](elem: A*) extends Seq[A] { protected def itToList[B >: A](elems:Iterator[B]): List[B] = if (elems.hasNext) { val hd = elems.next; hd::itToList(elems)} - else Nil; + else Nil; protected def mkQueue[A](i:List[A], o:List[A]):Queue[A] = { - new Queue[A](){ - override protected val in = i; - override protected val out = o - }; + new Queue[A](){ + override protected val in = i; + override protected val out = o + }; } /** Returns the <code>n</code>-th element of this queue. @@ -100,8 +100,8 @@ class Queue[+A](elem: A*) extends Seq[A] { newOut = in.reverse; newIn = Nil; } else { - newOut = out; - newIn = in; + newOut = out; + newIn = in; } if (newOut.isEmpty) error("queue empty"); else Pair(newOut.head, mkQueue(newIn, newOut.tail)); @@ -168,9 +168,9 @@ class Queue[+A](elem: A*) extends Seq[A] { } override def hashCode():Int = - if (isEmpty) 0 - else { - val q:Pair[A,Queue[A]] = dequeue; + if (isEmpty) 0 + else { + val q:Pair[A,Queue[A]] = dequeue; q._1.hashCode()+q._2.hashCode(); } } diff --git a/sources/scala/collection/immutable/Set.scala b/sources/scala/collection/immutable/Set.scala index 8ab45c8d5a..49987e80a9 100644 --- a/sources/scala/collection/immutable/Set.scala +++ b/sources/scala/collection/immutable/Set.scala @@ -16,7 +16,7 @@ package scala.collection.immutable; * <code>-</code>. * * @author Matthias Zenger - * @version 1.0, 19/07/2003 + * @version 1.1, 03/05/2004 */ trait Set[A] with scala.collection.Set[A] { @@ -27,12 +27,12 @@ trait Set[A] with scala.collection.Set[A] { /** <code>incl</code> can be used to add many elements to the set * at the same time. */ - def incl(elems: A*): Set[A] = incl(elems); + def incl(elems: A*): Set[A] = incl(elems); - /** This method will add all the elements provided by an iterator + /** This method will add all the elements provided by an iterator * of the iterable object <code>that</code> to the set. */ - def incl(that: Iterable[A]): Set[A] = { + def incl(that: Iterable[A]): Set[A] = { var res = this; that.elements.foreach(elem => res = res + elem); res; @@ -41,7 +41,7 @@ trait Set[A] with scala.collection.Set[A] { /** <code>-</code> can be used to remove a single element from * a set. */ - def -(elem: A): Set[A]; + def -(elem: A): Set[A]; /** <code>excl</code> removes many elements from the set. */ @@ -50,7 +50,7 @@ trait Set[A] with scala.collection.Set[A] { /** This method removes all the elements provided by an iterator * of the iterable object <code>that</code> from the set. */ - def excl(that: Iterable[A]): Set[A] = { + def excl(that: Iterable[A]): Set[A] = { var res = this; that.elements.foreach(elem => res = res - elem); res; @@ -61,10 +61,10 @@ trait Set[A] with scala.collection.Set[A] { */ def intersect(that: scala.collection.Set[A]): Set[A] = filter(that.contains); - /** Method <code>filter</code> removes all elements from the set for + /** Method <code>filter</code> removes all elements from the set for * which the predicate <code>p</code> yields the value <code>false</code>. */ - def filter(p: A => Boolean): Set[A] = { + def filter(p: A => Boolean): Set[A] = { var res = this; toList foreach { elem => if (!p(elem)) { res = res - elem; } diff --git a/sources/scala/collection/immutable/Tree.scala b/sources/scala/collection/immutable/Tree.scala index 5dff37a307..24c98dce98 100644 --- a/sources/scala/collection/immutable/Tree.scala +++ b/sources/scala/collection/immutable/Tree.scala @@ -5,7 +5,8 @@ ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** ** $Id$ -** =====================================================================*/ +\* */ + /* General Balanced Trees - highly efficient functional dictionaries. ** ** This is a scala version of gb_trees.erl which is @@ -37,35 +38,36 @@ package scala.collection.immutable; + /** General Balanced Trees - highly efficient functional dictionaries. -** -** An efficient implementation of Prof. Arne Andersson's General -** Balanced Trees. These have no storage overhead compared to plain -** unbalanced binary trees, and their performance is in general better -** than AVL trees. -** <p/> -** This implementation does not balance the trees after deletions. -** Since deletions -** don't increase the height of a tree, this should be OK in most -** applications. A balance method is provided for those cases -** where rebalancing is needed. -** <p/> -** The tree consists of entries conatining a key with an order. -** Concrete implementations of the tree class has to suply the -** function entryKey that given an entry in the tree return -** its key. -** <p/> -** When instanciating the tree an order for the keys has to be -** supplied. -** -** @author Erik Stenman -** @version 1.0, 10/07/2003 -*/ -abstract class Tree[KEY,Entry](order:Order[KEY]) { + * + * An efficient implementation of Prof. Arne Andersson's General + * Balanced Trees. These have no storage overhead compared to plain + * unbalanced binary trees, and their performance is in general better + * than AVL trees. + * <p/> + * This implementation does not balance the trees after deletions. + * Since deletions + * don't increase the height of a tree, this should be OK in most + * applications. A balance method is provided for those cases + * where rebalancing is needed. + * <p/> + * The tree consists of entries conatining a key with an order. + * Concrete implementations of the tree class has to suply the + * function entryKey that given an entry in the tree return + * its key. + * <p/> + * When instanciating the tree an order for the keys has to be + * supplied. + * + * @author Erik Stenman + * @version 1.0, 10/07/2003 + */ +abstract class Tree[A <% Ordered[A], B] { /* Data structure: ** - size:Int - the number of elements in the tree. ** - tree:T, which is composed of nodes of the form: - ** - GBNode(entry:Entry, smaller:T, bigger:T), and the "empty tree" node: + ** - GBNode(entry:B, smaller:T, bigger:T), and the "empty tree" node: ** - GBNil. ** ** Original balance condition h(T) <= ceil(c * log(|T|)) has been @@ -81,12 +83,12 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { * type This = C[T]; * </pre> */ - type This <: Tree[KEY,Entry]; + type This <: Tree[A,B]; /** * The type of nodes that the tree is build from. */ - protected type aNode = GBTree[KEY,Entry]; + protected type aNode = GBTree[A,B]; /** The nodes in the tree. */ @@ -116,7 +118,7 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { * This method has to be defined by concrete implementations * of the class. */ - def entryKey(entry:Entry):KEY; + def entryKey(entry:B):A; /** Is the given key mapped to a value by this map? @@ -124,19 +126,19 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { * @param key the key * @return true, iff there is a mapping for key in this map */ - def is_defined(key:KEY) = tree.is_defined(key); + def is_defined(key:A) = tree.is_defined(key); /** * A new tree with the entry added is returned, * assuming that key is <em>not</em> in the tree. */ - def add(key:KEY,entry:Entry):This = { + def add(key:A,entry:B):This = { val newSize = size+1; New(newSize, - tree.insert(key, - entry, - pow(newSize, p)).node); + tree.insert(key, + entry, + pow(newSize, p)).node); } /** @@ -144,7 +146,7 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { * if key is <em>not</em> in the tree, otherwise * the key is updated with the new entry. */ - def update_or_add(key:KEY, entry:Entry):This = { + def update_or_add(key:A, entry:B):This = { if(is_defined(key)) New(size,tree.update(key,entry)) else add(key,entry); } @@ -152,14 +154,14 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { /** Removes the key from the tree. */ - def delete_any(key:KEY) = + def delete_any(key:A) = if(is_defined(key)) delete(key) else // TODO: Avoid this creation by convincing the type system that this has type This. New(size,tree); /** Removes the key from the tree, assumimg that key is present. */ - private def delete(key:KEY) = New(size - 1, tree.delete(key)); + private def delete(key:A) = New(size - 1, tree.delete(key)); /** Check if this map maps <code>key</code> to a value and return the * value if it exists. @@ -167,7 +169,7 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { * @param key the key of the mapping of interest * @return the value of the mapping, if it exists */ - def findValue(key:KEY) = tree.get(key); + def findValue(key:A) = tree.get(key); /** * Gives you an iterator over all elements in the tree. @@ -176,19 +178,19 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { * * Note: The iterator itself has a state, i.e., it is not functional. */ - def entries:Iterator[Entry] = - new Iterator[Entry] { + def entries:Iterator[B] = + new Iterator[B] { var iter = tree.mk_iter(scala.Nil); def hasNext = !iter.isEmpty; def next = - iter.match { - case (GBNode(v,_,t)::iter_tail) => { - iter= t.mk_iter(iter_tail); + iter.match { + case (GBNode(v,_,t)::iter_tail) => { + iter= t.mk_iter(iter_tail); v; - } + } case scala.Nil => error("next on empty iterator"); - } + } } /** Create a new balanced tree from the tree. @@ -198,68 +200,68 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { def balance = New(size,tree.balance(size)); - case object GBNil extends GBTree[KEY,Entry] { + case object GBNil extends GBTree[A,B] { def count = Info(1,0); - def is_defined(key:KEY) = false; - def get(_key:KEY) = None; - def apply(key:KEY) = error("key " + key + " not found"); - def update(key:KEY, value:Entry) = error("key " + key + " not found"); - def insert(key:KEY, value:Entry, s:int):anInsertTree = + def is_defined(key:A) = false; + def get(_key:A) = None; + def apply(key:A) = error("key " + key + " not found"); + def update(key:A, value:B) = error("key " + key + " not found"); + def insert(key:A, value:B, s:int):anInsertTree = if (s == 0) INode(GBNode(value, GBNil, GBNil), 1, 1); else ITree(GBNode(value, GBNil, GBNil)); - def toList(acc:List[Entry]) = acc; - def mk_iter(iter_tail:List[GBTree[KEY,Entry]]) = iter_tail; - def merge(larger:GBTree[KEY,Entry]) = larger; - def take_smallest:Pair[Entry,GBTree[KEY,Entry]] = error("Take Smallest on empty tree"); - def delete(_key:KEY) = error("Delete on empty tree."); + def toList(acc:List[B]) = acc; + def mk_iter(iter_tail:List[GBTree[A,B]]) = iter_tail; + def merge(larger:GBTree[A,B]) = larger; + def take_smallest:Pair[B,GBTree[A,B]] = error("Take Smallest on empty tree"); + def delete(_key:A) = error("Delete on empty tree."); def balance(s:int) = this; override def hashCode() = 0; } - private case class GBNode(value:Entry,smaller:GBTree[KEY,Entry],bigger:GBTree[KEY,Entry]) extends GBTree[KEY,Entry] { + private case class GBNode(value:B,smaller:GBTree[A,B],bigger:GBTree[A,B]) extends GBTree[A,B] { def count:Info = { if (smaller == GBNil && bigger == GBNil) Info(1,1); else { - val sInfo = smaller.count; - val bInfo = bigger.count; - Info(mul2(max(sInfo.height,bInfo.height)), - sInfo.size + bInfo.size +1); + val sInfo = smaller.count; + val bInfo = bigger.count; + Info(mul2(max(sInfo.height,bInfo.height)), + sInfo.size + bInfo.size +1); } } - def is_defined(key:KEY):Boolean = { - if(order.<(key,entryKey(value))) smaller.is_defined(key) - else if(order.>(key,entryKey(value))) bigger.is_defined(key) + def is_defined(key:A):Boolean = { + if(key < entryKey(value)) smaller.is_defined(key) + else if(key > entryKey(value)) bigger.is_defined(key) else true; } - def get(key:KEY):Option[Entry] = - if (order.<(key,entryKey(value))) smaller.get(key); - else if (order.>(key,entryKey(value))) bigger.get(key); - else Some(value); - - def apply(key:KEY):Entry = - if (order.<(key,entryKey(value))) smaller.apply(key); - else if (order.>(key,entryKey(value))) bigger.apply(key); - else value; - - def update(key:KEY, newValue:Entry):aNode = - if (order.<(key,entryKey(value))) - GBNode(value, smaller.update(key,newValue), bigger); - else if (order.>(key,entryKey(value))) - GBNode(value, smaller, bigger.update(key,newValue)); + def get(key:A):Option[B] = + if (key < entryKey(value)) smaller.get(key); + else if (key > entryKey(value)) bigger.get(key); + else Some(value); + + def apply(key:A):B = + if (key < entryKey(value)) smaller.apply(key); + else if (key > entryKey(value)) bigger.apply(key); + else value; + + def update(key:A, newValue:B):aNode = + if (key < entryKey(value)) + GBNode(value, smaller.update(key,newValue), bigger); + else if (key > entryKey(value)) + GBNode(value, smaller, bigger.update(key,newValue)); else - GBNode(newValue, smaller, bigger); + GBNode(newValue, smaller, bigger); - def insert(key:KEY, newValue:Entry, s:int):anInsertTree = { - if(order.<(key,entryKey(value))) - smaller.insert(key, newValue, div2(s)).insert_left(value,bigger); - else if(order.>(key,entryKey(value))) - bigger.insert(key, newValue, div2(s)).insert_right(value,smaller); + def insert(key:A, newValue:B, s:int):anInsertTree = { + if(key < entryKey(value)) + smaller.insert(key, newValue, div2(s)).insert_left(value,bigger); + else if(key > entryKey(value)) + bigger.insert(key, newValue, div2(s)).insert_right(value,smaller); else error("Key exists" + key); } - def toList(acc:List[Entry]):List[Entry] = + def toList(acc:List[B]):List[B] = smaller.toList(value::bigger.toList(acc)); def mk_iter(iter_tail:List[aNode]):List[aNode] = @@ -267,33 +269,33 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { else smaller.mk_iter(this::iter_tail); - def delete(key:KEY):aNode = { - if (order.<(key,entryKey(value))) - GBNode(value, smaller.delete(key), bigger); + def delete(key:A):aNode = { + if (key < entryKey(value)) + GBNode(value, smaller.delete(key), bigger); else - if (order.>(key,entryKey(value))) - GBNode(value, smaller, bigger.delete(key)); - else - smaller.merge(bigger) + if (key > entryKey(value)) + GBNode(value, smaller, bigger.delete(key)); + else + smaller.merge(bigger) } def merge(larger:aNode) = { if(larger==GBNil) this; else { - val Pair(value1,larger1) = larger.take_smallest; - GBNode(value1,this,larger1); + val Pair(value1,larger1) = larger.take_smallest; + GBNode(value1,this,larger1); } } - def take_smallest:Pair[Entry,aNode] = { + def take_smallest:Pair[B,aNode] = { if (smaller == GBNil) Pair(value,bigger); else { - val Pair(value1, smaller1) = smaller.take_smallest; - Pair(value1, GBNode(value, smaller1, bigger)); + val Pair(value1, smaller1) = smaller.take_smallest; + Pair(value1, GBNode(value, smaller1, bigger)); } } - def balance(s:int):GBTree[KEY,Entry] = balance_list(toList(scala.Nil), s); + def balance(s:int):GBTree[A,B] = balance_list(toList(scala.Nil), s); override def hashCode() = value.hashCode() + smaller.hashCode() + bigger.hashCode(); @@ -301,9 +303,9 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { } - protected def balance_list(list:List[Entry], s:int) = balance_list_1(list, s)._1; + protected def balance_list(list:List[B], s:int) = balance_list_1(list, s)._1; - protected def balance_list_1(list:List[Entry], s:int):Pair[aNode,List[Entry]] = { + protected def balance_list_1(list:List[B], s:int):Pair[aNode,List[B]] = { if(s > 1) { val sm = s - 1; val s2 = div2(sm); @@ -314,24 +316,24 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { Pair(t, l2); } else if(s == 1) { - val v = list.head; - Pair(GBNode(v,GBNil,GBNil), list.tail); + val v = list.head; + Pair(GBNode(v,GBNil,GBNil), list.tail); } else - Pair(GBNil,list); + Pair(GBNil,list); } // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ - protected case class ITree(t:aNode) extends InsertTree[KEY,Entry] { - def insert_left(value:Entry,bigger:aNode) = ITree(GBNode(value,t,bigger)); - def insert_right(value:Entry,smaller:aNode) = ITree(GBNode(value,smaller,t)); + protected case class ITree(t:aNode) extends InsertTree[A,B] { + def insert_left(value:B,bigger:aNode) = ITree(GBNode(value,t,bigger)); + def insert_right(value:B,smaller:aNode) = ITree(GBNode(value,smaller,t)); def node = t; } - protected case class INode(t1:aNode,height:int,siz:int) extends InsertTree[KEY,Entry]{ - def insert_left(value:Entry,bigger:aNode) = balance_p(GBNode(value, t1, bigger), bigger); - def insert_right(value:Entry,smaller:aNode) = balance_p(GBNode(value, smaller, t1),smaller); + protected case class INode(t1:aNode,height:int,siz:int) extends InsertTree[A,B]{ + def insert_left(value:B,bigger:aNode) = balance_p(GBNode(value, t1, bigger), bigger); + def insert_right(value:B,smaller:aNode) = balance_p(GBNode(value, smaller, t1),smaller); protected def balance_p(t:aNode,subtree:aNode):anInsertTree = { val info = subtree.count; val totalHeight = mul2(max(height, info.height)); @@ -360,12 +362,12 @@ abstract class Tree[KEY,Entry](order:Order[KEY]) { } // End of class Tree... -private abstract class InsertTree[KEY,Entry]() { - type aNode = GBTree[KEY,Entry]; - type anInsertTree = InsertTree[KEY,Entry]; +private abstract class InsertTree[A,B]() { + type aNode = GBTree[A,B]; + type anInsertTree = InsertTree[A,B]; - def insert_left(v:Entry,t:aNode):anInsertTree; - def insert_right(v:Entry,t:aNode):anInsertTree; + def insert_left(v:B,t:aNode):anInsertTree; + def insert_right(v:B,t:aNode):anInsertTree; def node:aNode; } @@ -373,25 +375,25 @@ private abstract class InsertTree[KEY,Entry]() { * GBTree is an internal class used by Tree. */ -private abstract class GBTree[KEY,Entry] { - type aNode = GBTree[KEY,Entry]; - type anInsertTree = InsertTree[KEY,Entry]; +private abstract class GBTree[A,B] { + type aNode = GBTree[A,B]; + type anInsertTree = InsertTree[A,B]; /** Calculates 2^h, and size, where h is the height of the tree * and size is the number of nodes in the tree. */ def count:Info; - def is_defined(Key:KEY):Boolean; - def get(key:KEY):Option[Entry]; - def apply(key:KEY):Entry; - def update(key:KEY, value:Entry):aNode; - def insert(key:KEY, value:Entry, size:int):anInsertTree; - def toList(acc:List[Entry]):List[Entry]; + def is_defined(Key:A):Boolean; + def get(key:A):Option[B]; + def apply(key:A):B; + def update(key:A, value:B):aNode; + def insert(key:A, value:B, size:int):anInsertTree; + def toList(acc:List[B]):List[B]; def mk_iter(iter_tail:List[aNode]):List[aNode]; - def delete(key:KEY):aNode; + def delete(key:A):aNode; def merge(t:aNode):aNode; - def take_smallest:Pair[Entry,aNode]; - def balance(s:int):GBTree[KEY,Entry]; + def take_smallest:Pair[B,aNode]; + def balance(s:int):GBTree[A,B]; case class Info(height:int, size:int); diff --git a/sources/scala/collection/immutable/TreeMap.scala b/sources/scala/collection/immutable/TreeMap.scala index 097506f7a0..dbac7f6996 100644 --- a/sources/scala/collection/immutable/TreeMap.scala +++ b/sources/scala/collection/immutable/TreeMap.scala @@ -12,101 +12,96 @@ package scala.collection.immutable; /** This class implements immutable maps using a tree. * - * @author Erik Stenman, Matthias Zenger - * @version 1.0, 23/07/2003 + * @author Erik Stenman + * @author Matthias Zenger + * @version 1.1, 03/05/2004 */ - class TreeMap[KEY, VALUE](order: Order[KEY]) extends Tree[KEY, Pair[KEY, VALUE]](order) - with Map[KEY, VALUE] { - - override type This = TreeMap[KEY, VALUE]; - - /** A factory to create empty maps of the same type of keys. - */ - def empty[C] = new TreeMap[KEY, C](order); - - /** Returns the key of an entry. - * This method has to be defined by concrete implementations - * of the class. - */ - override def entryKey(entry:Pair[KEY,VALUE]) = entry._1; - - /** Creates a new TreeMap from a GBTree and its size. */ - protected def New(sz:Int,t:aNode):This = - new TreeMap[KEY,VALUE](order) { - override def size=sz; - override protected val tree:aNode=t; - } - - /** - * A new TreeMap with the entry added is returned, - * if key is <em>not</em> in the TreeMap, otherwise - * the key is updated with the new entry. - */ - def update(key:KEY, value:VALUE) = update_or_add(key,Pair(key,value)); - - /** - * A new TreeMap with the entry added is returned, - * assuming that key is <em>not</em> in the TreeMap. - */ - def insert(key:KEY,value:VALUE) = add(key,Pair(key,value)); - - /** Removes the key from the TreeMap. - */ - def -(key:KEY) = delete_any(key); - - /** Check if this map maps <code>key</code> to a value and return the - * value if it exists. - * - * @param key the key of the mapping of interest - * @return the value of the mapping, if it exists - */ - override def get(key:KEY) = - findValue(key).match { - case Some(Pair(_,value:VALUE)) => Some(value); - case _ => None; - } - - /** Retrieve the value which is associated with the given key. This - * method throws an exception if there is no mapping from the given - * key to a value. - * - * @param key the key - * @return the value associated with the given key. - * @throws Error("key not found"). - */ - override def apply(key:KEY):VALUE = tree.apply(key)._2; - - - /** Creates a list of all (key, value) mappings. - * - * @return the list of all mappings - */ - override def toList:List[Pair[KEY,VALUE]] = tree.toList(scala.Nil); - - /** Creates a new iterator over all elements contained in this - * object. - * - * @return the new iterator - */ - def elements:Iterator[Pair[KEY,VALUE]] = entries; - - - /** Compares two maps structurally; i.e. checks if all mappings - * contained in this map are also contained in the other map, - * and vice versa. - * - * @return true, iff both maps contain exactly the same mappings. - */ - override def equals(obj: Any): Boolean = - if (obj.isInstanceOf[scala.collection.Map[KEY, VALUE]]) { - val that = obj.asInstanceOf[scala.collection.Map[KEY, VALUE]]; - if (size != that.size) false else elements.forall { - case Pair(key, value) => that.get(key) match { - case None => false; - case Some(v) => v == value; - } - }; - } else - false; - + class TreeMap[A <% Ordered[A], B] extends Tree[A, Pair[A, B]] with Map[A, B] { + + override type This = TreeMap[A, B]; + + /** A factory to create empty maps of the same type of keys. + */ + def empty[C] = new TreeMap[A, C]; + + /** Returns the key of an entry. + * This method has to be defined by concrete implementations + * of the class. + */ + override def entryKey(entry:Pair[A,B]) = entry._1; + + /** Creates a new TreeMap from a GBTree and its size. + */ + protected def New(sz:Int,t:aNode):This = new TreeMap[A,B] { + override def size=sz; + override protected val tree:aNode=t; + } + + /** A new TreeMap with the entry added is returned, + * if key is <em>not</em> in the TreeMap, otherwise + * the key is updated with the new entry. + */ + def update(key:A, value:B) = update_or_add(key,Pair(key,value)); + + /** A new TreeMap with the entry added is returned, + * assuming that key is <em>not</em> in the TreeMap. + */ + def insert(key:A,value:B) = add(key,Pair(key,value)); + + /** Removes the key from the TreeMap. + */ + def -(key:A) = delete_any(key); + + /** Check if this map maps <code>key</code> to a value and return the + * value if it exists. + * + * @param key the key of the mapping of interest + * @return the value of the mapping, if it exists + */ + override def get(key:A) = + findValue(key).match { + case Some(Pair(_,value:B)) => Some(value); + case _ => None; + } + + /** Retrieve the value which is associated with the given key. This + * method throws an exception if there is no mapping from the given + * key to a value. + * + * @param key the key + * @return the value associated with the given key. + * @throws Error("key not found"). + */ + override def apply(key:A):B = tree.apply(key)._2; + + /** Creates a list of all (key, value) mappings. + * + * @return the list of all mappings + */ + override def toList:List[Pair[A,B]] = tree.toList(scala.Nil); + + /** Creates a new iterator over all elements contained in this + * object. + * + * @return the new iterator + */ + def elements:Iterator[Pair[A,B]] = entries; + + /** Compares two maps structurally; i.e. checks if all mappings + * contained in this map are also contained in the other map, + * and vice versa. + * + * @return true, iff both maps contain exactly the same mappings. + */ + override def equals(obj: Any): Boolean = + if (obj.isInstanceOf[scala.collection.Map[A, B]]) { + val that = obj.asInstanceOf[scala.collection.Map[A, B]]; + if (size != that.size) false else elements.forall { + case Pair(key, value) => that.get(key) match { + case None => false; + case Some(v) => v == value; + } + } + } else + false; } diff --git a/sources/scala/collection/immutable/TreeSet.scala b/sources/scala/collection/immutable/TreeSet.scala index bf085990c2..ddcc7b27c2 100644 --- a/sources/scala/collection/immutable/TreeSet.scala +++ b/sources/scala/collection/immutable/TreeSet.scala @@ -1,66 +1,68 @@ -package scala.collection.immutable; +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ -/** A set that uses TreeMap. -*/ +package scala.collection.immutable; -class TreeSet[A](order: Order[A]) with Set[A] { - protected val map = new TreeMap[ A, boolean ]( order ); +/** This class implements immutable sets using a tree. + * + * @author Matthias Zenger + * @author Burak Emir + * @version 1.1, 03/05/2004 + */ +class TreeSet[A <% Ordered[A]] extends Tree[A, A] with Set[A] { - /** Returns the number of elements in this set. - * - * @return number of set elements. - */ - def size: Int = map.size; + type This = TreeSet[A]; - /** Checks if this set contains element <code>elem</code>. - * - * @param elem the element to check for membership. - * @return true, iff <code>elem</code> is contained in this set. - */ - def contains(elem: A): Boolean = map.get(elem) match { - case Some(_) => true; - case _ => false; - } + def entryKey(entry: A) = entry; - /** This method creates a new set with an additional element. - */ - def +(elem: A): TreeSet[A] = new TreeSet(order) { - override val map = TreeSet.this.map.update( elem, true ); - } + protected def New(sz: Int, t: aNode): This = new TreeSet[A] { + override def size = sz; + override protected val tree: aNode = t; + } - /** <code>-</code> can be used to remove a single element from - * a set. - */ - def -(elem: A): TreeSet[A] = new TreeSet(order) { - override val map = TreeSet.this.map - elem ; - } + /** Checks if this set contains element <code>elem</code>. + * + * @param elem the element to check for membership. + * @return true, iff <code>elem</code> is contained in this set. + */ + def contains(elem: A): Boolean = !findValue(elem).isEmpty; - /** Creates a new iterator over all elements contained in this - * object. - * - * @return the new iterator - */ - def elements: Iterator[A] = map.elements.map { - x:Pair[A,boolean] => x._1 - }; + /** This method creates a new set with an additional element. + */ + def +(elem: A): TreeSet[A] = update_or_add(elem, elem); - /** Transform this set into a list of all elements. - * - * @return a list which enumerates all elements of this set. - */ - override def toList: List[A] = elements.toList; + /** <code>-</code> can be used to remove a single element from + * a set. + */ + def -(elem: A): TreeSet[A] = delete_any(elem); - /** Compares two sets for equality. - * Two set are equal iff they contain the same elements. - */ - override def equals(obj: Any): Boolean = - if (obj.isInstanceOf[scala.collection.Set[A]]) { - val that = obj.asInstanceOf[scala.collection.Set[A]]; - if (size != that.size) false else toList.forall(that.contains); - } else - false; + /** Creates a new iterator over all elements contained in this + * object. + * + * @return the new iterator + */ + def elements: Iterator[A] = entries; - override def hashCode(): Int = map.hashCode(); + /** Transform this set into a list of all elements. + * + * @return a list which enumerates all elements of this set. + */ + override def toList: List[A] = tree.toList(scala.Nil); + /** Compares two sets for equality. + * Two set are equal iff they contain the same elements. + */ + override def equals(obj: Any): Boolean = + if (obj.isInstanceOf[scala.collection.Set[A]]) { + val that = obj.asInstanceOf[scala.collection.Set[A]]; + if (size != that.size) false else toList.forall(that.contains); + } else + false; } diff --git a/sources/scala/collection/mutable/ArrayBuffer.scala b/sources/scala/collection/mutable/ArrayBuffer.scala index 98c10852e8..5f346c7fd3 100644 --- a/sources/scala/collection/mutable/ArrayBuffer.scala +++ b/sources/scala/collection/mutable/ArrayBuffer.scala @@ -16,29 +16,13 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 15/03/2004 */ -class ArrayBuffer[A] extends Buffer[A] { - import java.lang.System.arraycopy; - - protected def initialCapacity: Int = 8; - - private var buf: Array[A] = new Array(initialCapacity); - private var size: Int = 0; - - def length: Int = size; +class ArrayBuffer[A] extends Buffer[A] with ResizableArray[A] { def apply(n: Int): A = { if ((n < 0) || (n >= size)) error("cannot access element " + n + " in ArrayBuffer"); else - buf(n); - } - - protected def ensureCapacity(n: Int): Unit = { - if ((size + n) >= buf.length) { - val newbuf: Array[A] = new Array(buf.length * 2); - arraycopy(buf, 0, newbuf, 0, size); - buf = newbuf; - } + array(n); } /** Append a single element to this buffer and return @@ -47,8 +31,8 @@ class ArrayBuffer[A] extends Buffer[A] { * @param elem the element to append. */ def +(elem: A): Buffer[A] = { - ensureCapacity(1); - buf(size) = elem; + ensureSize(1); + array(size) = elem; size = size + 1; this } @@ -67,9 +51,9 @@ class ArrayBuffer[A] extends Buffer[A] { * @param elem the element to append. */ def +:(elem: A): Buffer[A] = { - ensureCapacity(1); - arraycopy(buf, 0, buf, 1, size); - buf(0) = elem; + ensureSize(1); + copy(0, 1, size); + array(0) = elem; size = size + 1; this } @@ -94,9 +78,9 @@ class ArrayBuffer[A] extends Buffer[A] { error("cannot insert element " + n + " in ListBuffer"); val xs = iter.elements.toList; val len = xs.length; - ensureCapacity(len); - arraycopy(buf, n, buf, n + len, size - n); - xs.copyToArray(buf, n); + ensureSize(len); + copy(n, n + len, size - n); + xs.copyToArray(array, n); size = size + len; } @@ -110,8 +94,8 @@ class ArrayBuffer[A] extends Buffer[A] { if ((n < 0) || (n >= size)) error("cannot update element " + n + " in ArrayBuffer"); else { - val res = buf(n); - buf(n) = newelem; + val res = array(n); + array(n) = newelem; res } } @@ -123,8 +107,8 @@ class ArrayBuffer[A] extends Buffer[A] { def remove(n: Int): A = { if ((n < 0) || (n >= size)) error("cannot remove element " + n + " in Buffer"); - val res = buf(n); - arraycopy(buf, n + 1, buf, n, size - n - 1); + val res = array(n); + copy(n + 1, n, size - n - 1); size = size - 1; res } @@ -135,12 +119,14 @@ class ArrayBuffer[A] extends Buffer[A] { size = 0; } - /** Returns a new iterator over all elements of this buffer. + /** Return a clone of this buffer. + * + * @return an <code>ArrayBuffer</code> with the same elements. */ - def elements: Iterator[A] = new Iterator[A] { - var i = 0; - def hasNext: Boolean = i < size; - def next: A = { i = i + 1; buf(i - 1) } + override def clone(): Buffer[A] = { + val res = new ArrayBuffer[A]; + res ++= this; + res } /** Checks if two buffers are structurally identical. diff --git a/sources/scala/collection/mutable/Buffer.scala b/sources/scala/collection/mutable/Buffer.scala index ddb4f65bef..65da4983d1 100644 --- a/sources/scala/collection/mutable/Buffer.scala +++ b/sources/scala/collection/mutable/Buffer.scala @@ -18,7 +18,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.1, 02/03/2004 */ -trait Buffer[A] with Seq[A] { +trait Buffer[A] with Seq[A] with Cloneable { /** Append a single element to this buffer and return * the identity of the buffer. @@ -132,6 +132,12 @@ trait Buffer[A] with Seq[A] { */ def clear: Unit; + /** Return a clone of this buffer. + * + * @return an <code>ArrayBuffer</code> with the same elements. + */ + override def clone(): Buffer[A] = super.clone().asInstanceOf[Buffer[A]]; + /** The hashCode method always yields an error, since it is not * safe to use buffers as keys in hash tables. * diff --git a/sources/scala/collection/mutable/BufferProxy.scala b/sources/scala/collection/mutable/BufferProxy.scala index 8a30964006..1365c0362f 100644 --- a/sources/scala/collection/mutable/BufferProxy.scala +++ b/sources/scala/collection/mutable/BufferProxy.scala @@ -130,4 +130,10 @@ class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { /** Clears the buffer contents. */ def clear: Unit = buf.clear; + + /** Return a clone of this buffer. + * + * @return a <code>Buffer</code> with the same elements. + */ + override def clone(): Buffer[A] = buf.clone(); } diff --git a/sources/scala/collection/mutable/ListBuffer.scala b/sources/scala/collection/mutable/ListBuffer.scala index f8fd66ca8a..527741bbc9 100644 --- a/sources/scala/collection/mutable/ListBuffer.scala +++ b/sources/scala/collection/mutable/ListBuffer.scala @@ -115,6 +115,16 @@ class ListBuffer[A] extends Buffer[A] with MutableList[A] { */ def clear: Unit = reset; + /** Return a clone of this buffer. + * + * @return an <code>ArrayBuffer</code> with the same elements. + */ + override def clone(): Buffer[A] = { + val res = new ListBuffer[A]; + res ++= this; + res + } + /** Checks if two buffers are structurally identical. * * @return true, iff both buffers contain the same sequence of elements. diff --git a/sources/scala/collection/mutable/MutableList.scala b/sources/scala/collection/mutable/MutableList.scala index 1f71bd7531..c8a694804f 100644 --- a/sources/scala/collection/mutable/MutableList.scala +++ b/sources/scala/collection/mutable/MutableList.scala @@ -17,7 +17,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -class MutableList[A] extends Seq[A] with PartialFunction[Int, A] { +abstract class MutableList[A] extends Seq[A] with PartialFunction[Int, A] { protected var first: LinkedList[A] = null; protected var last: LinkedList[A] = null; diff --git a/sources/scala/collection/mutable/Queue.scala b/sources/scala/collection/mutable/Queue.scala index 0579fb221f..8bd6a0da4c 100644 --- a/sources/scala/collection/mutable/Queue.scala +++ b/sources/scala/collection/mutable/Queue.scala @@ -14,7 +14,7 @@ package scala.collection.mutable; * insert and retrieve elements in a first-in-first-out (FIFO) manner. * * @author Matthias Zenger - * @version 1.0, 08/07/2003 + * @version 1.1, 03/05/2004 */ class Queue[A] extends MutableList[A] { @@ -28,7 +28,7 @@ class Queue[A] extends MutableList[A] { * * @param elem the element to insert */ - def +=(elem: A) = appendElem(elem); + def +=(elem: A): Unit = appendElem(elem); /** Adds all elements provided by an <code>Iterable</code> object * at the end of the queue. The elements are prepended in the order they @@ -36,13 +36,13 @@ class Queue[A] extends MutableList[A] { * * @param iter an iterable object */ - def +=(iter: Iterable[A]) = iter.elements.foreach(e => appendElem(e)); + def ++=(iter: Iterable[A]): Unit = iter.elements.foreach(e => appendElem(e)); /** Adds all elements to the queue. * * @param elems the elements to add. */ - def enqueue(elems: A*): Unit = (this += elems); + def enqueue(elems: A*): Unit = (this ++= elems); /** Returns the first element in the queue, and removes this element * from the queue. diff --git a/sources/scala/collection/mutable/Stack.scala b/sources/scala/collection/mutable/Stack.scala index c60518b209..d401d35144 100644 --- a/sources/scala/collection/mutable/Stack.scala +++ b/sources/scala/collection/mutable/Stack.scala @@ -14,7 +14,7 @@ package scala.collection.mutable; * objects in a last-in-first-out (LIFO) fashion. * * @author Matthias Zenger - * @version 1.0, 08/07/2003 + * @version 1.1, 03/05/2004 */ class Stack[A] extends MutableList[A] { @@ -36,14 +36,14 @@ class Stack[A] extends MutableList[A] { * * @param iter an iterable object */ - def +=(iter: Iterable[A]): Unit = iter.elements.foreach(e => prependElem(e)); + def ++=(iter: Iterable[A]): Unit = iter.elements.foreach(e => prependElem(e)); /** Pushes a sequence of elements on top of the stack. The first element * is pushed first, etc. * * @param elems a sequence of elements */ - def push(elems: A*): Unit = (this += elems); + def push(elems: A*): Unit = (this ++= elems); /** Returns the top element of the stack. This method will not remove * the element from the stack. An error is signaled if there is no @@ -55,7 +55,13 @@ class Stack[A] extends MutableList[A] { /** Removes the top element from the stack. */ - def pop: Unit = if (first != null) { first = first.next; } + def pop: A = + if (first != null) { + val res = first.elem; + first = first.next; + res + } else + error("stack empty"); /** * Removes all elements from the stack. After this operation completed, diff --git a/sources/scala/collection/mutable/SynchronizedBuffer.scala b/sources/scala/collection/mutable/SynchronizedBuffer.scala index d41da4f858..a64d864872 100644 --- a/sources/scala/collection/mutable/SynchronizedBuffer.scala +++ b/sources/scala/collection/mutable/SynchronizedBuffer.scala @@ -166,6 +166,14 @@ trait SynchronizedBuffer[A] extends Buffer[A] { super.clear; } + /** Return a clone of this buffer. + * + * @return an <code>ArrayBuffer</code> with the same elements. + */ + override def clone(): Buffer[A] = synchronized { + super.clone(); + } + /** The hashCode method always yields an error, since it is not * safe to use buffers as keys in hash tables. * |