Skip to content

Commit

Permalink
Adds serializers for Optional{Int,Long,Double}
Browse files Browse the repository at this point in the history
Also extends the SerializationCompatTest accordingly and updates
test/resources/TestDataJava8-*.
  • Loading branch information
magro committed Feb 29, 2016
1 parent 3593987 commit fb65ee9
Show file tree
Hide file tree
Showing 12 changed files with 181 additions and 92 deletions.
4 changes: 2 additions & 2 deletions src/com/esotericsoftware/kryo/Kryo.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import java.util.TreeMap;
import java.util.TreeSet;

import com.esotericsoftware.kryo.serializers.java8.OptionalSerializer;
import com.esotericsoftware.kryo.serializers.java8.OptionalSerializers;
import org.objenesis.instantiator.ObjectInstantiator;
import org.objenesis.strategy.InstantiatorStrategy;
import org.objenesis.strategy.SerializingInstantiatorStrategy;
Expand Down Expand Up @@ -211,7 +211,7 @@ public Kryo (ClassResolver classResolver, ReferenceResolver referenceResolver, S
addDefaultSerializer(TimeZone.class, TimeZoneSerializer.class);
addDefaultSerializer(Calendar.class, CalendarSerializer.class);
addDefaultSerializer(Locale.class, LocaleSerializer.class);
OptionalSerializer.addDefaultSerializer(this);
OptionalSerializers.addDefaultSerializer(this);
lowPriorityDefaultSerializerCount = defaultSerializers.size();

// Primitives and string. Primitive wrappers automatically use the same registration as primitives.
Expand Down
33 changes: 33 additions & 0 deletions src/com/esotericsoftware/kryo/serializers/java8/JavaVersion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* Copyright (c) 2016, Martin Grotzke
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

package com.esotericsoftware.kryo.serializers.java8;

/**
* Helper to determine the java version.
*/
final class JavaVersion {

private static final int JAVA_VERSION = Integer.parseInt(System.getProperty("java.version").split("\\.")[1]);

static boolean isJava8() {
return JAVA_VERSION >= 8;
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* Copyright (c) 2016, Martin Grotzke
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
* - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

package com.esotericsoftware.kryo.serializers.java8;

import static com.esotericsoftware.kryo.serializers.java8.JavaVersion.isJava8;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;

/**
* Serializers for {@link Optional}, {@link OptionalInt}, {@link OptionalLong} and {@link OptionalDouble}.
* Are added as default serializers for java >= 1.8.
*/
public final class OptionalSerializers {

public static void addDefaultSerializer(Kryo kryo) {
if (isJava8()) {
kryo.addDefaultSerializer(Optional.class, new OptionalSerializer());
kryo.addDefaultSerializer(OptionalInt.class, new OptionalIntSerializer());
kryo.addDefaultSerializer(OptionalLong.class, new OptionalLongSerializer());
kryo.addDefaultSerializer(OptionalDouble.class, new OptionalDoubleSerializer());
}
}

private static class OptionalSerializer extends Serializer<Optional> {

{ setAcceptsNull(false); }

@Override
@SuppressWarnings("unchecked")
public void write(Kryo kryo, Output output, Optional object) {
Object nullable = object.isPresent() ? object.get() : null;
kryo.writeClassAndObject(output, nullable);
}

@Override
public Optional read(Kryo kryo, Input input, Class<Optional> type) {
return Optional.ofNullable(kryo.readClassAndObject(input));
}

@Override
public Optional copy(Kryo kryo, Optional original) {
if (original.isPresent()) {
return Optional.of(kryo.copy(original.get()));
}
return original;
}
}

private static class OptionalIntSerializer extends Serializer<OptionalInt> {
{ setImmutable(true); }

public void write(Kryo kryo, Output output, OptionalInt object) {
output.writeBoolean(object.isPresent());
if(object.isPresent()) output.writeInt(object.getAsInt());
}

public OptionalInt read(Kryo kryo, Input input, Class<OptionalInt> type) {
boolean present = input.readBoolean();
return present ? OptionalInt.of(input.readInt()) : OptionalInt.empty();
}
}

private static class OptionalLongSerializer extends Serializer<OptionalLong> {
{ setImmutable(true); }

public void write(Kryo kryo, Output output, OptionalLong object) {
output.writeBoolean(object.isPresent());
if(object.isPresent()) output.writeLong(object.getAsLong());
}

public OptionalLong read(Kryo kryo, Input input, Class<OptionalLong> type) {
boolean present = input.readBoolean();
return present ? OptionalLong.of(input.readLong()) : OptionalLong.empty();
}
}

private static class OptionalDoubleSerializer extends Serializer<OptionalDouble> {
{ setImmutable(true); }

public void write(Kryo kryo, Output output, OptionalDouble object) {
output.writeBoolean(object.isPresent());
if(object.isPresent()) output.writeDouble(object.getAsDouble());
}

public OptionalDouble read(Kryo kryo, Input input, Class<OptionalDouble> type) {
boolean present = input.readBoolean();
return present ? OptionalDouble.of(input.readDouble()) : OptionalDouble.empty();
}
}

}
4 changes: 2 additions & 2 deletions test/com/esotericsoftware/kryo/SerializationCompatTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ public class SerializationCompatTest extends KryoTestCase {

private static final String ENDIANNESS = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN ? "le" : "be";
private static final int JAVA_VERSION = Integer.parseInt(System.getProperty("java.version").split("\\.")[1]);
private static final int EXPECTED_DEFAULT_SERIALIZER_COUNT = JAVA_VERSION < 8 ? 33 : 34;
private static final int EXPECTED_DEFAULT_SERIALIZER_COUNT = JAVA_VERSION < 8 ? 33 : 37;
private static final List<TestDataDescription<?>> TEST_DATAS = new ArrayList<TestDataDescription<?>>();

static {
TEST_DATAS.add(new TestDataDescription<TestData>("3.0.0", new TestData(), 1646, 1754));
if(JAVA_VERSION >= 8) TEST_DATAS.add(new TestDataDescription<TestDataJava8>("3.1.0", new TestDataJava8(), 1656, 1764));
if(JAVA_VERSION >= 8) TEST_DATAS.add(new TestDataDescription<TestDataJava8>("3.1.0", new TestDataJava8(), 1682, 1790));
};

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,15 @@ class SerializationCompatTestData {

static class TestDataJava8 extends TestData {
private Optional<String> _optionalString;
private OptionalInt _optionalInt;
private OptionalLong _optionalLong;
private OptionalDouble _optionalDouble;

TestDataJava8() {
_optionalString = Optional.of("foo");
_optionalInt = OptionalInt.of(42);
_optionalLong = OptionalLong.of(42L);
_optionalDouble = OptionalDouble.of(42d);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@

import com.esotericsoftware.kryo.KryoTestCase;

import java.util.Objects;
import java.util.Optional;
import java.util.*;

public class OptionalSerializerTest extends KryoTestCase {
public class OptionalSerializersTest extends KryoTestCase {

{
supportsCopy = true;
Expand All @@ -34,19 +33,34 @@ public class OptionalSerializerTest extends KryoTestCase {
protected void setUp() throws Exception {
super.setUp();
kryo.register(Optional.class);
kryo.register(OptionalInt.class);
kryo.register(OptionalLong.class);
kryo.register(OptionalDouble.class);
kryo.register(TestClass.class);
}

public void testNull() {
public void testOptional() {
roundTrip(2, 2, new TestClass(null));
roundTrip(3, 3, new TestClass(Optional.<String>empty()));
roundTrip(6, 6, new TestClass(Optional.of("foo")));
}

public void testEmpty() {
roundTrip(3, 3, new TestClass(Optional.<String>empty()));
public void testOptionalInt() {
roundTrip(2, 2, OptionalInt.empty());
roundTrip(6, 6, OptionalInt.of(Integer.MIN_VALUE));
roundTrip(6, 6, OptionalInt.of(Integer.MAX_VALUE));
}

public void testPresent() {
roundTrip(6, 6, new TestClass(Optional.of("foo")));
public void testOptionalLong() {
roundTrip(2, 2, OptionalLong.empty());
roundTrip(10, 10, OptionalLong.of(Long.MIN_VALUE));
roundTrip(10, 10, OptionalLong.of(Long.MAX_VALUE));
}

public void testOptionalDouble() {
roundTrip(2, 2, OptionalDouble.empty());
roundTrip(10, 10, OptionalDouble.of(Double.MIN_VALUE));
roundTrip(10, 10, OptionalDouble.of(Double.MAX_VALUE));
}

static class TestClass {
Expand Down
Binary file modified test/resources/TestDataJava8-bytebuffer.ser
Binary file not shown.
Binary file modified test/resources/TestDataJava8-fast.ser
Binary file not shown.
Binary file modified test/resources/TestDataJava8-standard.ser
Binary file not shown.
Binary file modified test/resources/TestDataJava8-unsafe-le.ser
Binary file not shown.
Binary file modified test/resources/TestDataJava8-unsafeMemory-le.ser
Binary file not shown.

0 comments on commit fb65ee9

Please sign in to comment.