Skip to content

Commit 0363427

Browse files
committed
Merge branch 'release/0.4.0'
2 parents 6181f96 + ae7c60f commit 0363427

File tree

48 files changed

+1063
-608
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1063
-608
lines changed

CHANGES.md

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# chill #
22

3+
### 0.4.0
4+
* Support serializing asJavaIterable.: https://github.com/twitter/chill/pull/192
5+
* Remove a deprecation, that really should never have been there: https://github.com/twitter/chill/pull/189
6+
* Use scalariform: https://github.com/twitter/chill/pull/188
7+
* README: Update Kryo project URL.: https://github.com/twitter/chill/pull/187
8+
* support mutable BitSet: https://github.com/twitter/chill/pull/185
9+
* Make chill-avro work with generic records: https://github.com/twitter/chill/pull/184
10+
* updating akka dependency to 2.3.2: https://github.com/twitter/chill/pull/182
11+
* add chill-algebird project by copying AlgebirdSerializers from of scaldi...: https://github.com/twitter/chill/pull/177
12+
* Scrooge serializer: https://github.com/twitter/chill/pull/178
13+
* Use shaded asm classes provided by Kryo.: https://github.com/twitter/chill/pull/175
14+
315
### 0.3.6
416
* Add ScalaAnyRefMapConfig, deals with non-string keys in cascading: https://github.com/twitter/chill/pull/174
517
* added AvroSerializer: https://github.com/twitter/chill/pull/172

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Chill [![Build Status](https://secure.travis-ci.org/twitter/chill.png)](http://travis-ci.org/twitter/chill)
22

3-
Extensions for the [Kryo serialization library](http://code.google.com/p/kryo/) including
3+
Extensions for the [Kryo serialization library](https://github.com/EsotericSoftware/kryo) including
44
serializers and a set of classes to ease configuration of Kryo in systems like Hadoop, Storm,
55
Akka, etc.
66

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.twitter.chill.akka
2-
/*******************************************************************************
2+
/**
3+
* *****************************************************************************
34
* Copyright 2012 Roman Levenstein
45
*
56
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,7 +14,8 @@ package com.twitter.chill.akka
1314
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1415
* See the License for the specific language governing permissions and
1516
* limitations under the License.
16-
******************************************************************************/
17+
* ****************************************************************************
18+
*/
1719

1820
import akka.actor.ExtendedActorSystem
1921
import akka.actor.ActorRef
@@ -23,30 +25,31 @@ import com.esotericsoftware.kryo.Serializer
2325
import com.esotericsoftware.kryo.io.Input
2426
import com.esotericsoftware.kryo.io.Output
2527

26-
/***
28+
/**
29+
* *
2730
* This module provides helper classes for serialization of Akka-specific classes.
2831
*
2932
* @author Roman Levenstein
3033
* @author P. Oscar Boykin
3134
*/
3235

33-
import com.twitter.chill.{toRich, IKryoRegistrar}
36+
import com.twitter.chill.{ toRich, IKryoRegistrar }
3437

3538
class ActorRefSerializer(system: ExtendedActorSystem) extends Serializer[ActorRef] with IKryoRegistrar {
3639

3740
def apply(kryo: Kryo): Unit = {
38-
if(!kryo.alreadyRegistered(classOf[ActorRef])) {
41+
if (!kryo.alreadyRegistered(classOf[ActorRef])) {
3942
kryo.forClass[ActorRef](this)
4043
kryo.forSubclass[ActorRef](this)
4144
}
4245
}
4346

44-
override def read(kryo: Kryo, input: Input, typ: Class[ActorRef]): ActorRef = {
45-
val path = input.readString()
46-
system.actorFor(path)
47-
}
47+
override def read(kryo: Kryo, input: Input, typ: Class[ActorRef]): ActorRef = {
48+
val path = input.readString()
49+
system.actorFor(path)
50+
}
4851

49-
override def write(kryo: Kryo, output: Output, obj: ActorRef) = {
52+
override def write(kryo: Kryo, output: Output, obj: ActorRef) = {
5053
output.writeString(Serialization.serializedActorPath(obj))
51-
}
54+
}
5255
}

chill-akka/src/main/scala/com/twitter/chill/akka/AkkaConfig.scala

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ limitations under the License.
1616

1717
package com.twitter.chill.akka
1818

19-
import com.twitter.chill.config.{Config => ChillConfig}
20-
import com.typesafe.config.{Config => TypesafeConfig}
19+
import com.twitter.chill.config.{ Config => ChillConfig }
20+
import com.typesafe.config.{ Config => TypesafeConfig }
2121
import com.typesafe.config.ConfigFactory
2222

2323
import scala.util.Try
2424

25-
/** Wraps the immutable typesafe.config.Config in a wrapper that
25+
/**
26+
* Wraps the immutable typesafe.config.Config in a wrapper that
2627
* keeps track of the state and follows the semantics of ChillConfig
2728
*/
2829
class AkkaConfig(var typesafeConfig: TypesafeConfig) extends ChillConfig {
@@ -35,6 +36,6 @@ class AkkaConfig(var typesafeConfig: TypesafeConfig) extends ChillConfig {
3536
ConfigFactory.parseString("%s = \"%s\"".format(key, v))
3637
.withFallback(typesafeConfig)
3738
}
38-
.getOrElse(typesafeConfig.withoutPath(key))
39+
.getOrElse(typesafeConfig.withoutPath(key))
3940
}
4041
}

chill-akka/src/main/scala/com/twitter/chill/akka/AkkaSerializer.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ limitations under the License.
1616

1717
package com.twitter.chill.akka
1818

19-
import akka.actor.{ExtendedActorSystem, ActorRef}
19+
import akka.actor.{ ExtendedActorSystem, ActorRef }
2020
import akka.serialization.Serializer
2121

2222
import com.twitter.chill._
@@ -44,7 +44,8 @@ import com.twitter.chill.config.ConfiguredInstantiator
4444
*/
4545
class AkkaSerializer(system: ExtendedActorSystem) extends Serializer {
4646

47-
/** You can override this to easily change your serializers.
47+
/**
48+
* You can override this to easily change your serializers.
4849
* If you do so, make sure to change the config to use the name of
4950
* your new class
5051
*/
@@ -71,7 +72,8 @@ class AkkaSerializer(system: ExtendedActorSystem) extends Serializer {
7172
kryoPool.fromBytes(bytes)
7273
}
7374

74-
/** Uses the Config system of chill.config to Configure at runtime which KryoInstantiator to use
75+
/**
76+
* Uses the Config system of chill.config to Configure at runtime which KryoInstantiator to use
7577
* Overriding kryoInstantiator and using your own class name is probably easier for most cases.
7678
* See ConfiguredInstantiator static methods for how to build up a correct Config with
7779
* your reflected or serialized instantiators.

chill-akka/src/test/scala/com/twitter/chill/akka/AkkaTests.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class AkkaTests extends Specification {
4343
"AkkaSerializer" should {
4444
"be selected for tuples" in {
4545
// Find the Serializer for it
46-
val serializer = serialization.findSerializerFor((1,2,3))
46+
val serializer = serialization.findSerializerFor((1, 2, 3))
4747
serializer.getClass.equals(classOf[AkkaSerializer]) must beTrue
4848
}
4949

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Copyright 2014 Twitter, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package com.twitter.chill.algebird
17+
18+
import com.esotericsoftware.kryo.Kryo
19+
import com.esotericsoftware.kryo.serializers.FieldSerializer
20+
21+
import com.twitter.chill.IKryoRegistrar
22+
23+
import com.twitter.algebird.{
24+
AveragedValue,
25+
DecayedValue,
26+
HLL,
27+
HyperLogLog,
28+
HyperLogLogMonoid,
29+
Moments,
30+
SpaceSaver,
31+
DenseVector,
32+
SparseVector,
33+
AdaptiveVector
34+
}
35+
36+
class AlgebirdRegistrar extends IKryoRegistrar {
37+
38+
def apply(k: Kryo) {
39+
// Some of the monoids from Algebird that we use:
40+
k.register(classOf[AveragedValue], new AveragedValueSerializer)
41+
k.register(classOf[DecayedValue], new DecayedValueSerializer)
42+
k.register(classOf[HyperLogLogMonoid], new HLLMonoidSerializer)
43+
k.register(classOf[Moments], new MomentsSerializer)
44+
k.addDefaultSerializer(classOf[HLL], new HLLSerializer)
45+
46+
/**
47+
* AdaptiveVector is IndexedSeq, which picks up the chill IndexedSeq serializer
48+
* (which is its own bug), force using the fields serializer here
49+
*/
50+
k.register(classOf[DenseVector[_]], new FieldSerializer[DenseVector[_]](k, classOf[DenseVector[_]]))
51+
52+
k.register(classOf[SparseVector[_]], new FieldSerializer[SparseVector[_]](k, classOf[SparseVector[_]]))
53+
54+
k.addDefaultSerializer(classOf[AdaptiveVector[_]], classOf[FieldSerializer[_]])
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
Copyright 2012 Twitter, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
package com.twitter.chill.algebird
17+
18+
import com.esotericsoftware.kryo.Kryo
19+
import com.esotericsoftware.kryo.{ Serializer => KSerializer }
20+
import com.esotericsoftware.kryo.io.{ Input, Output }
21+
22+
import com.twitter.algebird.{
23+
AveragedValue,
24+
DecayedValue,
25+
HLL,
26+
HyperLogLog,
27+
HyperLogLogMonoid,
28+
Moments,
29+
SpaceSaver,
30+
SSOne,
31+
SSMany
32+
}
33+
34+
import scala.collection.mutable.{ Map => MMap }
35+
import scala.collection.immutable.SortedMap
36+
37+
class AveragedValueSerializer extends KSerializer[AveragedValue] {
38+
setImmutable(true)
39+
def write(kser: Kryo, out: Output, s: AveragedValue) {
40+
out.writeLong(s.count, true)
41+
out.writeDouble(s.value)
42+
}
43+
def read(kser: Kryo, in: Input, cls: Class[AveragedValue]): AveragedValue =
44+
AveragedValue(in.readLong(true), in.readDouble)
45+
}
46+
47+
class MomentsSerializer extends KSerializer[Moments] {
48+
setImmutable(true)
49+
def write(kser: Kryo, out: Output, s: Moments) {
50+
out.writeLong(s.m0, true)
51+
out.writeDouble(s.m1)
52+
out.writeDouble(s.m2)
53+
out.writeDouble(s.m3)
54+
out.writeDouble(s.m4)
55+
}
56+
def read(kser: Kryo, in: Input, cls: Class[Moments]): Moments = {
57+
Moments(in.readLong(true),
58+
in.readDouble,
59+
in.readDouble,
60+
in.readDouble,
61+
in.readDouble)
62+
}
63+
}
64+
65+
class DecayedValueSerializer extends KSerializer[DecayedValue] {
66+
setImmutable(true)
67+
def write(kser: Kryo, out: Output, s: DecayedValue) {
68+
out.writeDouble(s.value)
69+
out.writeDouble(s.scaledTime)
70+
}
71+
def read(kser: Kryo, in: Input, cls: Class[DecayedValue]): DecayedValue =
72+
DecayedValue(in.readDouble, in.readDouble)
73+
}
74+
75+
class HLLSerializer extends KSerializer[HLL] {
76+
setImmutable(true)
77+
def write(kser: Kryo, out: Output, s: HLL) {
78+
val bytes = HyperLogLog.toBytes(s)
79+
out.writeInt(bytes.size, true)
80+
out.writeBytes(bytes)
81+
}
82+
def read(kser: Kryo, in: Input, cls: Class[HLL]): HLL = {
83+
HyperLogLog.fromBytes(in.readBytes(in.readInt(true)))
84+
}
85+
}
86+
87+
class HLLMonoidSerializer extends KSerializer[HyperLogLogMonoid] {
88+
setImmutable(true)
89+
val hllMonoids = MMap[Int, HyperLogLogMonoid]()
90+
def write(kser: Kryo, out: Output, mon: HyperLogLogMonoid) {
91+
out.writeInt(mon.bits, true)
92+
}
93+
def read(kser: Kryo, in: Input, cls: Class[HyperLogLogMonoid]): HyperLogLogMonoid = {
94+
val bits = in.readInt(true)
95+
hllMonoids.getOrElseUpdate(bits, new HyperLogLogMonoid(bits))
96+
}
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Copyright 2014 Twitter, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package com.twitter.chill.algebird
18+
19+
import com.twitter.chill.{ KSerializer, ScalaKryoInstantiator, KryoPool }
20+
import com.twitter.algebird.{ AveragedValue, DecayedValue, HyperLogLogMonoid, MomentsGroup, AdaptiveVector }
21+
import org.specs.Specification
22+
23+
class AlgebirdSerializersSpec extends Specification {
24+
val kryo = {
25+
val inst = () => {
26+
val newK = (new ScalaKryoInstantiator).newKryo
27+
newK.setReferences(false) // typical in production environment (scalding, spark)
28+
(new AlgebirdRegistrar).apply(newK)
29+
newK
30+
}
31+
KryoPool.withByteArrayOutputStream(1, inst)
32+
}
33+
34+
def roundtrip[X](x: X) {
35+
val bytes = kryo.toBytesWithClass(x)
36+
//println("bytes size : " + bytes.size)
37+
//println("bytes: " + new String(bytes, "UTF-8"))
38+
val result = kryo.fromBytes(bytes).asInstanceOf[X]
39+
result must_== x
40+
}
41+
42+
def roundtripNoEq[X](x: X)(f: X => Any) {
43+
val bytes = kryo.toBytesWithClass(x)
44+
val result = kryo.fromBytes(bytes).asInstanceOf[X]
45+
f(result) must_== f(x)
46+
}
47+
48+
"kryo with AlgebirdRegistrar" should {
49+
"serialize and deserialize AveragedValue" in {
50+
roundtrip(AveragedValue(10L, 123.45))
51+
}
52+
53+
"serialize and deserialize DecayedValue" in {
54+
roundtrip(DecayedValue.build(3.14, 20.2, 9.33))
55+
}
56+
57+
"serialize and deserialize HyperLogLogMonoid" in {
58+
roundtripNoEq(new HyperLogLogMonoid(12))(_.bits)
59+
}
60+
61+
"serialize and deserialize Moments" in {
62+
roundtrip(MomentsGroup.zero)
63+
}
64+
65+
"serialize and deserialize HLL" in {
66+
val sparse = new HyperLogLogMonoid(4).create(Array(-127.toByte))
67+
val dense = new HyperLogLogMonoid(4).batchCreate(Seq(-127, 100, 23, 44, 15, 96, 10).map(x => Array(x.toByte)))
68+
roundtrip(sparse)
69+
roundtrip(dense)
70+
}
71+
72+
"serialize and deserialize SparseVector and DenseVector" in {
73+
val sparse = AdaptiveVector.fromVector(Vector(1, 1, 1, 1, 1, 3), 1)
74+
val dense = AdaptiveVector.fromVector(Vector(1, 2, 3, 1, 2, 3), 1)
75+
roundtrip(sparse)
76+
roundtrip(dense)
77+
}
78+
79+
}
80+
}

0 commit comments

Comments
 (0)