Skip to content

Commit a12128d

Browse files
authored
Merge pull request #257 from chermenin/develop
Fix issue #255
2 parents f5b28ca + 6d22c5f commit a12128d

3 files changed

Lines changed: 176 additions & 17 deletions

File tree

chill-java/src/main/java/com/twitter/chill/java/ArraysAsListSerializer.java

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import java.lang.reflect.Field;
2424
import java.util.Arrays;
2525
import java.util.List;
26+
import java.util.HashMap;
27+
import java.util.Map;
2628

2729
import com.esotericsoftware.kryo.Kryo;
2830
import com.esotericsoftware.kryo.Serializer;
@@ -40,6 +42,19 @@
4042
*/
4143
public class ArraysAsListSerializer extends Serializer<List<?>> {
4244

45+
private static final Map<Class<?>, Class<?>> primitives = new HashMap<Class<?>, Class<?>>(8, 1.0F);
46+
47+
static {
48+
primitives.put(byte.class, Byte.class);
49+
primitives.put(short.class, Short.class);
50+
primitives.put(int.class, Integer.class);
51+
primitives.put(long.class, Long.class);
52+
primitives.put(char.class, Character.class);
53+
primitives.put(float.class, Float.class);
54+
primitives.put(double.class, Double.class);
55+
primitives.put(boolean.class, Boolean.class);
56+
}
57+
4358
static public IKryoRegistrar registrar() {
4459
return new SingleRegistrar(Arrays.asList("").getClass(), new ArraysAsListSerializer());
4560
}
@@ -58,34 +73,42 @@ public ArraysAsListSerializer() {
5873
@Override
5974
public List<?> read(final Kryo kryo, final Input input, final Class<List<?>> type) {
6075
final int length = input.readInt(true);
61-
final Class<?> componentType = kryo.readClass( input ).getType();
76+
Class<?> componentType = kryo.readClass(input).getType();
6277
try {
63-
final Object[] items = (Object[]) Array.newInstance( componentType, length );
64-
for( int i = 0; i < length; i++ ) {
65-
items[i] = kryo.readClassAndObject( input );
78+
final Object items = Array.newInstance(getBoxedClass(componentType), length);
79+
for (int i = 0; i < length; i++) {
80+
Array.set(items, i, kryo.readClassAndObject(input));
6681
}
67-
return Arrays.asList( items );
68-
} catch ( final Exception e ) {
69-
throw new RuntimeException( e );
82+
return Arrays.asList((Object[]) items);
83+
} catch (final Exception e) {
84+
throw new RuntimeException(e);
7085
}
7186
}
7287

7388
@Override
7489
public void write(final Kryo kryo, final Output output, final List<?> obj) {
7590
try {
76-
final Object[] array = (Object[]) _arrayField.get( obj );
91+
final Object[] array = (Object[]) _arrayField.get(obj);
7792
output.writeInt(array.length, true);
7893
final Class<?> componentType = array.getClass().getComponentType();
79-
kryo.writeClass( output, componentType );
80-
for( final Object item : array ) {
81-
kryo.writeClassAndObject( output, item );
94+
kryo.writeClass(output, componentType);
95+
for (final Object item : array) {
96+
kryo.writeClassAndObject(output, item);
8297
}
83-
} catch ( final RuntimeException e ) {
84-
// Don't eat and wrap RuntimeExceptions because the ObjectBuffer.write...
85-
// handles SerializationException specifically (resizing the buffer)...
86-
throw e;
87-
} catch ( final Exception e ) {
88-
throw new RuntimeException( e );
98+
} catch (final RuntimeException e) {
99+
// Don't eat and wrap RuntimeExceptions because the ObjectBuffer.write...
100+
// handles SerializationException specifically (resizing the buffer)...
101+
throw e;
102+
} catch (final Exception e) {
103+
throw new RuntimeException(e);
104+
}
105+
}
106+
107+
private static Class<?> getBoxedClass(final Class<?> c) {
108+
if (c.isPrimitive()) {
109+
Class<?> x;
110+
return (x = primitives.get(c)) != null ? x : c;
89111
}
112+
return c;
90113
}
91114
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2016 Alex Chermenin
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 &quot;AS IS&quot; 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+
18+
package com.twitter.chill.java;
19+
20+
import com.esotericsoftware.kryo.Kryo;
21+
import com.esotericsoftware.kryo.io.Input;
22+
import com.esotericsoftware.kryo.io.Output;
23+
24+
import java.util.Arrays;
25+
import java.util.HashMap;
26+
import java.util.List;
27+
import java.util.Map;
28+
29+
@SuppressWarnings("unchecked")
30+
public class TestLists {
31+
32+
private static final Kryo kryo = new Kryo();
33+
34+
private static final Map<Class<?>, List<?>> map = new HashMap<Class<?>, List<?>>(9);
35+
36+
static {
37+
ArraysAsListSerializer.registrar().apply(kryo);
38+
map.put(byte.class, Arrays.asList((byte) 1, (byte) 2, (byte) 3, (byte) 4));
39+
map.put(short.class, Arrays.asList((short) 1, (short) 2, (short) 3, (short) 4));
40+
map.put(int.class, Arrays.asList(1, 2, 3, 4));
41+
map.put(long.class, Arrays.asList(1L, 2L, 3L, 4L));
42+
map.put(char.class, Arrays.asList('1', '2', '3', '4'));
43+
map.put(float.class, Arrays.asList(1.0F, 2.0F, 3.0F, 4.0F));
44+
map.put(double.class, Arrays.asList(1.0, 2.0, 3.0, 4.0));
45+
map.put(boolean.class, Arrays.asList(true, false, true));
46+
map.put(String.class, Arrays.asList("one", "two", "three"));
47+
map.put(List.class, Arrays.asList(
48+
Arrays.asList(1, 2, 3, 4),
49+
Arrays.asList(1.0, 2.0, 3.0, 4.0),
50+
Arrays.asList("one", "two", "three")
51+
));
52+
}
53+
54+
public static <T> T serializeAndDeserialize(T t) {
55+
Output output = new Output(1000, -1);
56+
kryo.writeClassAndObject(output, t);
57+
Input input = new Input(output.toBytes());
58+
return (T) kryo.readClassAndObject(input);
59+
}
60+
61+
public static List<?> getList(Class<?> c) {
62+
return map.get(c);
63+
}
64+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2016 Alex Chermenin
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 &quot;AS IS&quot; 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+
18+
package com.twitter.chill.java
19+
20+
import TestLists._
21+
import org.scalatest._
22+
23+
class ArraysAsListTest extends WordSpec with Matchers {
24+
25+
"ArraysAsListSerializer" should {
26+
27+
"byte[]" in {
28+
val list = getList(java.lang.Byte.TYPE)
29+
list should equal(serializeAndDeserialize(list))
30+
}
31+
32+
"short[]" in {
33+
val list = getList(java.lang.Short.TYPE)
34+
list should equal(serializeAndDeserialize(list))
35+
}
36+
37+
"int[]" in {
38+
val list = getList(java.lang.Integer.TYPE)
39+
list should equal(serializeAndDeserialize(list))
40+
}
41+
42+
"float[]" in {
43+
val list = getList(java.lang.Float.TYPE)
44+
list should equal(serializeAndDeserialize(list))
45+
}
46+
47+
"double[]" in {
48+
val list = getList(java.lang.Double.TYPE)
49+
list should equal(serializeAndDeserialize(list))
50+
}
51+
52+
"char[]" in {
53+
val list = getList(java.lang.Character.TYPE)
54+
list should equal(serializeAndDeserialize(list))
55+
}
56+
57+
"boolean[]" in {
58+
val list = getList(java.lang.Boolean.TYPE)
59+
list should equal(serializeAndDeserialize(list))
60+
}
61+
62+
"String[]" in {
63+
val list = getList(classOf[String])
64+
list should equal(serializeAndDeserialize(list))
65+
}
66+
67+
"Object[][]" in {
68+
val list = getList(classOf[java.util.List[_]])
69+
list should equal(serializeAndDeserialize(list))
70+
}
71+
}
72+
}

0 commit comments

Comments
 (0)