summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/collection/mutable/ConcurrentTrieMap.scala (renamed from src/library/scala/collection/mutable/Ctrie.scala)100
-rw-r--r--src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala (renamed from src/library/scala/collection/parallel/mutable/ParCtrie.scala)54
-rw-r--r--src/library/scala/util/Properties.scala24
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/Elem.scala35
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/Node.scala2
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/PrettyPrinter.scala2
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/Utility.scala63
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/XML.scala19
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/factory/Binder.scala10
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/parsing/ConstructingHandler.scala4
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/parsing/DefaultMarkupHandler.scala2
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/parsing/MarkupHandler.scala3
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/parsing/MarkupParser.scala2
-rwxr-xr-xsrc/library/scala/xml/pull/XMLEventReader.scala2
14 files changed, 192 insertions, 130 deletions
diff --git a/src/library/scala/collection/mutable/Ctrie.scala b/src/library/scala/collection/mutable/ConcurrentTrieMap.scala
index cbec118aa9..1a44c8e423 100644
--- a/src/library/scala/collection/mutable/Ctrie.scala
+++ b/src/library/scala/collection/mutable/ConcurrentTrieMap.scala
@@ -13,7 +13,7 @@ package mutable
import java.util.concurrent.atomic._
import collection.immutable.{ ListMap => ImmutableListMap }
-import collection.parallel.mutable.ParCtrie
+import collection.parallel.mutable.ParConcurrentTrieMap
import generic._
import annotation.tailrec
import annotation.switch
@@ -31,16 +31,16 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
@inline final def CAS(old: MainNode[K, V], n: MainNode[K, V]) = INodeBase.updater.compareAndSet(this, old, n)
- final def gcasRead(ct: Ctrie[K, V]): MainNode[K, V] = GCAS_READ(ct)
+ final def gcasRead(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = GCAS_READ(ct)
- @inline final def GCAS_READ(ct: Ctrie[K, V]): MainNode[K, V] = {
+ @inline final def GCAS_READ(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = {
val m = /*READ*/mainnode
val prevval = /*READ*/m.prev
if (prevval eq null) m
else GCAS_Complete(m, ct)
}
- @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: Ctrie[K, V]): MainNode[K, V] = if (m eq null) null else {
+ @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = if (m eq null) null else {
// complete the GCAS
val prev = /*READ*/m.prev
val ctr = ct.readRoot(true)
@@ -72,7 +72,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: Ctrie[K, V]): Boolean = {
+ @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): Boolean = {
n.WRITE_PREV(old)
if (CAS(old, n)) {
GCAS_Complete(n, ct)
@@ -86,7 +86,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
nin
}
- final def copyToGen(ngen: Gen, ct: Ctrie[K, V]) = {
+ final def copyToGen(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = {
val nin = new INode[K, V](ngen)
val main = GCAS_READ(ct)
nin.WRITE(main)
@@ -97,7 +97,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
*
* @return true if successful, false otherwise
*/
- @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Boolean = {
+ @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Boolean = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -143,7 +143,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
* @param cond null - don't care if the key was there; KEY_ABSENT - key wasn't there; KEY_PRESENT - key was there; other value `v` - key must be bound to `v`
* @return null if unsuccessful, Option[V] otherwise (indicating previous value bound to the key)
*/
- @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Option[V] = {
+ @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -233,7 +233,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
*
* @return null if no value has been found, RESTART if the operation wasn't successful, or any other value otherwise
*/
- @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): AnyRef = {
+ @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): AnyRef = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -276,7 +276,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
* @param v if null, will remove the key irregardless of the value; otherwise removes only if binding contains that exact key and value
* @return null if not successful, an Option[V] indicating the previous value otherwise
*/
- final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Option[V] = {
+ final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -352,7 +352,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- private def clean(nd: INode[K, V], ct: Ctrie[K, V], lev: Int) {
+ private def clean(nd: INode[K, V], ct: ConcurrentTrieMap[K, V], lev: Int) {
val m = nd.GCAS_READ(ct)
m match {
case cn: CNode[K, V] => nd.GCAS(cn, cn.toCompressed(ct, lev, gen), ct)
@@ -360,9 +360,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- final def isNullInode(ct: Ctrie[K, V]) = GCAS_READ(ct) eq null
+ final def isNullInode(ct: ConcurrentTrieMap[K, V]) = GCAS_READ(ct) eq null
- final def cachedSize(ct: Ctrie[K, V]): Int = {
+ final def cachedSize(ct: ConcurrentTrieMap[K, V]): Int = {
val m = GCAS_READ(ct)
m.cachedSize(ct)
}
@@ -438,7 +438,7 @@ extends MainNode[K, V] {
if (updmap.size > 1) new LNode(updmap)
else {
val (k, v) = updmap.iterator.next
- new TNode(k, v, Ctrie.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses
+ new TNode(k, v, ConcurrentTrieMap.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses
}
}
def get(k: K) = listmap.get(k)
@@ -455,7 +455,7 @@ extends CNodeBase[K, V] {
val currsz = READ_SIZE()
if (currsz != -1) currsz
else {
- val sz = computeSize(ct.asInstanceOf[Ctrie[K, V]])
+ val sz = computeSize(ct.asInstanceOf[ConcurrentTrieMap[K, V]])
while (READ_SIZE() == -1) CAS_SIZE(-1, sz)
READ_SIZE()
}
@@ -466,7 +466,7 @@ extends CNodeBase[K, V] {
// => if there are concurrent size computations, they start
// at different positions, so they are more likely to
// to be independent
- private def computeSize(ct: Ctrie[K, V]): Int = {
+ private def computeSize(ct: ConcurrentTrieMap[K, V]): Int = {
var i = 0
var sz = 0
val offset = math.abs(util.Random.nextInt()) % array.length
@@ -511,7 +511,7 @@ extends CNodeBase[K, V] {
/** Returns a copy of this cnode such that all the i-nodes below it are copied
* to the specified generation `ngen`.
*/
- final def renewed(ngen: Gen, ct: Ctrie[K, V]) = {
+ final def renewed(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = {
var i = 0
val arr = array
val len = arr.length
@@ -542,7 +542,7 @@ extends CNodeBase[K, V] {
// returns the version of this node with at least some null-inodes
// removed (those existing when the op began)
// - if there are only null-i-nodes below, returns null
- final def toCompressed(ct: Ctrie[K, V], lev: Int, gen: Gen) = {
+ final def toCompressed(ct: ConcurrentTrieMap[K, V], lev: Int, gen: Gen) = {
var bmp = bitmap
var i = 0
val arr = array
@@ -594,7 +594,7 @@ private[mutable] object CNode {
val yidx = (yhc >>> lev) & 0x1f
val bmp = (1 << xidx) | (1 << yidx)
if (xidx == yidx) {
- val subinode = new INode[K, V](gen)//(Ctrie.inodeupdater)
+ val subinode = new INode[K, V](gen)//(ConcurrentTrieMap.inodeupdater)
subinode.mainnode = dual(x, xhc, y, yhc, lev + 5, gen)
new CNode(bmp, Array(subinode), gen)
} else {
@@ -613,7 +613,7 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai
}
-/** A concurrent hash-trie or Ctrie is a concurrent thread-safe lock-free
+/** A concurrent hash-trie or ConcurrentTrieMap is a concurrent thread-safe lock-free
* implementation of a hash array mapped trie. It is used to implement the
* concurrent map abstraction. It has particularly scalable concurrent insert
* and remove operations and is memory-efficient. It supports O(1), atomic,
@@ -627,20 +627,20 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai
* @since 2.10
*/
@SerialVersionUID(0L - 6402774413839597105L)
-final class Ctrie[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[Ctrie[K, V], AnyRef])
+final class ConcurrentTrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[ConcurrentTrieMap[K, V], AnyRef])
extends ConcurrentMap[K, V]
- with MapLike[K, V, Ctrie[K, V]]
- with CustomParallelizable[(K, V), ParCtrie[K, V]]
+ with MapLike[K, V, ConcurrentTrieMap[K, V]]
+ with CustomParallelizable[(K, V), ParConcurrentTrieMap[K, V]]
with Serializable
{
- import Ctrie.computeHash
+ import ConcurrentTrieMap.computeHash
private var rootupdater = rtupd
@volatile var root = r
def this() = this(
INode.newRootNode,
- AtomicReferenceFieldUpdater.newUpdater(classOf[Ctrie[K, V]], classOf[AnyRef], "root")
+ AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root")
)
/* internal methods */
@@ -652,22 +652,22 @@ extends ConcurrentMap[K, V]
out.writeObject(k)
out.writeObject(v)
}
- out.writeObject(CtrieSerializationEnd)
+ out.writeObject(ConcurrentTrieMapSerializationEnd)
}
private def readObject(in: java.io.ObjectInputStream) {
root = INode.newRootNode
- rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[Ctrie[K, V]], classOf[AnyRef], "root")
+ rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root")
var obj: AnyRef = null
do {
obj = in.readObject()
- if (obj != CtrieSerializationEnd) {
+ if (obj != ConcurrentTrieMapSerializationEnd) {
val k = obj.asInstanceOf[K]
val v = in.readObject().asInstanceOf[V]
update(k, v)
}
- } while (obj != CtrieSerializationEnd)
+ } while (obj != ConcurrentTrieMapSerializationEnd)
}
@inline final def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.compareAndSet(this, ov, nv)
@@ -760,37 +760,37 @@ extends ConcurrentMap[K, V]
override def seq = this
- override def par = new ParCtrie(this)
+ override def par = new ParConcurrentTrieMap(this)
- override def empty: Ctrie[K, V] = new Ctrie[K, V]
+ override def empty: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V]
final def isReadOnly = rootupdater eq null
final def nonReadOnly = rootupdater ne null
- /** Returns a snapshot of this Ctrie.
+ /** Returns a snapshot of this ConcurrentTrieMap.
* This operation is lock-free and linearizable.
*
* The snapshot is lazily updated - the first time some branch
- * in the snapshot or this Ctrie are accessed, they are rewritten.
+ * in the snapshot or this ConcurrentTrieMap are accessed, they are rewritten.
* This means that the work of rebuilding both the snapshot and this
- * Ctrie is distributed across all the threads doing updates or accesses
+ * ConcurrentTrieMap is distributed across all the threads doing updates or accesses
* subsequent to the snapshot creation.
*/
- @tailrec final def snapshot(): Ctrie[K, V] = {
+ @tailrec final def snapshot(): ConcurrentTrieMap[K, V] = {
val r = RDCSS_READ_ROOT()
val expmain = r.gcasRead(this)
- if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new Ctrie(r.copyToGen(new Gen, this), rootupdater)
+ if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r.copyToGen(new Gen, this), rootupdater)
else snapshot()
}
- /** Returns a read-only snapshot of this Ctrie.
+ /** Returns a read-only snapshot of this ConcurrentTrieMap.
* This operation is lock-free and linearizable.
*
* The snapshot is lazily updated - the first time some branch
- * of this Ctrie are accessed, it is rewritten. The work of creating
+ * of this ConcurrentTrieMap are accessed, it is rewritten. The work of creating
* the snapshot is thus distributed across subsequent updates
- * and accesses on this Ctrie by all threads.
+ * and accesses on this ConcurrentTrieMap by all threads.
* Note that the snapshot itself is never rewritten unlike when calling
* the `snapshot` method, but the obtained snapshot cannot be modified.
*
@@ -799,7 +799,7 @@ extends ConcurrentMap[K, V]
@tailrec final def readOnlySnapshot(): collection.Map[K, V] = {
val r = RDCSS_READ_ROOT()
val expmain = r.gcasRead(this)
- if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new Ctrie(r, null)
+ if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r, null)
else readOnlySnapshot()
}
@@ -872,7 +872,7 @@ extends ConcurrentMap[K, V]
def iterator: Iterator[(K, V)] =
if (nonReadOnly) readOnlySnapshot().iterator
- else new CtrieIterator(0, this)
+ else new ConcurrentTrieMapIterator(0, this)
private def cachedSize() = {
val r = RDCSS_READ_ROOT()
@@ -883,17 +883,17 @@ extends ConcurrentMap[K, V]
if (nonReadOnly) readOnlySnapshot().size
else cachedSize()
- override def stringPrefix = "Ctrie"
+ override def stringPrefix = "ConcurrentTrieMap"
}
-object Ctrie extends MutableMapFactory[Ctrie] {
+object ConcurrentTrieMap extends MutableMapFactory[ConcurrentTrieMap] {
val inodeupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[INodeBase[_, _]], classOf[MainNode[_, _]], "mainnode")
- implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), Ctrie[K, V]] = new MapCanBuildFrom[K, V]
+ implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), ConcurrentTrieMap[K, V]] = new MapCanBuildFrom[K, V]
- def empty[K, V]: Ctrie[K, V] = new Ctrie[K, V]
+ def empty[K, V]: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V]
@inline final def computeHash[K](k: K): Int = {
var hcode = k.hashCode
@@ -905,7 +905,7 @@ object Ctrie extends MutableMapFactory[Ctrie] {
}
-private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ctrie[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] {
+private[collection] class ConcurrentTrieMapIterator[K, V](var level: Int, private var ct: ConcurrentTrieMap[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] {
var stack = new Array[Array[BasicNode]](7)
var stackpos = new Array[Int](7)
var depth = -1
@@ -971,9 +971,9 @@ private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ct
}
} else current = null
- protected def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new CtrieIterator[K, V](_lev, _ct, _mustInit)
+ protected def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ConcurrentTrieMapIterator[K, V](_lev, _ct, _mustInit)
- protected def dupTo(it: CtrieIterator[K, V]) = {
+ protected def dupTo(it: ConcurrentTrieMapIterator[K, V]) = {
it.level = this.level
it.ct = this.ct
it.depth = this.depth
@@ -993,7 +993,7 @@ private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ct
}
/** Returns a sequence of iterators over subsets of this iterator.
- * It's used to ease the implementation of splitters for a parallel version of the Ctrie.
+ * It's used to ease the implementation of splitters for a parallel version of the ConcurrentTrieMap.
*/
protected def subdivide(): Seq[Iterator[(K, V)]] = if (subiter ne null) {
// the case where an LNode is being iterated
@@ -1043,7 +1043,7 @@ private[mutable] object RestartException extends util.control.ControlThrowable
/** Only used for ctrie serialization. */
@SerialVersionUID(0L - 7237891413820527142L)
-private[mutable] case object CtrieSerializationEnd
+private[mutable] case object ConcurrentTrieMapSerializationEnd
private[mutable] object Debug {
diff --git a/src/library/scala/collection/parallel/mutable/ParCtrie.scala b/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala
index 470972adad..a6495161ea 100644
--- a/src/library/scala/collection/parallel/mutable/ParCtrie.scala
+++ b/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala
@@ -20,12 +20,12 @@ import scala.collection.mutable.LNode
import scala.collection.mutable.CNode
import scala.collection.mutable.SNode
import scala.collection.mutable.INode
-import scala.collection.mutable.Ctrie
-import scala.collection.mutable.CtrieIterator
+import scala.collection.mutable.ConcurrentTrieMap
+import scala.collection.mutable.ConcurrentTrieMapIterator
-/** Parallel Ctrie collection.
+/** Parallel ConcurrentTrieMap collection.
*
* It has its bulk operations parallelized, but uses the snapshot operation
* to create the splitter. This means that parallel bulk operations can be
@@ -34,24 +34,24 @@ import scala.collection.mutable.CtrieIterator
* @author Aleksandar Prokopec
* @since 2.10
*/
-final class ParCtrie[K, V] private[collection] (private val ctrie: Ctrie[K, V])
+final class ParConcurrentTrieMap[K, V] private[collection] (private val ctrie: ConcurrentTrieMap[K, V])
extends ParMap[K, V]
- with GenericParMapTemplate[K, V, ParCtrie]
- with ParMapLike[K, V, ParCtrie[K, V], Ctrie[K, V]]
- with ParCtrieCombiner[K, V]
+ with GenericParMapTemplate[K, V, ParConcurrentTrieMap]
+ with ParMapLike[K, V, ParConcurrentTrieMap[K, V], ConcurrentTrieMap[K, V]]
+ with ParConcurrentTrieMapCombiner[K, V]
with Serializable
{
- def this() = this(new Ctrie)
+ def this() = this(new ConcurrentTrieMap)
- override def mapCompanion: GenericParMapCompanion[ParCtrie] = ParCtrie
+ override def mapCompanion: GenericParMapCompanion[ParConcurrentTrieMap] = ParConcurrentTrieMap
- override def empty: ParCtrie[K, V] = ParCtrie.empty
+ override def empty: ParConcurrentTrieMap[K, V] = ParConcurrentTrieMap.empty
- protected[this] override def newCombiner = ParCtrie.newCombiner
+ protected[this] override def newCombiner = ParConcurrentTrieMap.newCombiner
override def seq = ctrie
- def splitter = new ParCtrieSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[Ctrie[K, V]], true)
+ def splitter = new ParConcurrentTrieMapSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[ConcurrentTrieMap[K, V]], true)
override def clear() = ctrie.clear()
@@ -87,11 +87,11 @@ extends ParMap[K, V]
}
}
- override def stringPrefix = "ParCtrie"
+ override def stringPrefix = "ParConcurrentTrieMap"
/* tasks */
- /** Computes Ctrie size in parallel. */
+ /** Computes ConcurrentTrieMap size in parallel. */
class Size(offset: Int, howmany: Int, array: Array[BasicNode]) extends Task[Int, Size] {
var result = -1
def leaf(prev: Option[Int]) = {
@@ -118,15 +118,15 @@ extends ParMap[K, V]
}
-private[collection] class ParCtrieSplitter[K, V](lev: Int, ct: Ctrie[K, V], mustInit: Boolean)
-extends CtrieIterator[K, V](lev, ct, mustInit)
+private[collection] class ParConcurrentTrieMapSplitter[K, V](lev: Int, ct: ConcurrentTrieMap[K, V], mustInit: Boolean)
+extends ConcurrentTrieMapIterator[K, V](lev, ct, mustInit)
with IterableSplitter[(K, V)]
{
// only evaluated if `remaining` is invoked (which is not used by most tasks)
lazy val totalsize = ct.par.size
var iterated = 0
- protected override def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new ParCtrieSplitter[K, V](_lev, _ct, _mustInit)
+ protected override def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ParConcurrentTrieMapSplitter[K, V](_lev, _ct, _mustInit)
override def shouldSplitFurther[S](coll: collection.parallel.ParIterable[S], parallelismLevel: Int) = {
val maxsplits = 3 + Integer.highestOneBit(parallelismLevel)
@@ -153,15 +153,15 @@ extends CtrieIterator[K, V](lev, ct, mustInit)
}
-/** Only used within the `ParCtrie`. */
-private[mutable] trait ParCtrieCombiner[K, V] extends Combiner[(K, V), ParCtrie[K, V]] {
+/** Only used within the `ParConcurrentTrieMap`. */
+private[mutable] trait ParConcurrentTrieMapCombiner[K, V] extends Combiner[(K, V), ParConcurrentTrieMap[K, V]] {
- def combine[N <: (K, V), NewTo >: ParCtrie[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else {
+ def combine[N <: (K, V), NewTo >: ParConcurrentTrieMap[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else {
throw new UnsupportedOperationException("This shouldn't have been called in the first place.")
- val thiz = this.asInstanceOf[ParCtrie[K, V]]
- val that = other.asInstanceOf[ParCtrie[K, V]]
- val result = new ParCtrie[K, V]
+ val thiz = this.asInstanceOf[ParConcurrentTrieMap[K, V]]
+ val that = other.asInstanceOf[ParConcurrentTrieMap[K, V]]
+ val result = new ParConcurrentTrieMap[K, V]
result ++= thiz.iterator
result ++= that.iterator
@@ -174,13 +174,13 @@ private[mutable] trait ParCtrieCombiner[K, V] extends Combiner[(K, V), ParCtrie[
}
-object ParCtrie extends ParMapFactory[ParCtrie] {
+object ParConcurrentTrieMap extends ParMapFactory[ParConcurrentTrieMap] {
- def empty[K, V]: ParCtrie[K, V] = new ParCtrie[K, V]
+ def empty[K, V]: ParConcurrentTrieMap[K, V] = new ParConcurrentTrieMap[K, V]
- def newCombiner[K, V]: Combiner[(K, V), ParCtrie[K, V]] = new ParCtrie[K, V]
+ def newCombiner[K, V]: Combiner[(K, V), ParConcurrentTrieMap[K, V]] = new ParConcurrentTrieMap[K, V]
- implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParCtrie[K, V]] = new CanCombineFromMap[K, V]
+ implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParConcurrentTrieMap[K, V]] = new CanCombineFromMap[K, V]
}
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index 0c7772cd07..38ca89b98b 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -72,10 +72,11 @@ private[scala] trait PropertiesTrait {
* it is an RC, Beta, etc. or was built from source, or if the version
* cannot be read.
*/
- val releaseVersion = scalaPropOrNone("version.number") flatMap { s =>
- val segments = s split '.'
- if (segments.size == 4 && segments.last == "final") Some(segments take 3 mkString ".") else None
- }
+ val releaseVersion =
+ for {
+ v <- scalaPropOrNone("maven.version.number")
+ if !(v endsWith "-SNAPSHOT")
+ } yield v
/** The development Scala version, if this is not a final release.
* The precise contents are not guaranteed, but it aims to provide a
@@ -85,15 +86,12 @@ private[scala] trait PropertiesTrait {
* @return Some(version) if this is a non-final version, None if this
* is a final release or the version cannot be read.
*/
- val developmentVersion = scalaPropOrNone("version.number") flatMap { s =>
- val segments = s split '.'
- if (segments.isEmpty || segments.last == "final")
- None
- else if (segments.last startsWith "r")
- Some(s takeWhile (ch => ch != '-')) // Cutting e.g. 2.10.0.r24774-b20110417125606 to 2.10.0.r24774
- else
- Some(s)
- }
+ val developmentVersion =
+ for {
+ v <- scalaPropOrNone("maven.version.number")
+ if v endsWith "-SNAPSHOT"
+ ov <- scalaPropOrNone("version.number")
+ } yield ov
/** Either the development or release version if known, otherwise
* the empty string.
diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala
index df52b34f87..cc244a5b88 100644..100755
--- a/src/library/scala/xml/Elem.scala
+++ b/src/library/scala/xml/Elem.scala
@@ -17,8 +17,18 @@ package scala.xml
* @author Burak Emir <bqe@google.com>
*/
object Elem {
- def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*) =
- new Elem(prefix, label, attributes, scope, child:_*)
+ /** Build an Elem, setting its minimizeEmpty property to <code>true</code> if it has no children. Note that this
+ * default may not be exactly what you want, as some XML dialects don't permit some elements to be minimized.
+ *
+ * @deprecated This factory method is retained for backward compatibility; please use the other one, with which you
+ * can specify your own preference for minimizeEmpty.
+ */
+ @deprecated
+ def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*): Elem =
+ apply(prefix, label, attributes, scope, child.isEmpty, child: _*)
+
+ def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, child: Node*): Elem =
+ new Elem(prefix,label,attributes,scope, minimizeEmpty, child:_*)
def unapplySeq(n: Node) = n match {
case _: SpecialNode | _: Group => None
@@ -29,11 +39,13 @@ object Elem {
/** The case class `Elem` extends the `Node` class,
* providing an immutable data object representing an XML element.
*
- * @param prefix namespace prefix (may be null, but not the empty string)
- * @param label the element name
- * @param attribute the attribute map
- * @param scope the scope containing the namespace bindings
- * @param child the children of this node
+ * @param prefix namespace prefix (may be null, but not the empty string)
+ * @param label the element name
+ * @param attributes1 the attribute map
+ * @param scope the scope containing the namespace bindings
+ * @param minimizeEmpty `true` if this element should be serialized as minimized (i.e. "&lt;el/&gt;") when
+ * empty; `false` if it should be written out in long form.
+ * @param child the children of this node
*
* Copyright 2008 Google Inc. All Rights Reserved.
* @author Burak Emir <bqe@google.com>
@@ -43,9 +55,15 @@ class Elem(
val label: String,
attributes1: MetaData,
override val scope: NamespaceBinding,
+ val minimizeEmpty: Boolean,
val child: Node*)
extends Node with Serializable
{
+ @deprecated("This constructor is retained for backward compatibility. Please use the primary constructor, which lets you specify your own preference for `minimizeEmpty`.", "2.10")
+ def this(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*) = {
+ this(prefix, label, attributes, scope, child.isEmpty, child: _*)
+ }
+
final override def doCollectNamespaces = true
final override def doTransform = true
@@ -83,8 +101,9 @@ extends Node with Serializable
label: String = this.label,
attributes: MetaData = this.attributes,
scope: NamespaceBinding = this.scope,
+ minimizeEmpty: Boolean = this.minimizeEmpty,
child: Seq[Node] = this.child.toSeq
- ): Elem = Elem(prefix, label, attributes, scope, child: _*)
+ ): Elem = Elem(prefix, label, attributes, scope, minimizeEmpty, child: _*)
/** Returns concatenation of `text(n)` for each child `n`.
*/
diff --git a/src/library/scala/xml/Node.scala b/src/library/scala/xml/Node.scala
index 2ead18fe08..02e34e1bdc 100644..100755
--- a/src/library/scala/xml/Node.scala
+++ b/src/library/scala/xml/Node.scala
@@ -159,7 +159,7 @@ abstract class Node extends NodeSeq {
* @return ...
*/
def buildString(stripComments: Boolean): String =
- Utility.toXML(this, stripComments = stripComments).toString
+ Utility.serialize(this, stripComments = stripComments).toString
/**
* Same as `toString('''false''')`.
diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/library/scala/xml/PrettyPrinter.scala
index ea39b51352..64dbd00f2f 100644..100755
--- a/src/library/scala/xml/PrettyPrinter.scala
+++ b/src/library/scala/xml/PrettyPrinter.scala
@@ -161,7 +161,7 @@ class PrettyPrinter(width: Int, step: Int) {
case _ =>
val test = {
val sb = new StringBuilder()
- Utility.toXML(node, pscope, sb, false)
+ Utility.serialize(node, pscope, sb, false)
if (doPreserve(node)) sb.toString
else TextBuffer.fromString(sb.toString).toText(0).data
}
diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala
index fc20b892b9..9f944c0e92 100644..100755
--- a/src/library/scala/xml/Utility.scala
+++ b/src/library/scala/xml/Utility.scala
@@ -181,6 +181,13 @@ object Utility extends AnyRef with parsing.TokenTests {
// sb.toString()
// }
+ /**
+ * Serialize the provided Node to the provided StringBuilder.
+ * <p/>
+ * Note that calling this source-compatible method will result in the same old, arguably almost universally unwanted,
+ * behaviour.
+ */
+ @deprecated("Please use `serialize` instead and specify a `minimizeTags` parameter", "2.10")
def toXML(
x: Node,
pscope: NamespaceBinding = TopScope,
@@ -190,29 +197,51 @@ object Utility extends AnyRef with parsing.TokenTests {
preserveWhitespace: Boolean = false,
minimizeTags: Boolean = false): StringBuilder =
{
+ serialize(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, if (minimizeTags) MinimizeMode.Always else MinimizeMode.Never)
+ }
+
+ /**
+ * Serialize an XML Node to a StringBuilder.
+ *
+ * This is essentially a minor rework of `toXML` that can't have the same name due to an unfortunate
+ * combination of named/default arguments and overloading.
+ *
+ * @todo use a Writer instead
+ */
+ def serialize(
+ x: Node,
+ pscope: NamespaceBinding = TopScope,
+ sb: StringBuilder = new StringBuilder,
+ stripComments: Boolean = false,
+ decodeEntities: Boolean = true,
+ preserveWhitespace: Boolean = false,
+ minimizeTags: MinimizeMode.Value = MinimizeMode.Default): StringBuilder =
+ {
x match {
- case c: Comment => if (!stripComments) c buildString sb else sb
- case x: SpecialNode => x buildString sb
- case g: Group =>
- g.nodes foreach {toXML(_, x.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)}
- sb
- case _ =>
+ case c: Comment if !stripComments => c buildString sb
+ case s: SpecialNode => s buildString sb
+ case g: Group => for (c <- g.nodes) serialize(c, g.scope, sb, minimizeTags = minimizeTags) ; sb
+ case el: Elem =>
// print tag with namespace declarations
sb.append('<')
- x.nameToString(sb)
- if (x.attributes ne null) x.attributes.buildString(sb)
- x.scope.buildString(sb, pscope)
- if (x.child.isEmpty && minimizeTags) {
+ el.nameToString(sb)
+ if (el.attributes ne null) el.attributes.buildString(sb)
+ el.scope.buildString(sb, pscope)
+ if (el.child.isEmpty &&
+ (minimizeTags == MinimizeMode.Always ||
+ (minimizeTags == MinimizeMode.Default && el.minimizeEmpty)))
+ {
// no children, so use short form: <xyz .../>
- sb.append(" />")
+ sb.append("/>")
} else {
// children, so use long form: <xyz ...>...</xyz>
sb.append('>')
- sequenceToXML(x.child, x.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
+ sequenceToXML(el.child, el.scope, sb, stripComments)
sb.append("</")
- x.nameToString(sb)
+ el.nameToString(sb)
sb.append('>')
}
+ case _ => throw new IllegalArgumentException("Don't know how to serialize a " + x.getClass.getName)
}
}
@@ -223,20 +252,20 @@ object Utility extends AnyRef with parsing.TokenTests {
stripComments: Boolean = false,
decodeEntities: Boolean = true,
preserveWhitespace: Boolean = false,
- minimizeTags: Boolean = false): Unit =
+ minimizeTags: MinimizeMode.Value = MinimizeMode.Default): Unit =
{
if (children.isEmpty) return
else if (children forall isAtomAndNotText) { // add space
val it = children.iterator
val f = it.next
- toXML(f, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
+ serialize(f, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
while (it.hasNext) {
val x = it.next
sb.append(' ')
- toXML(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
+ serialize(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
}
}
- else children foreach { toXML(_, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) }
+ else children foreach { serialize(_, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) }
}
/**
diff --git a/src/library/scala/xml/XML.scala b/src/library/scala/xml/XML.scala
index bc3033d081..4beba91899 100644..100755
--- a/src/library/scala/xml/XML.scala
+++ b/src/library/scala/xml/XML.scala
@@ -26,6 +26,21 @@ object Source
def fromSysId(sysID: String) = new InputSource(sysID)
def fromString(string: String) = fromReader(new StringReader(string))
}
+
+/**
+ * Governs how empty elements (i.e. those without child elements) should be serialized.
+ */
+object MinimizeMode extends Enumeration {
+ /** Minimize empty tags if they were originally empty when parsed, or if they were constructed with [[scala.xml.Elem]]`#minimizeEmpty` == true */
+ val Default = Value
+
+ /** Always minimize empty tags. Note that this may be problematic for XHTML, in which case [[scala.xml.Xhtml]]`#toXhtml` should be used instead. */
+ val Always = Value
+
+ /** Never minimize empty tags. */
+ val Never = Value
+}
+
import Source._
/** The object `XML` provides constants, and functions to load
@@ -83,10 +98,10 @@ object XML extends XMLLoader[Elem]
* @param xmlDecl if true, write xml declaration
* @param doctype if not null, write doctype declaration
*/
- final def write(w: java.io.Writer, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType) {
+ final def write(w: java.io.Writer, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType, minimizeTags: MinimizeMode.Value = MinimizeMode.Default) {
/* TODO: optimize by giving writer parameter to toXML*/
if (xmlDecl) w.write("<?xml version='1.0' encoding='" + enc + "'?>\n")
if (doctype ne null) w.write( doctype.toString() + "\n")
- w.write(Utility.toXML(node).toString)
+ w.write(Utility.serialize(node, minimizeTags = minimizeTags).toString)
}
}
diff --git a/src/library/scala/xml/factory/Binder.scala b/src/library/scala/xml/factory/Binder.scala
index a8b0ed585b..b4fe153bd8 100644..100755
--- a/src/library/scala/xml/factory/Binder.scala
+++ b/src/library/scala/xml/factory/Binder.scala
@@ -43,13 +43,13 @@ abstract class Binder(val preserveWS: Boolean) extends ValidatingMarkupHandler {
result &+ text(0, x.data)
case x:EntityRef =>
result &+ entityRef(0, x.entityName)
- case _ =>
- elemStart(0, n.prefix, n.label, n.attributes, n.scope)
+ case x:Elem =>
+ elemStart(0, x.prefix, x.label, x.attributes, x.scope)
val old = result
result = new NodeBuffer()
- for (m <- n.child) traverse(m)
- result = old &+ elem(0, n.prefix, n.label, n.attributes, n.scope, NodeSeq.fromSeq(result)).toList;
- elemEnd(0, n.prefix, n.label)
+ for (m <- x.child) traverse(m)
+ result = old &+ elem(0, x.prefix, x.label, x.attributes, x.scope, x.minimizeEmpty, NodeSeq.fromSeq(result)).toList;
+ elemEnd(0, x.prefix, x.label)
}
final def validate(n: Node): Node = {
diff --git a/src/library/scala/xml/parsing/ConstructingHandler.scala b/src/library/scala/xml/parsing/ConstructingHandler.scala
index 60c19138c3..7e61674682 100644..100755
--- a/src/library/scala/xml/parsing/ConstructingHandler.scala
+++ b/src/library/scala/xml/parsing/ConstructingHandler.scala
@@ -21,8 +21,8 @@ abstract class ConstructingHandler extends MarkupHandler
val preserveWS: Boolean
def elem(pos: Int, pre: String, label: String, attrs: MetaData,
- pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq =
- Elem(pre, label, attrs, pscope, nodes:_*)
+ pscope: NamespaceBinding, empty: Boolean, nodes: NodeSeq): NodeSeq =
+ Elem(pre, label, attrs, pscope, empty, nodes:_*)
def procInstr(pos: Int, target: String, txt: String) =
ProcInstr(target, txt)
diff --git a/src/library/scala/xml/parsing/DefaultMarkupHandler.scala b/src/library/scala/xml/parsing/DefaultMarkupHandler.scala
index 699c5b2b5f..e0258ba781 100644..100755
--- a/src/library/scala/xml/parsing/DefaultMarkupHandler.scala
+++ b/src/library/scala/xml/parsing/DefaultMarkupHandler.scala
@@ -16,7 +16,7 @@ package parsing
abstract class DefaultMarkupHandler extends MarkupHandler {
def elem(pos: Int, pre: String, label: String, attrs: MetaData,
- scope:NamespaceBinding, args: NodeSeq) = NodeSeq.Empty
+ scope:NamespaceBinding, empty: Boolean, args: NodeSeq) = NodeSeq.Empty
def procInstr(pos: Int, target: String, txt: String) = NodeSeq.Empty
diff --git a/src/library/scala/xml/parsing/MarkupHandler.scala b/src/library/scala/xml/parsing/MarkupHandler.scala
index 87e785a98f..83db2f177d 100644..100755
--- a/src/library/scala/xml/parsing/MarkupHandler.scala
+++ b/src/library/scala/xml/parsing/MarkupHandler.scala
@@ -75,10 +75,11 @@ abstract class MarkupHandler extends Logged
* @param pre the prefix
* @param label the local name
* @param attrs the attributes (metadata)
+ * @param empty `true` if the element was previously empty; `false` otherwise.
* @param args the children of this element
* @return ...
*/
- def elem(pos: Int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding, args: NodeSeq): NodeSeq
+ def elem(pos: Int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding, empty: Boolean, args: NodeSeq): NodeSeq
/** callback method invoked by MarkupParser after parsing PI.
*/
diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/library/scala/xml/parsing/MarkupParser.scala
index 1de08b3025..32feaa2209 100644..100755
--- a/src/library/scala/xml/parsing/MarkupParser.scala
+++ b/src/library/scala/xml/parsing/MarkupParser.scala
@@ -569,7 +569,7 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
tmp
}
}
- val res = handle.elem(pos, pre, local, aMap, scope, ts)
+ val res = handle.elem(pos, pre, local, aMap, scope, ts == NodeSeq.Empty, ts)
handle.elemEnd(pos, pre, local)
res
}
diff --git a/src/library/scala/xml/pull/XMLEventReader.scala b/src/library/scala/xml/pull/XMLEventReader.scala
index f84d91d138..c764d042c8 100755
--- a/src/library/scala/xml/pull/XMLEventReader.scala
+++ b/src/library/scala/xml/pull/XMLEventReader.scala
@@ -81,7 +81,7 @@ extends collection.AbstractIterator[XMLEvent]
// memory usage optimization return one <ignore/> for top level to satisfy
// MarkupParser.document() otherwise NodeSeq.Empty
private var ignoreWritten = false
- final def elem(pos: Int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq =
+ final def elem(pos: Int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, empty: Boolean, nodes: NodeSeq): NodeSeq =
if (level == 1 && !ignoreWritten) {ignoreWritten = true; <ignore/> } else NodeSeq.Empty
def procInstr(pos: Int, target: String, txt: String) = setEvent(EvProcInstr(target, txt))