You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/01/19 20:02:11 UTC

[08/11] incubator-tinkerpop git commit: Added gryo serializers for virtually all java.time classes.

Added gryo serializers for virtually all java.time classes.

These classes did not have serializers natively to kryo and were also not in the semi-standard contrib package of serializers.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/74b4c618
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/74b4c618
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/74b4c618

Branch: refs/heads/TINKERPOP-998
Commit: 74b4c6186158037b20593a12e9b7ed4105632be1
Parents: cf2e3b1
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jan 15 19:51:39 2016 -0500
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jan 15 19:51:39 2016 -0500

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../gremlin/structure/io/gryo/GryoMapper.java   |  30 +-
 .../structure/io/gryo/JavaTimeSerializers.java  | 303 +++++++++++++++++++
 .../structure/io/gryo/GryoMapperTest.java       | 109 +++++++
 4 files changed, 442 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/74b4c618/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index ddb9077..0a14e50 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -28,6 +28,7 @@ TinkerPop 3.1.1 (NOT OFFICIALLY RELEASED YET)
 
 * Reduced the complexity and execution time of all `AbstractLambdaTraversal` instances.
 * `DefaultTraversal` has a well defined `hashCode()` and `equals()`.
+* Added serializers to Gryo for `java.time` related classes.
 * Integrated `NumberHelper` in `SackFunctions`.
 * The Spark persistence `StorageLevel` can now be set for both job graphs and `PersistedOutputRDD` data.
 * Added to the list of "invalid binding keys" allowed by Gremlin Server to cover the private fields of `T` which get exposed in the `ScriptEngine` on static imports.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/74b4c618/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
index 7d945ce..cc77fa3 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
@@ -69,6 +69,20 @@ import org.javatuples.Triplet;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.net.URI;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Period;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -232,7 +246,7 @@ public final class GryoMapper implements Mapper<Kryo> {
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(EnumSet.class, null, 46));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(HashMap.class, null, 11));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(HashMap.Entry.class, null, 16));
-            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(HASH_MAP_NODE, null, 92));   // ***LAST ID**
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(HASH_MAP_NODE, null, 92));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(KryoSerializable.class, null, 36));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(LinkedHashMap.class, null, 47));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(LinkedHashSet.class, null, 71));
@@ -282,6 +296,20 @@ public final class GryoMapper implements Mapper<Kryo> {
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(AtomicLong.class, null, 79));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(DependantMutableMetrics.class, null, 80));
             add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Pair.class, kryo -> new PairSerializer(), 88));
+
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Duration.class, kryo -> new JavaTimeSerializers.DurationSerializer(), 93));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Instant.class, kryo -> new JavaTimeSerializers.InstantSerializer(), 94));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(LocalDate.class, kryo -> new JavaTimeSerializers.LocalDateSerializer(), 95));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(LocalDateTime.class, kryo -> new JavaTimeSerializers.LocalDateTimeSerializer(), 96));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(LocalTime.class, kryo -> new JavaTimeSerializers.LocalTimeSerializer(), 97));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(MonthDay.class, kryo -> new JavaTimeSerializers.MonthDaySerializer(), 98));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(OffsetDateTime.class, kryo -> new JavaTimeSerializers.OffsetDateTimeSerializer(), 99));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(OffsetTime.class, kryo -> new JavaTimeSerializers.OffsetTimeSerializer(), 100));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Period.class, kryo -> new JavaTimeSerializers.PeriodSerializer(), 101));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Year.class, kryo -> new JavaTimeSerializers.YearSerializer(), 102));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(YearMonth.class, kryo -> new JavaTimeSerializers.YearMonthSerializer(), 103));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(ZonedDateTime.class, kryo -> new JavaTimeSerializers.ZonedDateTimeSerializer(), 104));
+            add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(ZoneOffset.class, kryo -> new JavaTimeSerializers.ZoneOffsetSerializer(), 105)); // ***LAST ID**
         }};
 
         private final List<IoRegistry> registries = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/74b4c618/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/JavaTimeSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/JavaTimeSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/JavaTimeSerializers.java
