This is an automated email from the ASF dual-hosted git repository. jorgebg pushed a commit to branch TINKERPOP-1942 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/TINKERPOP-1942 by this push: new 94ae73d Metrics serializer 94ae73d is described below commit 94ae73d3b2958f217bef49e72e19d554093ed960 Author: Jorge Bay Gondra <jorgebaygon...@gmail.com> AuthorDate: Wed Dec 19 11:52:59 2018 +0100 Metrics serializer --- docs/src/dev/io/graphbinary.asciidoc | 14 +++++ .../gremlin/driver/ser/binary/DataType.java | 1 + .../driver/ser/binary/TypeSerializerRegistry.java | 2 + .../driver/ser/binary/types/MetricsSerializer.java | 68 ++++++++++++++++++++++ .../GraphBinaryReaderWriterRoundTripTest.java | 19 ++++++ 5 files changed, 104 insertions(+) diff --git a/docs/src/dev/io/graphbinary.asciidoc b/docs/src/dev/io/graphbinary.asciidoc index e301164..3243dd4 100644 --- a/docs/src/dev/io/graphbinary.asciidoc +++ b/docs/src/dev/io/graphbinary.asciidoc @@ -105,6 +105,7 @@ Changes to existing types require new revision. - `0x29`: TraversalStrategy - `0x2a`: BulkSet - `0x2b`: Tree +- `0x2c`: Metrics - `0xfe`: Unspecified null object - `0x00`: Custom @@ -543,6 +544,19 @@ Where: - `{item_0}...{item_n}` are the items of the `Tree`. `{item_i}` is composed of `{key}` is a fully-qualified type value followed by a `{Tree}`. +==== Metrics + +Format: `{id}{name}{duration}{counts}{annotations}{nested_metrics}` + +Where: + +- `{id}` is a `String` representing the identifier. +- `{name}` is a `String` representing the name. +- `{duration}` is a `Long` describing the duration in nanoseconds. +- `{counts}` is a `Map` composed by `String` keys and `Long` values. +- `{annotations}` is a `Map` composed by `String` keys and a value of any type. +- `{nested_metrics}` is a `List` composed by `Metrics` items. + ==== Custom A custom type, represented as a blob value. diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/DataType.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/DataType.java index a50a981..4a769fb 100644 --- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/DataType.java +++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/DataType.java @@ -65,6 +65,7 @@ public enum DataType { TRAVERSALSTRATEGY(0X29), BULKSET(0X2A), TREE(0X2B), + METRICS(0x2C), CHAR(0X80), DURATION(0X81), diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java index c29902c..2f0b95c 100644 --- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java +++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java @@ -35,6 +35,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet; import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.process.traversal.util.AndP; +import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics; import org.apache.tinkerpop.gremlin.process.traversal.util.OrP; import org.apache.tinkerpop.gremlin.structure.Column; import org.apache.tinkerpop.gremlin.structure.Direction; @@ -132,6 +133,7 @@ public class TypeSerializerRegistry { new RegistryEntry<>(TraversalStrategy.class, new TraversalStrategySerializer()), new RegistryEntry<>(BulkSet.class, new BulkSetSerializer()), new RegistryEntry<>(Tree.class, new TreeSerializer()), + new RegistryEntry<>(Metrics.class, new MetricsSerializer()), // MapEntrySerializer is a TransformSerializer implementation new RegistryEntry<>(Map.Entry.class, new MapEntrySerializer()), diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/MetricsSerializer.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/MetricsSerializer.java new file mode 100644 index 0000000..788650d --- /dev/null +++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/MetricsSerializer.java @@ -0,0 +1,68 @@ +/* + * 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.driver.ser.binary.types; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import org.apache.tinkerpop.gremlin.driver.ser.SerializationException; +import org.apache.tinkerpop.gremlin.driver.ser.binary.DataType; +import org.apache.tinkerpop.gremlin.driver.ser.binary.GraphBinaryReader; +import org.apache.tinkerpop.gremlin.driver.ser.binary.GraphBinaryWriter; +import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics; +import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics; + +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class MetricsSerializer extends SimpleTypeSerializer<Metrics> { + private static final CollectionSerializer collectionSerializer = new CollectionSerializer(DataType.LIST); + + public MetricsSerializer() { + super(DataType.METRICS); + } + + @Override + Metrics readValue(ByteBuf buffer, GraphBinaryReader context) throws SerializationException { + // Consider using a custom implementation, like "DefaultMetrics" + final MutableMetrics result = new MutableMetrics( + context.readValue(buffer, String.class, false), + context.readValue(buffer, String.class, false)); + result.setDuration(context.readValue(buffer, Long.class, false), TimeUnit.NANOSECONDS); + final Map<String, Long> counts = context.readValue(buffer, Map.class, false); + counts.forEach(result::setCount); + final Map<String, Object> annotations = context.readValue(buffer, Map.class, false); + annotations.forEach(result::setAnnotation); + Collection<MutableMetrics> nestedMetrics = collectionSerializer.readValue(buffer, context); + nestedMetrics.forEach(result::addNested); + return result; + } + + @Override + public ByteBuf writeValue(Metrics value, ByteBufAllocator allocator, GraphBinaryWriter context) throws SerializationException { + return allocator.compositeBuffer(6).addComponents(true, + context.writeValue(value.getId(), allocator, false), + context.writeValue(value.getName(), allocator, false), + context.writeValue(value.getDuration(TimeUnit.NANOSECONDS), allocator, false), + context.writeValue(value.getCounts(), allocator, false), + context.writeValue(value.getAnnotations(), allocator, false), + // Avoid changing type to List + collectionSerializer.writeValue(value.getNested(), allocator, context)); + } +} diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java index a719d88..1763279 100644 --- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java +++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/GraphBinaryReaderWriterRoundTripTest.java @@ -36,6 +36,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet; import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics; +import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics; import org.apache.tinkerpop.gremlin.structure.Column; import org.apache.tinkerpop.gremlin.structure.Direction; import org.apache.tinkerpop.gremlin.structure.Graph; @@ -52,6 +54,7 @@ import org.apache.tinkerpop.gremlin.util.function.Lambda; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import org.mockito.internal.matchers.apachecommons.ReflectionEquals; import java.math.BigDecimal; import java.math.BigInteger; @@ -73,10 +76,12 @@ import java.time.YearMonth; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.hasLabel; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; @RunWith(Parameterized.class) public class GraphBinaryReaderWriterRoundTripTest { @@ -121,6 +126,12 @@ public class GraphBinaryReaderWriterRoundTripTest { subTree.put(new ReferenceVertex(100, "animal"), subSubTree); tree.put(new ReferenceVertex(1000, "animal"), subTree); + final MutableMetrics metrics = new MutableMetrics("id1", "name1"); + metrics.setDuration(123, TimeUnit.MICROSECONDS); + metrics.setCount("c1", 20); + metrics.setAnnotation("a", "b"); + metrics.addNested(new MutableMetrics("idNested", "nameNested")); + return Arrays.asList( new Object[] {"String", "ABC", null}, new Object[] {"Char", '£', null}, @@ -217,6 +228,14 @@ public class GraphBinaryReaderWriterRoundTripTest { }}, new Object[] {"BulkSet", bulkSet, null}, new Object[] {"Tree", tree, null}, + new Object[] {"EmptyMetrics", new MutableMetrics("idEmpty", "nameEmpty"), (Consumer<Metrics>) m -> { + assertThat(m, new ReflectionEquals(new MutableMetrics("idEmpty", "nameEmpty"))); + }}, + new Object[] {"Metrics", metrics, (Consumer<Metrics>) m -> { + assertThat(m, new ReflectionEquals(metrics, "nested", "counts")); + assertEquals(new ArrayList(metrics.getCounts().values()), new ArrayList(m.getCounts().values())); + assertThat(m.getNested(), new ReflectionEquals(metrics.getNested())); + }}, // collections new Object[] {"ListSingle", listSingle, null},