summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sources/scala/collection/immutable/Set.scala6
-rw-r--r--sources/scala/xml/AttributeSeq.scala3
-rw-r--r--sources/scala/xml/NodeFactory.scala29
-rw-r--r--sources/scala/xml/Text.scala5
-rw-r--r--sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala17
5 files changed, 39 insertions, 21 deletions
diff --git a/sources/scala/collection/immutable/Set.scala b/sources/scala/collection/immutable/Set.scala
index 49987e80a9..7308b595dc 100644
--- a/sources/scala/collection/immutable/Set.scala
+++ b/sources/scala/collection/immutable/Set.scala
@@ -71,4 +71,10 @@ trait Set[A] with scala.collection.Set[A] {
}
res;
}
+
+ /** hashcode for this set */
+ override def hashCode() = {
+ elements.foldLeft(0)((hash: Int, e: A) => hash + e.hashCode());
+ }
+
}
diff --git a/sources/scala/xml/AttributeSeq.scala b/sources/scala/xml/AttributeSeq.scala
index 31bb5cf43c..c0484d159b 100644
--- a/sources/scala/xml/AttributeSeq.scala
+++ b/sources/scala/xml/AttributeSeq.scala
@@ -147,7 +147,8 @@ abstract class AttributeSeq with Seq[Attribute] {
AttributeSeq.fromAttrs( elements.map( f ).toList:_* )
}
- override def hashCode():Int = sortedSeq.hashCode();
+ override def hashCode():Int =
+ sortedSeq.hashCode();
def toMap:Map[Pair[String,String],Attribute] =
new Map[Pair[String,String],Attribute] {
diff --git a/sources/scala/xml/NodeFactory.scala b/sources/scala/xml/NodeFactory.scala
index d971865dad..3ab21963f4 100644
--- a/sources/scala/xml/NodeFactory.scala
+++ b/sources/scala/xml/NodeFactory.scala
@@ -20,8 +20,6 @@ abstract class NodeFactory[A <: Node] {
/* default behaviour is to use hash-consing */
val cache = new mutable.HashMap[int,List[A]]();
-
-
protected def create(uname: UName, attrs: AttributeSeq, children:Seq[Node]): A;
def makeNode(uname: UName, attrSeq:AttributeSeq, children:Seq[Node]): A = {
@@ -33,18 +31,39 @@ abstract class NodeFactory[A <: Node] {
el
}
+ /** faster equality, because */
+ def eqElements(ch1:Seq[Node], ch2:Seq[Node]): Boolean = {
+ (ch1.length == ch2.length) && {
+ val it1 = ch1.elements;
+ val it2 = ch2.elements;
+ var res = true;
+ while(res && it1.hasNext) {
+ res = it1.next.eq(it2.next);
+ }
+ res
+ }
+ }
+
def nodeEquals(n: Node) =
(n.namespace == uname.uri)
&&(n.label == uname.label)
&&(n.attributes == attrSeq)
- &&(n.child.sameElements(children));
-
+ &&(eqElements(n.child,children));
+
+ /*
+ Console.println("[makeNode called, hash: ]"+hash);
+ Console.println("[elem name: ]"+uname+" hash "+(41 * uname.uri.hashCode() % 7 + uname.label.hashCode());
+ Console.println("[attrs : ]"+attrSeq+" hash "+attrSeq.hashCode());
+ Console.println("[children name: ]"+children+" hash "+children.hashCode());
+ */
cache.get( hash ) match {
case Some(list) => // find structurally equal
val it = list.elements;
val lookup = it.find { x => nodeEquals(x) };
lookup match {
- case Some(x) => x; // return cached elem
+ case Some(x) =>
+ //Console.println("[cache hit !]"+x);
+ x; // return cached elem
case _ => construct;
}
case _ => construct
diff --git a/sources/scala/xml/Text.scala b/sources/scala/xml/Text.scala
index a65c75b60f..c81918bcea 100644
--- a/sources/scala/xml/Text.scala
+++ b/sources/scala/xml/Text.scala
@@ -13,11 +13,14 @@ import scala.collection.immutable ;
/** an XML node for text (PCDATA). Used in both non-bound and bound XML
* representations
* @author Burak Emir
- * @param text the text contained in this node
+ * @param text the text contained in this node, may not be null.
**/
case class Text( text:String ) extends SpecialNode {
+ if(null == text)
+ throw new java.lang.NullPointerException("tried to construct Text with null");
+
final override def typeTag$:Int = -1;
/** the constant "#PCDATA"
diff --git a/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala b/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala
index ee1882cd57..117e7a8888 100644
--- a/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala
+++ b/sources/scala/xml/nobinding/NoBindingFactoryAdapter.scala
@@ -26,12 +26,12 @@ class NoBindingFactoryAdapter extends FactoryAdapter with NodeFactory[Elem] {
def nodeContainsText( label:java.lang.String ):boolean = true;
+ // methods for NodeFactory[Elem]
protected def create(uname: UName, attrs: AttributeSeq, children:Seq[Node]): Elem = {
Elem( uname.uri, uname.label, attrs, children:_* );
}
- /* default behaviour is to use hash-consing */
- //val cache = new mutable.HashMap[int,Elem]();
+ // methods for FactoryAdapter
/** creates a node. never creates the same node twice, using hash-consing
*/
@@ -49,18 +49,7 @@ class NoBindingFactoryAdapter extends FactoryAdapter with NodeFactory[Elem] {
val elHashCode =
Utility.hashCode( uri$, label, attrSeq.hashCode(), children ) ;
makeNode(UName(uri$,label),attrSeq, children);
- /*
- cache.get( elHashCode ).match{
- case Some(cachedElem) =>
- //System.err.println("[using cached elem +"+cachedElem.toXML+"!]"); //DEBUG
- cachedElem
- case None =>
- val el = Elem( uri$, label, attrSeq, children:_* );
- cache.update( elHashCode, el );
- el
- }
- */
- }
+ }
/** creates a text node
*/