summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/immutable/List.scala
diff options
context:
space:
mode:
authorAleksandar Prokopec <axel22@gmail.com>2013-02-07 15:52:40 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-02-07 16:09:38 -0800
commitfa3b8040ebfedc721a538476be28a6217f1dec56 (patch)
treef1932e37763486ef46195012f163f6b9c7d0c831 /src/library/scala/collection/immutable/List.scala
parent033c6635b4ac03b9e6f335a76dabb65f1f0296cd (diff)
downloadscala-fa3b8040ebfedc721a538476be28a6217f1dec56.tar.gz
scala-fa3b8040ebfedc721a538476be28a6217f1dec56.tar.bz2
scala-fa3b8040ebfedc721a538476be28a6217f1dec56.zip
SI-6961 no structural sharing in list serialization
Revert list serialization back to what it was in 2.9.x and before. Partial revert of a6fcd70b60 e234978dfd, which fixed SI-5374. The ListBuffer part of the fix remains in place.
Diffstat (limited to 'src/library/scala/collection/immutable/List.scala')
-rw-r--r--src/library/scala/collection/immutable/List.scala33
1 files changed, 9 insertions, 24 deletions
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index 55ac3995e9..9765e7c52f 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -55,6 +55,12 @@ import java.io._
* val shorter = mainList.tail // costs nothing as it uses the same 2::1::Nil instances as mainList
* }}}
*
+ * @note The functional list is characterized by persistence and structural sharing, thus offering considerable
+ * performance and space consumption benefits in some scenarios if used correctly.
+ * However, note that objects having multiple references into the same functional list (that is,
+ * objects that rely on structural sharing), will be serialized and deserialized with multiple lists, one for
+ * each reference to it. I.e. structural sharing is lost after serialization/deserialization.
+ *
* @author Martin Odersky and others
* @version 2.8
* @since 1.0
@@ -352,25 +358,8 @@ final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extend
override def tail : List[B] = tl
override def isEmpty: Boolean = false
- private def writeObject(out: ObjectOutputStream) {
- out.writeObject(ListSerializeStart) // needed to differentiate with the legacy `::` serialization
- out.writeObject(this.hd)
- out.writeObject(this.tl)
- }
-
private def readObject(in: ObjectInputStream) {
- val obj = in.readObject()
- if (obj == ListSerializeStart) {
- this.hd = in.readObject().asInstanceOf[B]
- this.tl = in.readObject().asInstanceOf[List[B]]
- } else oldReadObject(in, obj)
- }
-
- /* The oldReadObject method exists here for compatibility reasons.
- * :: objects used to be serialized by serializing all the elements to
- * the output stream directly, but this was broken (see SI-5374).
- */
- private def oldReadObject(in: ObjectInputStream, firstObject: AnyRef) {
+ val firstObject = in.readObject()
hd = firstObject.asInstanceOf[B]
assert(hd != ListSerializeEnd)
var current: ::[B] = this
@@ -378,14 +367,14 @@ final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extend
case ListSerializeEnd =>
current.tl = Nil
return
- case a : Any =>
+ case a =>
val list : ::[B] = new ::(a.asInstanceOf[B], Nil)
current.tl = list
current = list
}
}
- private def oldWriteObject(out: ObjectOutputStream) {
+ private def writeObject(out: ObjectOutputStream) {
var xs: List[B] = this
while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail }
out.writeObject(ListSerializeEnd)
@@ -654,10 +643,6 @@ object List extends SeqFactory[List] {
}
/** Only used for list serialization */
-@SerialVersionUID(0L - 8287891243975527522L)
-private[scala] case object ListSerializeStart
-
-/** Only used for list serialization */
@SerialVersionUID(0L - 8476791151975527571L)
private[scala] case object ListSerializeEnd