Skip to content
This repository was archived by the owner on Feb 20, 2019. It is now read-only.

Commit a7fd483

Browse files
committed
Merge pull request #159 from phaller/topic/debug
Ignore known size when generating pickler for Externalizable
2 parents b043e3d + e8fb856 commit a7fd483

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

core/src/main/scala/pickling/Macros.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ trait PicklerMacros extends Macro {
3333
if (fir.isPublic) q"picklee.${newTermName(fir.name)}"
3434
else reflectively("picklee", fir)(fm => q"$fm.get.asInstanceOf[${fir.tpe}]").head //TODO: don't think it's possible for this to return an empty list, so head should be OK
3535

36+
def computeKnownSizeOfObjectOutput(cir: ClassIR): (Option[Tree], List[Tree]) = {
37+
// for now we cannot compute a fixed size for ObjectOutputs
38+
// in the future this will be a possible optimization (faster Externalizables)
39+
None -> List()
40+
}
41+
3642
// this exists so as to provide as much information as possible about the size of the object
3743
// to-be-pickled to the picklers at runtime. In the case of the binary format for example,
3844
// this allows us to remove array copying and allocation bottlenecks
@@ -45,6 +51,11 @@ trait PicklerMacros extends Macro {
4551
if (elTpe.isEffectivelyPrimitive) Some(q"picklee.length * ${primitiveSizes(elTpe)} + 4")
4652
else None
4753
knownSize -> Nil
54+
} else if (tpe <:< typeOf[java.io.Externalizable]) {
55+
computeKnownSizeOfObjectOutput(cir) match {
56+
case (None, lst) => None -> List()
57+
case _ => c.abort(c.enclosingPosition, "not implemented")
58+
}
4859
} else {
4960
val possibleSizes: List[(Option[Tree], Option[Tree])] = cir.fields map {
5061
case fld if fld.tpe.isEffectivelyPrimitive =>

core/src/test/scala/pickling/run/externalizable.scala

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package scala.pickling.externalizable
22

33
import org.scalatest.FunSuite
44
import scala.pickling._
5-
import json._
65
import java.io.{Externalizable, IOException, ObjectInput, ObjectOutput}
76
import java.nio.ByteBuffer
87

@@ -111,11 +110,63 @@ object StorageLevel {
111110
}
112111
}
113112

113+
class StorageLevel2 (
114+
private var useDisk_ : Boolean,
115+
private var useMemory_ : Boolean,
116+
private var deserialized_ : Boolean,
117+
private var replication_ : Int)
118+
extends Externalizable {
119+
120+
def toInt: Int = {
121+
var ret = 0
122+
if (useDisk_) {
123+
ret |= 4
124+
}
125+
if (useMemory_) {
126+
ret |= 2
127+
}
128+
if (deserialized_) {
129+
ret |= 1
130+
}
131+
ret
132+
}
133+
134+
override def writeExternal(out: ObjectOutput) {
135+
out.writeByte(toInt)
136+
out.writeByte(replication_)
137+
}
138+
139+
override def readExternal(in: ObjectInput) {
140+
val flags = in.readByte()
141+
useDisk_ = (flags & 4) != 0
142+
useMemory_ = (flags & 2) != 0
143+
deserialized_ = (flags & 1) != 0
144+
replication_ = in.readByte()
145+
}
146+
147+
override def equals(other: Any): Boolean =
148+
other.isInstanceOf[StorageLevel2] && {
149+
val o = other.asInstanceOf[StorageLevel2]
150+
o.useDisk_ == useDisk_ && o.useMemory_ == useMemory_ && o.deserialized_ == deserialized_ && o.replication_ == replication_
151+
}
152+
}
153+
114154
class ExternalizableTest extends FunSuite {
115155
test("main") {
156+
import json._
157+
116158
val sl = StorageLevel.MEMORY_ONLY_SER
117159
val pickle: JSONPickle = sl.pickle
118160
val up = pickle.unpickle[StorageLevel]
119161
assert(sl == up)
120162
}
163+
164+
test("Externalizable pickler must not use knownSize") {
165+
import binary._
166+
167+
val obj = new StorageLevel2(false, true, false, 1)
168+
val p = obj.pickle
169+
val up = p.unpickle[StorageLevel2]
170+
assert(up == obj)
171+
}
121172
}

0 commit comments

Comments
 (0)