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/16 01:52:47 UTC

incubator-tinkerpop git commit: Added gryo serializers for virtually all java.time classes.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1086 [created] 74b4c6186


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-1086
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.
      */