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

Commit 61d9f19

Browse files
committed
Merge pull request #199 from scala/fastbinary
Adding a new fast binary format, principle: reduce array allocations
2 parents 882ecb0 + b338a38 commit 61d9f19

File tree

10 files changed

+949
-22
lines changed

10 files changed

+949
-22
lines changed

core/src/main/scala/pickling/Output.scala

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package scala.pickling
22

3+
import scala.reflect.ClassTag
4+
import scala.collection.mutable.ArrayBuffer
35
import java.io.OutputStream
46

57
trait Output[T] {
@@ -10,23 +12,18 @@ trait Output[T] {
1012

1113
}
1214

13-
// and then demand Output[Nothing] in the abstract PickleFormat
14-
// in JSON we can demand Output[String], since Output[Nothing] <: Output[String]
15-
16-
import scala.reflect.ClassTag
17-
1815
class OutputStreamOutput(out: OutputStream) extends ArrayOutput[Byte] {
1916
def result(): Array[Byte] =
20-
null
17+
null
2118

2219
def +=(obj: Byte) =
23-
out.write(obj.asInstanceOf[Int])
20+
out.write(obj.asInstanceOf[Int])
2421

2522
def put(obj: Array[Byte]): this.type = {
26-
out.write(obj)
27-
this
23+
out.write(obj)
24+
this
2825
}
29-
}
26+
}
3027

3128
// Array output with a few more methods for performance
3229
abstract class ArrayOutput[T: ClassTag] extends Output[Array[T]] {
@@ -40,7 +37,6 @@ abstract class ArrayOutput[T: ClassTag] extends Output[Array[T]] {
4037
this.put(arr)
4138
}
4239

43-
import scala.collection.mutable.ArrayBuffer
4440

4541
class ByteArrayBufferOutput extends ArrayOutput[Byte] {
4642

@@ -100,5 +96,4 @@ class StringOutput extends Output[String] {
10096
}
10197

10298
override def toString = buf.toString
103-
10499
}

core/src/main/scala/pickling/binary/BinaryPickleFormat.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ package binary {
535535
def endCollection(): Unit = { /* do nothing */ }
536536
}
537537

538-
class BinaryPickleFormat extends PickleFormat {
538+
trait Constants {
539539
val NULL_TAG : Byte = -2
540540
val REF_TAG : Byte = -3
541541
val UNIT_TAG : Byte = -4
@@ -567,7 +567,9 @@ package binary {
567567

568568
val primitives = Set(KEY_NULL, KEY_REF, KEY_BYTE, KEY_SHORT, KEY_CHAR, KEY_INT, KEY_LONG, KEY_BOOLEAN, KEY_FLOAT, KEY_DOUBLE, KEY_UNIT, KEY_STRING, KEY_ARRAY_BYTE, KEY_ARRAY_SHORT, KEY_ARRAY_CHAR, KEY_ARRAY_INT, KEY_ARRAY_LONG, KEY_ARRAY_BOOLEAN, KEY_ARRAY_FLOAT, KEY_ARRAY_DOUBLE)
569569
val nullablePrimitives = Set(KEY_NULL, KEY_STRING, KEY_ARRAY_BYTE, KEY_ARRAY_SHORT, KEY_ARRAY_CHAR, KEY_ARRAY_INT, KEY_ARRAY_LONG, KEY_ARRAY_BOOLEAN, KEY_ARRAY_FLOAT, KEY_ARRAY_DOUBLE)
570+
}
570571

572+
class BinaryPickleFormat extends PickleFormat with Constants {
571573
type PickleType = BinaryPickle
572574
type OutputType = ArrayOutput[Byte]
573575
def createBuilder() = new BinaryPickleBuilder(this, null)

core/src/main/scala/pickling/binary/Util.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -359,17 +359,17 @@ package binary {
359359
object UnsafeMemory {
360360
import sun.misc.Unsafe
361361

362-
private[binary] val unsafe: Unsafe =
362+
private[pickling] val unsafe: Unsafe =
363363
scala.concurrent.util.Unsafe.instance
364364

365-
private[binary] val byteArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Byte]])
366-
private[binary] val shortArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Short]])
367-
private[binary] val intArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Int]])
368-
private[binary] val longArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Long]])
369-
private[binary] val floatArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Float]])
370-
private[binary] val doubleArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Double]])
371-
private[binary] val charArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Char]])
372-
private[binary] val booleanArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Boolean]])
365+
private[pickling] val byteArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Byte]])
366+
private[pickling] val shortArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Short]])
367+
private[pickling] val intArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Int]])
368+
private[pickling] val longArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Long]])
369+
private[pickling] val floatArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Float]])
370+
private[pickling] val doubleArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Double]])
371+
private[pickling] val charArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Char]])
372+
private[pickling] val booleanArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Boolean]])
373373

374374
def putInt(arr: Array[Byte], i: Int, value: Int): Unit = {
375375
unsafe.putInt(arr, byteArrayOffset + i, value)

0 commit comments

Comments
 (0)