new file mode 100644
index 0000000..1d4e236
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/JavaTimeSerializers.java
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.structure.io.gryo;
+
+import org.apache.tinkerpop.shaded.kryo.Kryo;
+import org.apache.tinkerpop.shaded.kryo.Serializer;
+import org.apache.tinkerpop.shaded.kryo.io.Input;
+import org.apache.tinkerpop.shaded.kryo.io.Output;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Period;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+/**
+ * Serializers for classes in the {@code java.time} package.
+ */
+final class JavaTimeSerializers {
+
+    private JavaTimeSerializers() {}
+
+    /**
+     * Serializer for the {@link Duration} class.
+     */
+    final static class DurationSerializer extends Serializer<Duration>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final Duration duration)
+        {
+            output.writeLong(duration.toNanos());
+        }
+
+        @Override
+        public Duration read(final Kryo kryo, final Input input, final Class<Duration> durationClass)
+        {
+            return Duration.ofNanos(input.readLong());
+        }
+    }
+
+    /**
+     * Serializer for the {@link Instant} class.
+     */
+    final static class InstantSerializer extends Serializer<Instant>
+    {
+        @Override
+        public void write(Kryo kryo, Output output, Instant instant)
+        {
+            output.writeLong(instant.getEpochSecond());
+            output.writeInt(instant.getNano());
+        }
+
+        @Override
+        public Instant read(Kryo kryo, Input input, Class<Instant> aClass)
+        {
+            return Instant.ofEpochSecond(input.readLong(), input.readInt());
+        }
+    }
+
+    /**
+     * Serializer for the {@link LocalDate} class.
+     */
+    final static class LocalDateSerializer extends Serializer<LocalDate>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final LocalDate localDate)
+        {
+            output.writeLong(localDate.toEpochDay());
+        }
+
+        @Override
+        public LocalDate read(final Kryo kryo, final Input input, final Class<LocalDate> clazz)
+        {
+            return LocalDate.ofEpochDay(input.readLong());
+        }
+    }
+
+    /**
+     * Serializer for the {@link LocalDateTime} class.
+     */
+    final static class LocalDateTimeSerializer extends Serializer<LocalDateTime>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final LocalDateTime localDateTime)
+        {
+            output.writeInt(localDateTime.getYear());
+            output.writeInt(localDateTime.getMonthValue());
+            output.writeInt(localDateTime.getDayOfMonth());
+            output.writeInt(localDateTime.getHour());
+            output.writeInt(localDateTime.getMinute());
+            output.writeInt(localDateTime.getSecond());
+            output.writeInt(localDateTime.getNano());
+        }
+
+        @Override
+        public LocalDateTime read(final Kryo kryo, final Input input, final Class<LocalDateTime> clazz)
+        {
+            return LocalDateTime.of(input.readInt(), input.readInt(), input.readInt(), input.readInt(), input.readInt(), input.readInt(), input.readInt());
+        }
+    }
+
+    /**
+     * Serializer for the {@link LocalTime} class.
+     */
+    final static class LocalTimeSerializer extends Serializer<LocalTime>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final LocalTime localTime)
+        {
+            output.writeLong(localTime.toNanoOfDay());
+        }
+
+        @Override
+        public LocalTime read(final Kryo kryo, final Input input, final Class<LocalTime> clazz)
+        {
+            return LocalTime.ofNanoOfDay(input.readLong());
+        }
+    }
+
+    /**
+     * Serializer for the {@link MonthDay} class.
+     */
+    final static class MonthDaySerializer extends Serializer<MonthDay>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final MonthDay monthDay)
+        {
+            output.writeInt(monthDay.getMonthValue());
+            output.writeInt(monthDay.getDayOfMonth());
+        }
+
+        @Override
+        public MonthDay read(final Kryo kryo, final Input input, final Class<MonthDay> clazz)
+        {
+            return MonthDay.of(input.readInt(), input.readInt());
+        }
+    }
+
+    /**
+     * Serializer for the {@link OffsetDateTime} class.
+     */
+    final static class OffsetDateTimeSerializer extends Serializer<OffsetDateTime>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final OffsetDateTime offsetDateTime)
+        {
+            kryo.writeObject(output, offsetDateTime.toLocalDateTime());
+            kryo.writeObject(output, offsetDateTime.getOffset());
+        }
+
+        @Override
+        public OffsetDateTime read(final Kryo kryo, final Input input, final Class<OffsetDateTime> clazz)
+        {
+            return OffsetDateTime.of(kryo.readObject(input, LocalDateTime.class), kryo.readObject(input, ZoneOffset.class));
+        }
+    }
+
+    /**
+     * Serializer for the {@link OffsetTime} class.
+     */
+    final static class OffsetTimeSerializer extends Serializer<OffsetTime>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final OffsetTime offsetTime)
+        {
+            kryo.writeObject(output, offsetTime.toLocalTime());
+            kryo.writeObject(output, offsetTime.getOffset());
+        }
+
+        @Override
+        public OffsetTime read(final Kryo kryo, final Input input, final Class<OffsetTime> clazz)
+        {
+            return OffsetTime.of(kryo.readObject(input, LocalTime.class), kryo.readObject(input, ZoneOffset.class));
+        }
+    }
+
+    /**
+     * Serializer for the {@link Period} class.
+     */
+    final static class PeriodSerializer extends Serializer<Period>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final Period period)
+        {
+            output.writeInt(period.getYears());
+            output.writeInt(period.getMonths());
+            output.writeInt(period.getDays());
+        }
+
+        @Override
+        public Period read(final Kryo kryo, final Input input, final Class<Period> clazz)
+        {
+            return Period.of(input.readInt(), input.readInt(), input.readInt());
+        }
+    }
+
+    /**
+     * Serializer for the {@link Year} class.
+     */
+    final static class YearSerializer extends Serializer<Year>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final Year year)
+        {
+            output.writeInt(year.getValue());
+        }
+
+        @Override
+        public Year read(final Kryo kryo, final Input input, final Class<Year> clazz)
+        {
+            return Year.of(input.readInt());
+        }
+    }
+
+    /**
+     * Serializer for the {@link YearMonth} class.
+     */
+    final static class YearMonthSerializer extends Serializer<YearMonth>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final YearMonth monthDay)
+        {
+            output.writeInt(monthDay.getYear());
+            output.writeInt(monthDay.getMonthValue());
+        }
+
+        @Override
+        public YearMonth read(final Kryo kryo, final Input input, final Class<YearMonth> clazz)
+        {
+            return YearMonth.of(input.readInt(), input.readInt());
+        }
+    }
+
+    /**
+     * Serializer for the {@link ZonedDateTime} class.
+     */
+    final static class ZonedDateTimeSerializer extends Serializer<ZonedDateTime>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final ZonedDateTime zonedDateTime)
+        {
+            output.writeInt(zonedDateTime.getYear());
+            output.writeInt(zonedDateTime.getMonthValue());
+            output.writeInt(zonedDateTime.getDayOfMonth());
+            output.writeInt(zonedDateTime.getHour());
+            output.writeInt(zonedDateTime.getMinute());
+            output.writeInt(zonedDateTime.getSecond());
+            output.writeInt(zonedDateTime.getNano());
+            output.writeString(zonedDateTime.getZone().getId());
+        }
+
+        @Override
+        public ZonedDateTime read(final Kryo kryo, final Input input, final Class<ZonedDateTime> clazz)
+        {
+            return ZonedDateTime.of(input.readInt(), input.readInt(), input.readInt(),
+                    input.readInt(), input.readInt(), input.readInt(), input.readInt(),
+                    ZoneId.of(input.readString()));
+        }
+    }
+
+    /**
+     * Serializer for the {@link ZoneOffset} class.
+     */
+    final static class ZoneOffsetSerializer extends Serializer<ZoneOffset>
+    {
+        @Override
+        public void write(final Kryo kryo, final Output output, final ZoneOffset zoneOffset)
+        {
+            output.writeString(zoneOffset.getId());
+        }
+
+        @Override
+        public ZoneOffset read(final Kryo kryo, final Input input, final Class<ZoneOffset> clazz)
+        {
+            return ZoneOffset.of(input.readString());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/74b4c618/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
index 76a2804..a915797 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java
@@ -36,6 +36,20 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.MonthDay;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.Period;
+import java.time.Year;
+import java.time.YearMonth;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -50,6 +64,10 @@ import static org.junit.Assert.assertNotSame;
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
 public class GryoMapperTest {
+
+    private final GryoMapper sharedMapper = GryoMapper.build().create();
+    private final Kryo sharedKryo = sharedMapper.createMapper();
+
     @Test
     public void shouldMakeNewInstance() {
         final GryoMapper.Builder b = GryoMapper.build();
@@ -200,6 +218,97 @@ public class GryoMapperTest {
         }
     }
 
+    @Test
+    public void shouldHandleDuration()throws Exception  {
+        final Duration o = Duration.ZERO;
+        assertEquals(o, serializeDeserialize(o, Duration.class));
+    }
+
+    @Test
+    public void shouldHandleInstant()throws Exception  {
+        final Instant o = Instant.ofEpochMilli(System.currentTimeMillis());
+        assertEquals(o, serializeDeserialize(o, Instant.class));
+    }
+
+    @Test
+    public void shouldHandleLocalDate()throws Exception  {
+        final LocalDate o = LocalDate.now();
+        assertEquals(o, serializeDeserialize(o, LocalDate.class));
+    }
+
+    @Test
+    public void shouldHandleLocalDateTime()throws Exception  {
+        final LocalDateTime o = LocalDateTime.now();
+        assertEquals(o, serializeDeserialize(o, LocalDateTime.class));
+    }
+
+    @Test
+    public void shouldHandleLocalTime()throws Exception  {
+        final LocalTime o = LocalTime.now();
+        assertEquals(o, serializeDeserialize(o, LocalTime.class));
+    }
+
+    @Test
+    public void shouldHandleMonthDay()throws Exception  {
+        final MonthDay o = MonthDay.now();
+        assertEquals(o, serializeDeserialize(o, MonthDay.class));
+    }
+
+    @Test
+    public void shouldHandleOffsetDateTime()throws Exception  {
+        final OffsetDateTime o = OffsetDateTime.now();
+        assertEquals(o, serializeDeserialize(o, OffsetDateTime.class));
+    }
+
+    @Test
+    public void shouldHandleOffsetTime()throws Exception  {
+        final OffsetTime o = OffsetTime.now();
+        assertEquals(o, serializeDeserialize(o, OffsetTime.class));
+    }
+
+    @Test
+    public void shouldHandlePeriod()throws Exception  {
+        final Period o = Period.ofDays(3);
+        assertEquals(o, serializeDeserialize(o, Period.class));
+    }
+
+    @Test
+    public void shouldHandleYear()throws Exception  {
+        final Year o = Year.now();
+        assertEquals(o, serializeDeserialize(o, Year.class));
+    }
+
+    @Test
+    public void shouldHandleYearMonth()throws Exception  {
+        final YearMonth o = YearMonth.now();
+        assertEquals(o, serializeDeserialize(o, YearMonth.class));
+    }
+
+    @Test
+    public void shouldHandleZonedDateTime()throws Exception  {
+        final ZonedDateTime o = ZonedDateTime.now();
+        assertEquals(o, serializeDeserialize(o, ZonedDateTime.class));
+    }
+
+    @Test
+    public void shouldHandleZonedOffset()throws Exception  {
+        final ZoneOffset o  = ZonedDateTime.now().getOffset();
+        assertEquals(o, serializeDeserialize(o, ZoneOffset.class));
+    }
+
+    public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception {
+        try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+            final Output out = new Output(stream);
+            sharedKryo.writeObject(out, o);
+            out.flush();
+
+            try (final InputStream inputStream = new ByteArrayInputStream(stream.toByteArray())) {
+                final Input input = new Input(inputStream);
+                return sharedKryo.readObject(input, clazz);
+            }
+        }
+    }
+
     /**
      * Creates new {@link CustomClassResolver} when requested.
      */