From 3a4c181e03a43fefcaeee83489109dbfebdce970 Mon Sep 17 00:00:00 2001 From: buraq Date: Wed, 30 Jul 2003 12:58:55 +0000 Subject: hash-consing on load, enabled per default --- sources/scala/xml/Element.scala | 13 +++++++++++++ sources/scala/xml/Generic.scala | 15 ++++++++++++--- sources/scala/xml/PCDATA.scala | 1 + sources/scala/xml/ScalaFactoryAdapter.scala | 29 +++++++++++++++++++++++++---- 4 files changed, 51 insertions(+), 7 deletions(-) (limited to 'sources') diff --git a/sources/scala/xml/Element.scala b/sources/scala/xml/Element.scala index 04fb40bcb8..e4d24f1918 100644 --- a/sources/scala/xml/Element.scala +++ b/sources/scala/xml/Element.scala @@ -15,6 +15,8 @@ abstract class Element { def getAttribs: Map[ String, String ]; // disabled def setAttribs( m:Map[ String, String ] ):Unit ; + override def hashCode() = Element.hashValue( getName, getAttribs, getChildren ); + def toXML: String = { "<" + getName + toXML_( getAttribs ) + ">" + toXML_( getChildren ) @@ -59,3 +61,14 @@ abstract class Element { } // def toXML */ } // abstract class + +object Element { + def hashValue( name:String, attribs:Map[ String, String ], children:Seq[ Element ] ) = { + name.hashCode() + attribs.hashCode() + children.hashCode() + } + + def hashValue( name:String, attribs:java.util.Map, children:Seq[ Element ] ) = { + name.hashCode() + attribs.hashCode() + children.hashCode() + } + +} diff --git a/sources/scala/xml/Generic.scala b/sources/scala/xml/Generic.scala index d7d2a81445..22355cf226 100644 --- a/sources/scala/xml/Generic.scala +++ b/sources/scala/xml/Generic.scala @@ -25,15 +25,24 @@ object Generic { def elementContainsText( name:java.lang.String ):boolean = true; + // default behaviour is hash-consing + val cache = new HashMap(); + def createElement( elemName:String, attribs :java.util.Map, // ignore attributes. children:java.util.Iterator ):scala.Object = { + val el = Labelled( Symbol( elemName), iterToList[ Any ]( children )); + val el_cache = cache.get( el as scala.All ) as scala.Object; + if ( el_cache != null ) { + System.err.println("[using cached elem!]"); + el_cache + } else { + cache.put( el as scala.All, el as scala.All ); + el + } - - Labelled( Symbol( elemName), iterToList[ Any ]( children )) - } def createPCDATA( text:String ):scala.Object = { diff --git a/sources/scala/xml/PCDATA.scala b/sources/scala/xml/PCDATA.scala index 120cbf4bf4..70d849f3bf 100644 --- a/sources/scala/xml/PCDATA.scala +++ b/sources/scala/xml/PCDATA.scala @@ -14,6 +14,7 @@ case class PCDATA( content:String ) extends Element { override def toXML:String = content; + override def hashCode() = content.hashCode(); override def toString() = "PCDATA("+content+")"; } // PCDATA diff --git a/sources/scala/xml/ScalaFactoryAdapter.scala b/sources/scala/xml/ScalaFactoryAdapter.scala index 081e127e45..cb38c85860 100644 --- a/sources/scala/xml/ScalaFactoryAdapter.scala +++ b/sources/scala/xml/ScalaFactoryAdapter.scala @@ -46,16 +46,37 @@ abstract class ScalaFactoryAdapter val g: Map[ String, boolean ] ; + val compress: boolean ; + def elementContainsText( name:java.lang.String ):boolean = g.get( name ) ; + // if compress is set, used for hash-consing + val cache = new HashMap(); + def createElement(elemName:String, attribs:java.util.Map, children:java.util.Iterator ):scala.Object = { - val c = f.get( elemName ); // constructor - val el = c( iterToList[Element]( children ) ); - el.setAttribs( mapToMap[String,String]( attribs ) ); - el + val _children = iterToList[Element]( children ); // 2do:optimize + if( !compress ) { + val c = f.get( elemName ); // get constructor + val el = c( _children ); + el.setAttribs( mapToMap[String,String]( attribs ) ); + el + } else { // do hash-consing + + val h = Element.hashValue( elemName, attribs, _children ); + val el_cache = cache.get( h as scala.All ) as scala.Object; + if ( el_cache != null ) { // return cached elem + el_cache + } else { + val c = f.get( elemName ); // get constructor + val el = c( _children ); + el.setAttribs( mapToMap[String,String]( attribs ) ); + cache.put( h as scala.All, el as scala.All ); + el + } + } } def createPCDATA( text:String ):scala.Object = { -- cgit v1.2.3