package scales.xml.parser.strategies
import scales.utils._
import scales.xml._
import scales.xml.impl.{NotFromParser, FromParser}
import scales.xml.impl.TreeProxies
trait OptimisingStrategiesImplicits {
}
trait OptimisationToken {
implicit val ver : XmlVersion
implicit val fromParser : FromParser
private[strategies] var attrs: Array[Attribute] = Array.ofDim(20)
private[strategies] final def resizeAttrs(size: Int) {
if (size > attrs.length) {
attrs = Array.ofDim((size * 1.5).toInt)
}
}
}
class BaseToken(implicit val ver : XmlVersion, val fromParser : FromParser) extends OptimisationToken
trait MemoryOptimisationStrategy[Token <: OptimisationToken] {
def createToken(implicit ver : XmlVersion, fromParser : FromParser) : Token
def attributeArray(newSize: Int, token: Token): Array[Attribute] = {
token.resizeAttrs(newSize)
token.attrs
}
def attribute( qname : AttributeQName, value : String, token : Token) : Attribute = Attribute(qname,value)
def noNamespaceQName( local : String, token : Token) : NoNamespaceQName = {
import token._
NoNamespaceQName(local)
}
def unprefixedQName( local : String, uri : String, token : Token) : UnprefixedQName = {
import token._
UnprefixedQName(local, Namespace(uri))
}
def prefixedQName( local : String, uri : String, prefix : String, token : Token) : PrefixedQName = {
import token._
PrefixedQName(local, Namespace(uri).prefixed(prefix))
}
def elem( name : QName, attributes : Attributes, namespaces : Map[String, String], token : Token) : Elem = {
import token._
Elem(name, attributes, namespaces)
}
}
trait BaseTokenF {
def createToken(implicit ver : XmlVersion, fromParser : FromParser) : BaseToken = new BaseToken()
}
object NoOptimisation extends PathOptimisationStrategy[BaseToken] with BaseTokenF
trait PathOptimisationStrategy[Token <: OptimisationToken] extends MemoryOptimisationStrategy[Token] {
def elementEnd( xml : TreeProxies, token : Token) {
xml.elementEnd
}
def beginSubTree( stack : TreeProxies, elem : Elem, token : Token) {
stack.beginSub(elem, XmlBuilder())
}
}
import scales.xml.impl.FullEqualQNameKey
class QNameToken(implicit val ver : XmlVersion, val fromParser : FromParser) extends OptimisationToken {
val qkey = new FullEqualQNameKey()
val noNsQ = (k : FullEqualQNameKey) => NoNamespaceQName(k.local)
val unQ = (k : FullEqualQNameKey) => UnprefixedQName(k.local, Namespace(k.namespace))
val pQ = (k : FullEqualQNameKey) => PrefixedQName(k.local, Namespace(k.namespace).prefixed(k.prefix))
}
trait QNameTokenF {
def createToken(implicit ver : XmlVersion, fromParser : FromParser) = new QNameToken()
}
trait QNameOptimisationT[Token <: QNameToken] extends MemoryOptimisationStrategy[Token] {
import java.util.concurrent.ConcurrentHashMap
val qNameCache = new ConcurrentHashMap[ FullEqualQNameKey, QName ]
override def noNamespaceQName( local : String, token : Token) : NoNamespaceQName = {
val qt = token
import qt._
value( qkey.setNoNamespaceQName(local) )( noNsQ )
}
override def unprefixedQName( local : String, uri : String, token : Token) : UnprefixedQName = {
val qt = token
import qt._
value( qkey.setUnprefixedQName(local, uri) )( unQ )
}
override def prefixedQName( local : String, uri : String, prefix : String, token : Token) : PrefixedQName = {
val qt = token
import qt._
value( qkey.setPrefixedQName( local, uri, prefix) )( pQ )
}
def value[T <: QName](key : FullEqualQNameKey)( newT : FullEqualQNameKey => T ) : T = {
var value = qNameCache.get(key)
if (value == null) {
value = newT(key)
val res = qNameCache.putIfAbsent(key.copy, value)
value = if (res == null) value else res
}
value.asInstanceOf[T]
}
}
object QNameMemoryOptimisation extends PathOptimisationStrategy[QNameToken] with QNameOptimisationT[QNameToken] with QNameTokenF
<iframe src="https://scalesxml.github.io/scales-xml_2.10/0.5.0/api.sxr/scales/xml/parser/strategies/OptimisingStrategies.scala.html" width="1280" height="720" frameborder="0"> </iframe>