Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre-registering certain standard classes to better support long term persistence scenarios #303

Merged
merged 32 commits into from
Feb 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a821f7f
Update to latest scala versions
gdiet Jan 9, 2018
24a3b7c
Fix for deprecation warning
gdiet Jan 9, 2018
0924a71
Fixed typo in spec and removed unused import
gdiet Jan 9, 2018
39afb4a
Added test to ensure long term stability of registration IDs
gdiet Jan 9, 2018
2cc50bf
Renamed spec
gdiet Jan 9, 2018
234f737
Require registration for empty set
gdiet Jan 9, 2018
de36cbe
Registration for empty set
gdiet Jan 9, 2018
af986af
Require registration for hash sets
gdiet Jan 9, 2018
8266b03
Registration for hash sets
gdiet Jan 9, 2018
65e92ce
Require registration for list set
gdiet Jan 9, 2018
d7c4d0e
Registration for list set
gdiet Jan 9, 2018
0e163b7
Require registration for list, queue, range
gdiet Jan 9, 2018
6d27088
Registration for list, queue, range
gdiet Jan 9, 2018
71ab736
Require registration for hash maps, list maps, None, and arrays
gdiet Jan 10, 2018
38dbd75
Registration for hash maps, list maps, None, and arrays
gdiet Jan 10, 2018
c55a179
Require registration for wrapped arrays
gdiet Jan 10, 2018
45eb733
Registration for wrapped arrays
gdiet Jan 10, 2018
8c48dd7
Require registration for wrapped strings
gdiet Jan 10, 2018
8e8cde6
Registration for wrapped strings
gdiet Jan 10, 2018
35cc7cd
Registration for streams
gdiet Jan 11, 2018
01e75fb
Registration for TreeSet and TreeMap
gdiet Jan 15, 2018
98d6da9
Added missing registrations to test
gdiet Jan 15, 2018
0f9a268
Registration for the empty map
gdiet Jan 18, 2018
4533516
Added missing registrations to test
gdiet Jan 23, 2018
1bb412d
found a problem when serializing streams
gdiet Jan 23, 2018
d2a6941
fixed stream serializer
gdiet Jan 24, 2018
eb229fa
finished test examples
gdiet Jan 24, 2018
a327ed2
bumping up scala versions for travis ci
gdiet Feb 1, 2018
0b90a4e
revert ScalaKryoInstantiator to redesign changes in backward compatible
gdiet Feb 2, 2018
6d25303
introduced 0.9.2 compatibility registrar
gdiet Feb 2, 2018
810bdeb
re-added registrations, this time with the backward compatibility layer
gdiet Feb 2, 2018
1960f57
improved scaladoc for changed and new stuff
gdiet Feb 2, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ language: scala
sudo: false
matrix:
include:
- scala: 2.10.6
- scala: 2.10.7
script: ./sbt ++$TRAVIS_SCALA_VERSION clean test mimaReportBinaryIssues

