Skip to content

Instantly share code, notes, and snippets.

@romix
Created June 19, 2014 06:23
Show Gist options
  • Save romix/6d20482f1e2677c1b93b to your computer and use it in GitHub Desktop.
Save romix/6d20482f1e2677c1b93b to your computer and use it in GitHub Desktop.
diff --git a/src/main/scala/com/romix/scala/serialization/kryo/ScalaCollectionsSerializer.scala b/src/main/scala/com/romix/scala/serialization/kryo/ScalaCollectionsSerializer.scala
index 60f4d75..6f37ecf 100644
--- a/src/main/scala/com/romix/scala/serialization/kryo/ScalaCollectionsSerializer.scala
+++ b/src/main/scala/com/romix/scala/serialization/kryo/ScalaCollectionsSerializer.scala
@@ -19,6 +19,7 @@ package com.romix.scala.serialization.kryo
import scala.collection.Traversable
import scala.collection.Set
import scala.collection.SortedSet
+import scala.collection.immutable.{Set=>ISet}
import java.lang.reflect.Constructor
import com.esotericsoftware.kryo.Kryo
@@ -58,28 +59,40 @@ class ScalaCollectionSerializer ( ) extends Serializer[Traversable[_]] {
}
class ScalaSetSerializer ( ) extends Serializer[Set[_]] {
- var class2constuctor = Map[Class[_], Constructor[_]]()
+ var isSortedSet = false
+ var constr: Constructor[_] = null
+ var emptyColl: Set[Any] = null
+ var isImmutableSet = false
+ var isInitialized = false
+
+ private[this] def init(kryo:Kryo, typ: Class[Set[_]]) = {
+ if (!isInitialized) {
+ isInitialized = true
+ isSortedSet = classOf[SortedSet[_]].isAssignableFrom(typ)
+ isImmutableSet = classOf[ISet[_]].isAssignableFrom(typ)
+ try {
+ constr = typ.getDeclaredConstructor(classOf[scala.math.Ordering[_]])
+ } catch {
+ case _: Throwable => if (isImmutableSet) emptyColl = kryo.newInstance(typ).asInstanceOf[Set[Any]].empty
+ }
+ }
+ }
+
override def read(kryo: Kryo, input: Input, typ: Class[Set[_]]): Set[_] = {
val len = input.readInt(true)
+ init(kryo, typ)
- var coll: Set[Any] =
- if(classOf[SortedSet[_]].isAssignableFrom(typ)) {
+ var coll: Set[Any] = if(isSortedSet) {
// Read ordering and set it for this collection
implicit val setOrdering = kryo.readClassAndObject(input).asInstanceOf[scala.math.Ordering[Any]]
- try {
- val constructor =
- class2constuctor.get(typ) getOrElse {
- val constr = typ.getDeclaredConstructor(classOf[scala.math.Ordering[_]])
- class2constuctor += typ->constr
- constr
- }
- constructor.newInstance(setOrdering).asInstanceOf[Set[Any]].empty
- } catch {
- case _: Throwable => kryo.newInstance(typ).asInstanceOf[Set[Any]].empty
- }
- } else {
- kryo.newInstance(typ).asInstanceOf[Set[Any]].empty
- }
+ if (constr != null) {
+ constr.newInstance(setOrdering).asInstanceOf[Set[Any]].empty
+ } else null
+ } else null
+
+ if (coll == null) {
+ coll = if (isImmutableSet) emptyColl else kryo.newInstance(typ).asInstanceOf[Set[Any]].empty
+ }
var i = 0
while (i < len) {
@@ -94,7 +107,9 @@ class ScalaSetSerializer ( ) extends Serializer[Set[_]] {
val len = collection.size
output.writeInt(len, true)
- if(classOf[SortedSet[_]].isAssignableFrom(obj.getClass())) {
+ init(kryo, obj.getClass().asInstanceOf[Class[Set[_]]])
+
+ if(isSortedSet) {
val ordering = obj.asInstanceOf[SortedSet[_]].ordering
kryo.writeClassAndObject(output, ordering)
}
diff --git a/src/main/scala/com/romix/scala/serialization/kryo/ScalaMapSerializers.scala b/src/main/scala/com/romix/scala/serialization/kryo/ScalaMapSerializers.scala
index 39d4a33..7cbcb90 100644
--- a/src/main/scala/com/romix/scala/serialization/kryo/ScalaMapSerializers.scala
+++ b/src/main/scala/com/romix/scala/serialization/kryo/ScalaMapSerializers.scala
@@ -65,11 +65,18 @@ class ScalaMutableMapSerializer() extends Serializer[MMap[_,_]] {
class ScalaImmutableMapSerializer() extends Serializer[IMap[_,_]] {
+ private var emptyColl: IMap[Any, Any] = null
+
setImmutable(true)
override def read(kryo: Kryo, input: Input, typ: Class[IMap[_,_]]): IMap[_,_] = {
val len = input.readInt(true)
- var coll: IMap[Any, Any] = kryo.newInstance(typ).asInstanceOf[IMap[Any,Any]].empty
+
+ if (emptyColl == null) {
+ emptyColl = kryo.newInstance(typ).asInstanceOf[IMap[Any,Any]].empty
+ }
+
+ var coll: IMap[Any, Any] = emptyColl
if (len != 0) {
var i = 0
@@ -96,7 +103,8 @@ class ScalaImmutableMapSerializer() extends Serializer[IMap[_,_]] {
}
class ScalaSortedMapSerializer() extends Serializer[SortedMap[_,_]] {
- private var class2constuctor = IMap[Class[_], Constructor[_]]()
+ private var constr: Constructor[_] = null
+ private var emptyColl: SortedMap[Any, Any] = null
// All sorted maps are immutable
setImmutable(true)
@@ -104,17 +112,16 @@ class ScalaSortedMapSerializer() extends Serializer[SortedMap[_,_]] {
override def read(kryo: Kryo, input: Input, typ: Class[SortedMap[_,_]]): SortedMap[_,_] = {
val len = input.readInt(true)
implicit val mapOrdering = kryo.readClassAndObject(input).asInstanceOf[scala.math.Ordering[Any]]
- var coll: SortedMap[Any, Any] =
+
+ if (constr == null && emptyColl == null) {
try {
- val constructor = class2constuctor.get(typ) getOrElse {
- val constr = typ.getDeclaredConstructor(classOf[scala.math.Ordering[_]])
- class2constuctor += typ->constr
- constr
- }
- constructor.newInstance(mapOrdering).asInstanceOf[SortedMap[Any,Any]].empty
+ constr = typ.getDeclaredConstructor(classOf[scala.math.Ordering[_]])
} catch {
- case _: Throwable => kryo.newInstance(typ).asInstanceOf[SortedMap[Any,Any]].empty
+ case _: Throwable => emptyColl = kryo.newInstance(typ).asInstanceOf[SortedMap[Any,Any]].empty
}
+ }
+
+ var coll: SortedMap[Any, Any] = if (constr != null) { constr.newInstance(mapOrdering).asInstanceOf[SortedMap[Any,Any]].empty } else emptyColl
var i = 0
while(i < len) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment