You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by yu...@apache.org on 2023/06/02 03:00:19 UTC

[pinot] branch master updated: Add required JSON annotation in H3IndexResolution (#10792)

This is an automated email from the ASF dual-hosted git repository.

yupeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new 60ab652e32 Add required JSON annotation in H3IndexResolution (#10792)
60ab652e32 is described below

commit 60ab652e3209927012fe8e7d765cb0e2e1ceab77
Author: Gonzalo Ortiz Jaureguizar <go...@users.noreply.github.com>
AuthorDate: Fri Jun 2 05:00:12 2023 +0200

    Add required JSON annotation in H3IndexResolution (#10792)
    
    * Fix H3IndexConfig json serialization and deserialization
    
    * Decode H3IndexResolution in short and list forms
---
 .../spi/index/reader/H3IndexResolution.java        | 49 +++++++++++++++++++++-
 .../spi/index/creator/H3IndexConfigTest.java       | 25 ++++++++++-
 .../segment/spi/reader/H3IndexResolutionTest.java  | 49 ++++++++++++++++++++++
 3 files changed, 120 insertions(+), 3 deletions(-)

diff --git a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/reader/H3IndexResolution.java b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/reader/H3IndexResolution.java
index 8e2708bc5e..c8e05b6f86 100644
--- a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/reader/H3IndexResolution.java
+++ b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/index/reader/H3IndexResolution.java
@@ -18,8 +18,17 @@
  */
 package org.apache.pinot.segment.spi.index.reader;
 
-import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.fasterxml.jackson.databind.type.CollectionLikeType;
+import com.fasterxml.jackson.databind.util.StdConverter;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -31,10 +40,11 @@ import java.util.Objects;
  * To efficiently serialize the resolutions, we use two bytes for encoding th enabled resolutions. The resolution level
  * maps to the corresponding bit.
  */
+@JsonSerialize(converter = H3IndexResolution.ToIntListConverted.class)
+@JsonDeserialize(using = H3IndexResolution.Deserializator.class)
 public class H3IndexResolution {
   private short _resolutions;
 
-  @JsonCreator
   public H3IndexResolution(List<Integer> resolutions) {
     for (int resolution : resolutions) {
       _resolutions |= 1 << resolution;
@@ -91,4 +101,39 @@ public class H3IndexResolution {
   public int hashCode() {
     return Objects.hash(_resolutions);
   }
+
+  public static class ToIntListConverted extends StdConverter<H3IndexResolution, List<Integer>> {
+    @Override
+    public List<Integer> convert(H3IndexResolution value) {
+      return value.getResolutions();
+    }
+  }
+
+  public static class Deserializator extends StdDeserializer<H3IndexResolution> {
+    public Deserializator() {
+      super(H3IndexResolution.class);
+    }
+
+    @Override
+    public H3IndexResolution deserialize(JsonParser p, DeserializationContext ctxt)
+        throws IOException, JsonProcessingException {
+      switch (p.currentToken()) {
+        case VALUE_NUMBER_INT: {
+          long longValue = p.getLongValue();
+          if (longValue > Short.MAX_VALUE || longValue < Short.MIN_VALUE) {
+            throw new JsonParseException(p, "Resolution value is outside the short int range");
+          }
+          return new H3IndexResolution((short) longValue);
+        }
+        case START_ARRAY: {
+          CollectionLikeType arrayType = ctxt.getTypeFactory().constructCollectionLikeType(List.class, Integer.class);
+          List<Integer> resolutions = ctxt.readValue(p, arrayType);
+          return new H3IndexResolution(resolutions);
+        }
+        default: {
+          throw new JsonParseException(p, "Expecting number or array, but found " + p.currentToken());
+        }
+      }
+    }
+  }
 }
diff --git a/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/index/creator/H3IndexConfigTest.java b/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/index/creator/H3IndexConfigTest.java
index 6d0da56cb1..d3043afef4 100644
--- a/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/index/creator/H3IndexConfigTest.java
+++ b/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/index/creator/H3IndexConfigTest.java
@@ -19,11 +19,11 @@
 package org.apache.pinot.segment.spi.index.creator;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.collect.Lists;
 import org.apache.pinot.segment.spi.index.reader.H3IndexResolution;
 import org.apache.pinot.spi.utils.JsonUtils;
 import org.testng.Assert;
 import org.testng.annotations.Test;
-import org.testng.collections.Lists;
 
 import static org.testng.Assert.*;
 
@@ -84,4 +84,27 @@ public class H3IndexConfigTest {
     Assert.assertEquals(resolution.getLowestResolution(), 5);
     Assert.assertEquals(resolution.getResolutions(), Lists.newArrayList(5, 6, 13));
   }
+
+  @Test
+  public void serde()
+      throws JsonProcessingException {
+    H3IndexConfig initialConf = new H3IndexConfig(new H3IndexResolution(Lists.newArrayList(5, 6, 13)));
+
+    String confAsJson = JsonUtils.objectToString(initialConf);
+    Assert.assertEquals(confAsJson, "{\"disabled\":false,\"resolution\":[5,6,13]}");
+
+    H3IndexConfig readConf = JsonUtils.stringToObject(confAsJson, H3IndexConfig.class);
+    Assert.assertEquals(readConf, initialConf, "Unexpected configuration after serialization and deserialization");
+  }
+
+  @Test
+  public void deserializeShort()
+      throws JsonProcessingException {
+    H3IndexConfig initialConf = new H3IndexConfig(new H3IndexResolution(Lists.newArrayList(5, 6, 13)));
+
+    String serialized = "{\"resolution\":8288}";
+    H3IndexConfig h3IndexConfig = JsonUtils.stringToObject(serialized, H3IndexConfig.class);
+
+    Assert.assertEquals(h3IndexConfig, initialConf, "Unexpected configuration after reading " + serialized);
+  }
 }
diff --git a/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/reader/H3IndexResolutionTest.java b/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/reader/H3IndexResolutionTest.java
index d9128a46f2..ec6ef8dbfe 100644
--- a/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/reader/H3IndexResolutionTest.java
+++ b/pinot-segment-spi/src/test/java/org/apache/pinot/segment/spi/reader/H3IndexResolutionTest.java
@@ -18,7 +18,10 @@
  */
 package org.apache.pinot.segment.spi.reader;
 
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import org.apache.pinot.segment.spi.index.reader.H3IndexResolution;
+import org.apache.pinot.spi.utils.JsonUtils;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 import org.testng.collections.Lists;
@@ -33,4 +36,50 @@ public class H3IndexResolutionTest {
     Assert.assertEquals(resolution.getLowestResolution(), 5);
     Assert.assertEquals(resolution.getResolutions(), Lists.newArrayList(5, 6, 13));
   }
+
+  @Test
+  public void serialization()
+      throws JsonProcessingException {
+    H3IndexResolution resolution = new H3IndexResolution(Lists.newArrayList(13, 5, 6));
+    String string = JsonUtils.objectToString(resolution);
+    Assert.assertEquals(string, "[5,6,13]");
+  }
+
+  @Test
+  public void deserializationList()
+      throws JsonProcessingException {
+    H3IndexResolution resolution =
+        JsonUtils.stringToObject("[5,6,13]", H3IndexResolution.class);
+    Assert.assertEquals(resolution.size(), 3);
+    Assert.assertEquals(resolution.getLowestResolution(), 5);
+    Assert.assertEquals(resolution.getResolutions(), Lists.newArrayList(5, 6, 13));
+  }
+
+  @Test
+  public void deserializationShort()
+      throws JsonProcessingException {
+    H3IndexResolution resolution =
+        JsonUtils.stringToObject("8288", H3IndexResolution.class);
+    Assert.assertEquals(resolution.size(), 3);
+    Assert.assertEquals(resolution.getLowestResolution(), 5);
+    Assert.assertEquals(resolution.getResolutions(), Lists.newArrayList(5, 6, 13));
+  }
+
+  @Test
+  public void deserializationLargeInt() {
+    Assert.assertThrows(JsonParseException.class,
+        () -> JsonUtils.stringToObject(Integer.toString(Integer.MAX_VALUE), H3IndexResolution.class));
+  }
+
+  @Test
+  public void deserializationSmallInt() {
+    Assert.assertThrows(JsonParseException.class,
+        () -> JsonUtils.stringToObject(Integer.toString(Integer.MIN_VALUE), H3IndexResolution.class));
+  }
+
+  @Test
+  public void deserializationObject() {
+    Assert.assertThrows(JsonParseException.class,
+        () -> JsonUtils.stringToObject("{}", H3IndexResolution.class));
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org