- scala: 2.11.8
- scala: 2.11.12
jdk: oraclejdk8
script: ./sbt ++$TRAVIS_SCALA_VERSION clean coverage test coverageReport mimaReportBinaryIssues
after_success:
- bash <(curl -s https://codecov.io/bash)

- scala: 2.12.1
- scala: 2.12.4
jdk: oraclejdk8
script: ./sbt "+++$TRAVIS_SCALA_VERSION clean" "+++$TRAVIS_SCALA_VERSION test" # "+++$TRAVIS_SCALA_VERSION mimaReportBinaryIssues"

Expand Down
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ val scroogeVersion = "4.12.0"

val sharedSettings = mimaDefaultSettings ++ scalariformSettings ++ Seq(
organization := "com.twitter",
scalaVersion := "2.11.8",
crossScalaVersions := Seq("2.10.6", "2.11.8", "2.12.1"),
scalaVersion := "2.11.12",
crossScalaVersions := Seq("2.10.7", "2.11.12", "2.12.4"),
scalacOptions ++= Seq("-unchecked", "-deprecation"),
ScalariformKeys.preferences := formattingPreferences,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package com.twitter.chill
class ClassManifestSerializer[T] extends KSerializer[ClassManifest[T]] {

def write(kser: Kryo, out: Output, obj: ClassManifest[T]) {
kser.writeObject(out, obj.erasure)
kser.writeObject(out, obj.runtimeClass)
}

def read(kser: Kryo, in: Input, cls: Class[ClassManifest[T]]): ClassManifest[T] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,15 @@ limitations under the License.

package com.twitter.chill

import scala.collection.immutable.{
BitSet,
HashSet,
ListSet,
NumericRange,
Range,
SortedSet,
SortedMap,
ListMap,
HashMap,
Queue
}

import scala.collection.mutable.{
WrappedArray,
BitSet => MBitSet,
Map => MMap,
HashMap => MHashMap,
Set => MSet,
HashSet => MHashSet,
ListBuffer,
Queue => MQueue,
Buffer
}

import scala.collection.immutable.{ BitSet, HashMap, HashSet, ListMap, ListSet, NumericRange, Queue, Range, SortedMap, SortedSet, TreeMap, TreeSet, WrappedString }
import scala.collection.mutable.{ Buffer, ListBuffer, WrappedArray, BitSet => MBitSet, HashMap => MHashMap, HashSet => MHashSet, Map => MMap, Queue => MQueue, Set => MSet }
import scala.util.matching.Regex

import com.twitter.chill.java.{ Java8ClosureRegistrar, PackageRegistrar }
import _root_.java.io.Serializable

import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.reflect.ClassTag

/**
Expand Down Expand Up @@ -99,6 +77,10 @@ class ScalaKryoInstantiator extends EmptyScalaKryoInstantiator {
}
}

/**
* Note that additional scala collections registrations are provided by [[AllScalaRegistrar]]. They have not been
* included in this registrar for backwards compatibility reasons.
*/
class ScalaCollectionsRegistrar extends IKryoRegistrar {
def apply(newK: Kryo) {
// for binary compat this is here, but could be moved to RichKryo
Expand Down Expand Up @@ -177,14 +159,11 @@ class JavaWrapperCollectionRegistrar extends IKryoRegistrar {
}
}

/** Registers all the scala (and java) serializers we have */
class AllScalaRegistrar extends IKryoRegistrar {
/** Registrar for everything that was registered in chill 0.9.2 - included for backwards compatibility. */
class AllScalaRegistrar_0_9_2 extends IKryoRegistrar {
def apply(k: Kryo) {
val col = new ScalaCollectionsRegistrar
col(k)

val jcol = new JavaWrapperCollectionRegistrar
jcol(k)
new ScalaCollectionsRegistrar()(k)
new JavaWrapperCollectionRegistrar()(k)

// Register all 22 tuple serializers and specialized serializers
ScalaTupleSerialization.register(k)
Expand All @@ -205,3 +184,67 @@ class AllScalaRegistrar extends IKryoRegistrar {
new Java8ClosureRegistrar()(k)
}
}

/**
* Registers all the scala (and java) serializers we have. The registrations are designed to cover most of
* scala.collecion.immutable, so they can be used in long term persistence scenarios that run with
* setRegistrationRequired(true).
*/
class AllScalaRegistrar extends IKryoRegistrar {
def apply(k: Kryo) {
new AllScalaRegistrar_0_9_2()(k)

k.registerClasses(Seq(
classOf[Array[Byte]],
classOf[Array[Short]],
classOf[Array[Int]],
classOf[Array[Long]],
classOf[Array[Float]],
classOf[Array[Double]],
classOf[Array[Boolean]],
classOf[Array[Char]],
classOf[Array[String]],
classOf[Array[Any]],
classOf[Class[_]], // needed for the WrappedArraySerializer
classOf[Any], // needed for scala.collection.mutable.WrappedArray$ofRef
mutable.WrappedArray.make(Array[Byte]()).getClass,
mutable.WrappedArray.make(Array[Short]()).getClass,
mutable.WrappedArray.make(Array[Int]()).getClass,
mutable.WrappedArray.make(Array[Long]()).getClass,
mutable.WrappedArray.make(Array[Float]()).getClass,
mutable.WrappedArray.make(Array[Double]()).getClass,
mutable.WrappedArray.make(Array[Boolean]()).getClass,
mutable.WrappedArray.make(Array[Char]()).getClass,
mutable.WrappedArray.make(Array[String]()).getClass,
None.getClass,
classOf[Queue[_]],
Nil.getClass,
classOf[::[_]],
classOf[Range],
classOf[WrappedString],
classOf[TreeSet[_]],
classOf[TreeMap[_, _]],
// The most common orderings for TreeSet and TreeMap
Ordering.Byte.getClass,
Ordering.Short.getClass,
Ordering.Int.getClass,
Ordering.Long.getClass,
Ordering.Float.getClass,
Ordering.Double.getClass,
Ordering.Boolean.getClass,
Ordering.Char.getClass,
Ordering.String.getClass))
.forConcreteTraversableClass(Set[Any]())
.forConcreteTraversableClass(ListSet[Any]())
.forConcreteTraversableClass(ListSet[Any]('a))
.forConcreteTraversableClass(HashSet[Any]())
.forConcreteTraversableClass(HashSet[Any]('a))
.forConcreteTraversableClass(Map[Any, Any]())
.forConcreteTraversableClass(HashMap())
.forConcreteTraversableClass(HashMap('a -> 'a))
.forConcreteTraversableClass(ListMap())
.forConcreteTraversableClass(ListMap('a -> 'a))
k.register(classOf[Stream.Cons[_]], new StreamSerializer[Any])
k.register(Stream.empty[Any].getClass)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.twitter.chill

class StreamSerializer[T]() extends KSerializer[Stream[T]] {
def write(kser: Kryo, out: Output, stream: Stream[T]) {
kser.writeClassAndObject(out, stream.toList)
}

def read(kser: Kryo, in: Input, cls: Class[Stream[T]]): Stream[T] = {
kser.readClassAndObject(in).asInstanceOf[List[T]].toStream
}
}
3 changes: 1 addition & 2 deletions chill-scala/src/test/scala/com/twitter/chill/KryoSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import org.scalatest.matchers.{ Matcher, MatchResult }
import scala.collection.immutable.{ SortedSet, BitSet, ListSet, HashSet, SortedMap, ListMap, HashMap }
import scala.collection.mutable.{ ArrayBuffer => MArrayBuffer, BitSet => MBitSet, HashMap => MHashMap }
import _root_.java.util.PriorityQueue
import _root_.java.util.Locale
import scala.collection.mutable
import scala.collection.JavaConverters._
import scala.reflect._
Expand Down Expand Up @@ -55,7 +54,7 @@ case class Foo(m1: Map[String, Int], m2: Map[String, Seq[String]])
class KryoSpec extends WordSpec with Matchers with BaseProperties {

def roundtrip[T] = new Matcher[T] {
def apply(t: T) = MatchResult(rtEquiv(t), "successfull serialization roundtrip for " + t, "failed serialization roundtrip for " + t)
def apply(t: T) = MatchResult(rtEquiv(t), "successful serialization roundtrip for " + t, "failed serialization roundtrip for " + t)
}

def getKryo = KryoSerializer.registered.newKryo
Expand Down
Loading