{"action":"created","comment":{"url":"https://api.github.com/repos/druid-io/druid/pulls/comments/87530434","pull_request_review_id":8140423,"id":87530434,"diff_hunk":"@@ -0,0 +1,443 @@\n+/*\n+ * Licensed to Metamarkets Group Inc. (Metamarkets) under one\n+ * or more contributor license agreements. See the NOTICE file\n+ * distributed with this work for additional information\n+ * regarding copyright ownership. Metamarkets licenses this file\n+ * to you under the Apache License, Version 2.0 (the\n+ * \"License\"); you may not use this file except in compliance\n+ * with the License. You may obtain a copy of the License at\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing,\n+ * software distributed under the License is distributed on an\n+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+ * KIND, either express or implied. See the License for the\n+ * specific language governing permissions and limitations\n+ * under the License.\n+ */\n+\n+package io.druid.segment;\n+\n+import com.google.common.base.Function;\n+import com.google.common.base.Predicate;\n+import com.google.common.base.Strings;\n+import com.google.common.collect.Lists;\n+import com.google.common.hash.Hasher;\n+import com.google.common.primitives.Ints;\n+import io.druid.query.aggregation.Aggregator;\n+import io.druid.query.QueryDimensionInfo;\n+import io.druid.query.aggregation.cardinality.CardinalityAggregator;\n+import io.druid.query.aggregation.hyperloglog.HyperLogLogCollector;\n+import io.druid.query.dimension.DefaultDimensionSpec;\n+import io.druid.query.dimension.DimensionSpec;\n+import io.druid.query.filter.DruidPredicateFactory;\n+import io.druid.query.filter.ValueMatcher;\n+import io.druid.query.search.search.SearchHit;\n+import io.druid.query.search.search.SearchQuerySpec;\n+import io.druid.query.topn.BaseTopNAlgorithm;\n+import io.druid.query.topn.TopNParams;\n+import io.druid.query.topn.TopNQuery;\n+import io.druid.segment.data.EmptyIndexedInts;\n+import io.druid.segment.data.IndexedInts;\n+import org.apache.commons.lang.mutable.MutableInt;\n+\n+import java.nio.ByteBuffer;\n+import java.util.Arrays;\n+import java.util.BitSet;\n+import java.util.Comparator;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.Objects;\n+import java.util.TreeMap;\n+\n+public class StringDimensionQueryHelper implements DimensionQueryHelper<Integer, int[], String>\n+{\n+  private static final int GROUP_BY_MISSING_VALUE = -1;\n+  private final String dimensionName;\n+\n+  private static Comparator<byte[]> GROUPING_KEY_COMPARATOR = new Comparator<byte[]>()\n+  {\n+    @Override\n+    public int compare(byte[] o1, byte[] o2)\n+    {\n+      int intLhs = Ints.fromByteArray(o1);\n+      int intRhs = Ints.fromByteArray(o2);\n+      return Ints.compare(intLhs, intRhs);\n+    }\n+  };\n+\n+  private static boolean isComparableNullOrEmpty(final Comparable value)\n+  {\n+    if (value instanceof String) {\n+      return Strings.isNullOrEmpty((String) value);\n+    }\n+    return value == null;\n+  }\n+\n+  public StringDimensionQueryHelper(String dimensionName) {\n+    this.dimensionName = dimensionName;\n+  }\n+\n+  @Override\n+  public Object getColumnValueSelector(DimensionSpec dimensionSpec, ColumnSelectorFactory columnSelectorFactory)\n+  {\n+    return columnSelectorFactory.makeDimensionSelector(dimensionSpec);\n+  }\n+\n+  @Override\n+  public int getRowSize(Object rowValues)\n+  {\n+    return ((IndexedInts) rowValues).size();\n+  }\n+\n+  @Override\n+  public int getCardinality(Object valueSelector)\n+  {\n+    return ((DimensionSelector) valueSelector).getValueCardinality();\n+  }\n+\n+  public ValueMatcher getValueMatcher(ColumnSelectorFactory cursor, final Comparable value)\n+  {\n+    final DimensionSelector selector = cursor.makeDimensionSelector(\n+        new DefaultDimensionSpec(dimensionName, dimensionName)\n+    );\n+\n+    // if matching against null, rows with size 0 should also match\n+    final boolean matchNull = isComparableNullOrEmpty(value);\n+\n+    final int cardinality = selector.getValueCardinality();\n+\n+    if (cardinality >= 0) {\n+      // Dictionary-encoded dimension. Compare by id instead of by value to save time.\n+      final int valueId = selector.lookupId((String) value);\n+\n+      return new ValueMatcher()\n+      {\n+        @Override\n+        public boolean matches()\n+        {\n+          final IndexedInts row = selector.getRow();\n+          final int size = row.size();\n+          if (size == 0) {\n+            // null should match empty rows in multi-value columns\n+            return matchNull;\n+          } else {\n+            for (int i = 0; i < size; ++i) {\n+              if (row.get(i) == valueId) {\n+                return true;\n+              }\n+            }\n+            return false;\n+          }\n+        }\n+      };\n+    } else {\n+      // Not dictionary-encoded. Skip the optimization.\n+      return new ValueMatcher()\n+      {\n+        @Override\n+        public boolean matches()\n+        {\n+          final IndexedInts row = selector.getRow();\n+          final int size = row.size();\n+          if (size == 0) {\n+            // null should match empty rows in multi-value columns\n+            return matchNull;\n+          } else {\n+            for (int i = 0; i < size; ++i) {\n+              if (Objects.equals(selector.lookupName(row.get(i)), value)) {\n+                return true;\n+              }\n+            }\n+            return false;\n+          }\n+        }\n+      };\n+    }\n+  }\n+\n+  public ValueMatcher getValueMatcher(ColumnSelectorFactory cursor, final DruidPredicateFactory predicateFactory)\n+  {\n+    final DimensionSelector selector = cursor.makeDimensionSelector(\n+        new DefaultDimensionSpec(dimensionName, dimensionName)\n+    );\n+\n+    final Predicate<String> predicate = predicateFactory.makeStringPredicate();\n+    final int cardinality = selector.getValueCardinality();\n+    final boolean matchNull = predicate.apply(null);\n+\n+    if (cardinality >= 0) {\n+      // Dictionary-encoded dimension. Check every value; build a bitset of matching ids.\n+      final BitSet valueIds = new BitSet(cardinality);\n+      for (int i = 0; i < cardinality; i++) {\n+        if (predicate.apply(selector.lookupName(i))) {\n+          valueIds.set(i);\n+        }\n+      }\n+\n+      return new ValueMatcher()\n+      {\n+        @Override\n+        public boolean matches()\n+        {\n+          final IndexedInts row = selector.getRow();\n+          final int size = row.size();\n+          if (size == 0) {\n+            // null should match empty rows in multi-value columns\n+            return matchNull;\n+          } else {\n+            for (int i = 0; i < size; ++i) {\n+              if (valueIds.get(row.get(i))) {\n+                return true;\n+              }\n+            }\n+            return false;\n+          }\n+        }\n+      };\n+    } else {\n+      // Not dictionary-encoded. Skip the optimization.\n+      return new ValueMatcher()\n+      {\n+        @Override\n+        public boolean matches()\n+        {\n+          final IndexedInts row = selector.getRow();\n+          final int size = row.size();\n+          if (size == 0) {\n+            // null should match empty rows in multi-value columns\n+            return matchNull;\n+          } else {\n+            for (int i = 0; i < size; ++i) {\n+              if (predicate.apply(selector.lookupName(row.get(i)))) {\n+                return true;\n+              }\n+            }\n+            return false;\n+          }\n+        }\n+      };\n+    }\n+  }\n+\n+  public void hashRow(Object dimSelector, Hasher hasher)\n+  {\n+    final DimensionSelector selector = (DimensionSelector) dimSelector;\n+    final IndexedInts row = selector.getRow();\n+    final int size = row.size();\n+    // nothing to add to hasher if size == 0, only handle size == 1 and size != 0 cases.\n+    if (size == 1) {\n+      final String value = selector.lookupName(row.get(0));\n+      hasher.putUnencodedChars(value != null ? value : CardinalityAggregator.NULL_STRING);\n+    } else if (size != 0) {\n+      final String[] values = new String[size];\n+      for (int i = 0; i < size; ++i) {\n+        final String value = selector.lookupName(row.get(i));\n+        values[i] = value != null ? value : CardinalityAggregator.NULL_STRING;\n+      }\n+      // Values need to be sorted to ensure consistent multi-value ordering across different segments\n+      Arrays.sort(values);\n+      for (int i = 0; i < size; ++i) {\n+        if (i != 0) {\n+          hasher.putChar(CardinalityAggregator.SEPARATOR);\n+        }\n+        hasher.putUnencodedChars(values[i]);\n+      }\n+    }\n+  }\n+\n+  public void hashValues(Object dimSelector, HyperLogLogCollector collector)\n+  {\n+    final DimensionSelector selector = (DimensionSelector) dimSelector;\n+    for (final Integer index : selector.getRow()) {\n+      final String value = selector.lookupName(index);\n+      collector.add(CardinalityAggregator.hashFn.hashUnencodedChars(value == null ? CardinalityAggregator.NULL_STRING : value).asBytes());\n+    }\n+  }\n+\n+  @Override\n+  public int getGroupingKeySize()\n+  {\n+    return Ints.BYTES;\n+  }\n+\n+  @Override\n+  public Comparator<byte[]> getGroupingKeyByteComparator()\n+  {\n+    return GROUPING_KEY_COMPARATOR;\n+  }\n+\n+  @Override\n+  public void readDimValueFromGroupingKey(\n+      Map<String, Object> theEvent, String outputName, Object dimSelector, ByteBuffer keyBuffer\n+  )\n+  {\n+    final DimensionSelector selector = (DimensionSelector) dimSelector;\n+    final int dimVal = keyBuffer.getInt();\n+    if (dimVal != GROUP_BY_MISSING_VALUE) {\n+      theEvent.put(outputName, selector.lookupName(dimVal));\n+    }\n+  }\n+\n+  @Override\n+  public List<ByteBuffer> addDimValuesToGroupingKey(\n+      Object selector, ByteBuffer key, Function<ByteBuffer, List<ByteBuffer>> updateValuesFn\n+  )\n+  {\n+    List<ByteBuffer> unaggregatedBuffers = null;\n+    final DimensionSelector dimSelector = (DimensionSelector) selector;\n+    final IndexedInts row = dimSelector.getRow();\n+    if (row == null || row.size() == 0) {\n+      ByteBuffer newKey = key.duplicate();\n+      newKey.putInt(GROUP_BY_MISSING_VALUE);\n+      unaggregatedBuffers = updateValuesFn.apply(newKey);\n+    } else {\n+      for (Integer dimValue : row) {\n+        ByteBuffer newKey = key.duplicate();\n+        newKey.putInt(dimValue);\n+        unaggregatedBuffers = updateValuesFn.apply(newKey);\n+      }\n+    }\n+    return unaggregatedBuffers;\n+  }\n+\n+  @Override\n+  public Object getRowFromDimSelector(Object dimSelector) {\n+    final DimensionSelector selector = (DimensionSelector) dimSelector;\n+    IndexedInts values = selector == null ? EmptyIndexedInts.EMPTY_INDEXED_INTS : selector.getRow();\n+    return values;\n+  }\n+\n+  @Override\n+  public int initializeGroupingKeyV2Dimension(\n+      final Object valuesObj,\n+      final ByteBuffer keyBuffer,\n+      final int keyBufferPosition\n+  )\n+  {\n+    IndexedInts values = (IndexedInts) valuesObj;\n+    final int rowSize = values.size();\n+    if (rowSize == 0) {\n+      keyBuffer.putInt(keyBufferPosition, GROUP_BY_MISSING_VALUE);\n+    } else {\n+      keyBuffer.putInt(keyBufferPosition, values.get(0));\n+    }\n+    return rowSize;\n+  }\n+\n+  @Override\n+  public void addValueToGroupingKeyV2(\n+      final Object values,\n+      final int rowValueIdx,\n+      final ByteBuffer keyBuffer,\n+      final int keyBufferPosition\n+  )\n+  {\n+    IndexedInts intValues = (IndexedInts) values;\n+    keyBuffer.putInt(\n+        keyBufferPosition,\n+        intValues.get(rowValueIdx)\n+    );\n+  }\n+\n+  @Override\n+  public void readValueFromGroupingKeyV2(QueryDimensionInfo dimInfo, Map<String, Object> resultMap, ByteBuffer key)\n+  {\n+    final int id = key.getInt(dimInfo.keyBufferPosition);\n+\n+    if (id >= 0) {\n+      resultMap.put(\n+          dimInfo.spec.getOutputName(),\n+          ((DimensionSelector) dimInfo.selector).lookupName(id)\n+      );\n+    }\n+  }\n+\n+  @Override\n+  public Aggregator[][] getDimExtractionRowSelector(TopNParams params, TopNQuery query, Capabilities capabilities)\n+  {\n+    final BaseTopNAlgorithm.AggregatorArrayProvider provider = new BaseTopNAlgorithm.AggregatorArrayProvider(\n+        (DimensionSelector) params.getDimSelector(),\n+        query,\n+        params.getCardinality(),\n+        capabilities\n+    );\n+\n+    // Unlike regular topN we cannot rely on ordering to optimize.","path":"processing/src/main/java/io/druid/segment/StringDimensionQueryHelper.java","position":364,"original_position":367,"commit_id":"1cf3832de61a4088730e7182a05e7471196fa36e","original_commit_id":"97d716d906c54ab084c8a21c7657480b1a5b0481","user":{"login":"jon-wei","id":8729063,"avatar_url":"https://avatars.githubusercontent.com/u/8729063?v=3","gravatar_id":"","url":"https://api.github.com/users/jon-wei","html_url":"https://github.com/jon-wei","followers_url":"https://api.github.com/users/jon-wei/followers","following_url":"https://api.github.com/users/jon-wei/following{/other_user}","gists_url":"https://api.github.com/users/jon-wei/gists{/gist_id}","starred_url":"https://api.github.com/users/jon-wei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jon-wei/subscriptions","organizations_url":"https://api.github.com/users/jon-wei/orgs","repos_url":"https://api.github.com/users/jon-wei/repos","events_url":"https://api.github.com/users/jon-wei/events{/privacy}","received_events_url":"https://api.github.com/users/jon-wei/received_events","type":"User","site_admin":false},"body":"The comment was copied over from the original location in DimExtractionTopNAlgorithm, it refers to why DimExtractionTopNAlgorithm would be used instead of other TopNAlgorithms (see getMapFn() in TopNQueryEngine)\r\n","created_at":"2016-11-11T03:01:59Z","updated_at":"2016-11-11T03:01:59Z","html_url":"https://github.com/druid-io/druid/pull/3570#discussion_r87530434","pull_request_url":"https://api.github.com/repos/druid-io/druid/pulls/3570","_links":{"self":{"href":"https://api.github.com/repos/druid-io/druid/pulls/comments/87530434"},"html":{"href":"https://github.com/druid-io/druid/pull/3570#discussion_r87530434"},"pull_request":{"href":"https://api.github.com/repos/druid-io/druid/pulls/3570"}}},"pull_request":{"url":"https://api.github.com/repos/druid-io/druid/pulls/3570","id":89458241,"html_url":"https://github.com/druid-io/druid/pull/3570","diff_url":"https://github.com/druid-io/druid/pull/3570.diff","patch_url":"https://github.com/druid-io/druid/pull/3570.patch","issue_url":"https://api.github.com/repos/druid-io/druid/issues/3570","number":3570,"state":"open","locked":false,"title":"Add dimension type-based interface for query processing","user":{"login":"jon-wei","id":8729063,"avatar_url":"https://avatars.githubusercontent.com/u/8729063?v=3","gravatar_id":"","url":"https://api.github.com/users/jon-wei","html_url":"https://github.com/jon-wei","followers_url":"https://api.github.com/users/jon-wei/followers","following_url":"https://api.github.com/users/jon-wei/following{/other_user}","gists_url":"https://api.github.com/users/jon-wei/gists{/gist_id}","starred_url":"https://api.github.com/users/jon-wei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jon-wei/subscriptions","organizations_url":"https://api.github.com/users/jon-wei/orgs","repos_url":"https://api.github.com/users/jon-wei/repos","events_url":"https://api.github.com/users/jon-wei/events{/privacy}","received_events_url":"https://api.github.com/users/jon-wei/received_events","type":"User","site_admin":false},"body":"This PR is a continuation of https://github.com/druid-io/druid/pull/3217, adding an interface that handles type-specific processing within the query engines, along with a String implementation of that interface.\n\nSee DimensionQueryHelper for the new interface.\n\nNote: This does not include support for longs/floats, and additional work is needed on query result merging for full non-String support.\n\n---\n\nBenchmarks\n\nmaster, on ec2 c4.8xlarge:\n\n```\nBenchmark                                              (defaultStrategy)  (initialBuckets)  (limit)  (numProcessingThreads)  (numSegments)  (pagingThreshold)  (rowsPerSegment)              (schemaAndQuery)  (threshold)  Mode  Cnt        Score        Error  Units\nGroupByBenchmark.queryMultiQueryableIndex                             v1                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50   554282.566 ±   7520.915  us/op\nGroupByBenchmark.queryMultiQueryableIndex                             v1                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   637817.206 ±   9380.033  us/op\nGroupByBenchmark.queryMultiQueryableIndex                             v2                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50   306662.606 ±   6405.133  us/op\nGroupByBenchmark.queryMultiQueryableIndex                             v2                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   370571.020 ±   6056.274  us/op\n\nGroupByBenchmark.querySingleIncrementalIndex                          v1                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50   258864.584 ±   3177.654  us/op\nGroupByBenchmark.querySingleIncrementalIndex                          v1                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   296594.768 ±   2803.593  us/op\nGroupByBenchmark.querySingleIncrementalIndex                          v2                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50    69639.640 ±    472.956  us/op\nGroupByBenchmark.querySingleIncrementalIndex                          v2                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   105713.374 ±   1459.826  us/op\n\nGroupByBenchmark.querySingleQueryableIndex                            v1                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50   215434.094 ±   2167.322  us/op\nGroupByBenchmark.querySingleQueryableIndex                            v1                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   268212.848 ±   2624.511  us/op\nGroupByBenchmark.querySingleQueryableIndex                            v2                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50    36921.928 ±    322.074  us/op\nGroupByBenchmark.querySingleQueryableIndex                            v2                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50    50261.078 ±    564.743  us/op\n\nSearchBenchmark.queryMultiQueryableIndex                             N/A               N/A     1000                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50    19850.613 ±    142.000  us/op\nSearchBenchmark.querySingleIncrementalIndex                          N/A               N/A     1000                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50   275066.237 ±  38088.117  us/op\nSearchBenchmark.querySingleQueryableIndex                            N/A               N/A     1000                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50    19343.501 ±    115.814  us/op\n\nSelectBenchmark.queryIncrementalIndex                                N/A               N/A      N/A                     N/A              1               1000             25000                       basic.A          N/A  avgt   50    57188.509 ±    424.254  us/op\nSelectBenchmark.queryMultiQueryableIndex                             N/A               N/A      N/A                     N/A              1               1000             25000                       basic.A          N/A  avgt   50    85750.294 ±    644.991  us/op\nSelectBenchmark.queryQueryableIndex                                  N/A               N/A      N/A                     N/A              1               1000             25000                       basic.A          N/A  avgt   50    77596.627 ±    555.957  us/op\n\nTimeseriesBenchmark.queryFilteredSingleQueryableIndex                N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50    10323.617 ±    416.767  us/op\nTimeseriesBenchmark.queryFilteredSingleQueryableIndex                N/A               N/A      N/A                     N/A              1                N/A            750000       basic.timeFilterNumeric          N/A  avgt   50     6322.936 ±    115.667  us/op\nTimeseriesBenchmark.queryFilteredSingleQueryableIndex                N/A               N/A      N/A                     N/A              1                N/A            750000  basic.timeFilterAlphanumeric          N/A  avgt   50     6419.686 ±    149.413  us/op\nTimeseriesBenchmark.queryFilteredSingleQueryableIndex                N/A               N/A      N/A                     N/A              1                N/A            750000    basic.timeFilterByInterval          N/A  avgt   50     2465.433 ±     40.162  us/op\n\nTimeseriesBenchmark.queryMultiQueryableIndex                         N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50   117792.386 ±    661.203  us/op\nTimeseriesBenchmark.queryMultiQueryableIndex                         N/A               N/A      N/A                     N/A              1                N/A            750000       basic.timeFilterNumeric          N/A  avgt   50    18851.278 ±     53.420  us/op\nTimeseriesBenchmark.queryMultiQueryableIndex                         N/A               N/A      N/A                     N/A              1                N/A            750000  basic.timeFilterAlphanumeric          N/A  avgt   50   103451.371 ±  10362.037  us/op\nTimeseriesBenchmark.queryMultiQueryableIndex                         N/A               N/A      N/A                     N/A              1                N/A            750000    basic.timeFilterByInterval          N/A  avgt   50     7404.500 ±     21.724  us/op\n\nTimeseriesBenchmark.querySingleIncrementalIndex                      N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50  1472730.756 ±  18902.496  us/op\nTimeseriesBenchmark.querySingleIncrementalIndex                      N/A               N/A      N/A                     N/A              1                N/A            750000       basic.timeFilterNumeric          N/A  avgt   50    68570.272 ±   7168.122  us/op\nTimeseriesBenchmark.querySingleIncrementalIndex                      N/A               N/A      N/A                     N/A              1                N/A            750000  basic.timeFilterAlphanumeric          N/A  avgt   50   142299.159 ±   3247.576  us/op\nTimeseriesBenchmark.querySingleIncrementalIndex                      N/A               N/A      N/A                     N/A              1                N/A            750000    basic.timeFilterByInterval          N/A  avgt   50    15521.080 ±    653.871  us/op\n\nTimeseriesBenchmark.querySingleQueryableIndex                        N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50   126410.787 ±   1543.988  us/op\nTimeseriesBenchmark.querySingleQueryableIndex                        N/A               N/A      N/A                     N/A              1                N/A            750000       basic.timeFilterNumeric          N/A  avgt   50    18682.817 ±     48.007  us/op\nTimeseriesBenchmark.querySingleQueryableIndex                        N/A               N/A      N/A                     N/A              1                N/A            750000  basic.timeFilterAlphanumeric          N/A  avgt   50    99198.913 ±   2113.965  us/op\nTimeseriesBenchmark.querySingleQueryableIndex                        N/A               N/A      N/A                     N/A              1                N/A            750000    basic.timeFilterByInterval          N/A  avgt   50     7409.440 ±     16.413  us/op\n\nTopNBenchmark.queryMultiQueryableIndex                               N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A           10  avgt   50   154567.890 ±   1424.878  us/op\nTopNBenchmark.queryMultiQueryableIndex                               N/A               N/A      N/A                     N/A              1                N/A            750000             basic.numericSort           10  avgt   50   672519.884 ±   3612.674  us/op\nTopNBenchmark.queryMultiQueryableIndex                               N/A               N/A      N/A                     N/A              1                N/A            750000        basic.alphanumericSort           10  avgt   50   616865.834 ±   3509.284  us/op\n\nTopNBenchmark.querySingleIncrementalIndex                            N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A           10  avgt   50  1440780.167 ±  28955.474  us/op\nTopNBenchmark.querySingleIncrementalIndex                            N/A               N/A      N/A                     N/A              1                N/A            750000             basic.numericSort           10  avgt   50   487580.095 ±  18331.669  us/op\nTopNBenchmark.querySingleIncrementalIndex                            N/A               N/A      N/A                     N/A              1                N/A            750000        basic.alphanumericSort           10  avgt   50   448849.362 ±   1951.610  us/op\n\nTopNBenchmark.querySingleQueryableIndex                              N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A           10  avgt   50   151013.283 ±   2006.581  us/op\nTopNBenchmark.querySingleQueryableIndex                              N/A               N/A      N/A                     N/A              1                N/A            750000             basic.numericSort           10  avgt   50   287638.724 ±   2931.862  us/op\nTopNBenchmark.querySingleQueryableIndex                              N/A               N/A      N/A                     N/A              1                N/A            750000        basic.alphanumericSort           10  avgt   50   288567.584 ±   1975.228  us/op\n```\n\nwith patch\n\n```\nBenchmark                                              (defaultStrategy)  (initialBuckets)  (limit)  (numProcessingThreads)  (numSegments)  (pagingThreshold)  (rowsPerSegment)              (schemaAndQuery)  (threshold)  Mode  Cnt        Score       Error  Units\nGroupByBenchmark.queryMultiQueryableIndex                             v1                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50   530030.767 ±  7377.015  us/op\nGroupByBenchmark.queryMultiQueryableIndex                             v1                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   621539.736 ±  6936.704  us/op\nGroupByBenchmark.queryMultiQueryableIndex                             v2                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50   300317.648 ±  5070.978  us/op\nGroupByBenchmark.queryMultiQueryableIndex                             v2                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   386036.408 ±  6684.521  us/op\n\nGroupByBenchmark.querySingleIncrementalIndex                          v1                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50   256456.989 ±  2557.561  us/op\nGroupByBenchmark.querySingleIncrementalIndex                          v1                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   303315.479 ±  3861.128  us/op\nGroupByBenchmark.querySingleIncrementalIndex                          v2                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50    71541.673 ±  2846.291  us/op\nGroupByBenchmark.querySingleIncrementalIndex                          v2                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   107898.701 ±  1670.923  us/op\n\nGroupByBenchmark.querySingleQueryableIndex                            v1                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50   198084.002 ±  1497.913  us/op\nGroupByBenchmark.querySingleQueryableIndex                            v1                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50   258655.466 ±  1636.346  us/op\nGroupByBenchmark.querySingleQueryableIndex                            v2                -1      N/A                       4              4                N/A            100000                       basic.A          N/A  avgt   50    36901.443 ±   492.361  us/op\nGroupByBenchmark.querySingleQueryableIndex                            v2                -1      N/A                       4              4                N/A            100000                  basic.nested          N/A  avgt   50    51540.719 ±   420.109  us/op\n\nSearchBenchmark.queryMultiQueryableIndex                             N/A               N/A     1000                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50    19596.676 ±   112.045  us/op\nSearchBenchmark.querySingleIncrementalIndex                          N/A               N/A     1000                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50   274717.341 ± 11173.318  us/op\nSearchBenchmark.querySingleQueryableIndex                            N/A               N/A     1000                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50    19917.239 ±    71.564  us/op\n\nSelectBenchmark.queryIncrementalIndex                                N/A               N/A      N/A                     N/A              1               1000             25000                       basic.A          N/A  avgt   50    59473.600 ±   571.223  us/op\nSelectBenchmark.queryMultiQueryableIndex                             N/A               N/A      N/A                     N/A              1               1000             25000                       basic.A          N/A  avgt   50    81695.908 ±   616.253  us/op\nSelectBenchmark.queryQueryableIndex                                  N/A               N/A      N/A                     N/A              1               1000             25000                       basic.A          N/A  avgt   50    80691.158 ±   519.358  us/op\n\nTimeseriesBenchmark.queryFilteredSingleQueryableIndex                N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50    10205.503 ±    15.472  us/op\nTimeseriesBenchmark.queryFilteredSingleQueryableIndex                N/A               N/A      N/A                     N/A              1                N/A            750000       basic.timeFilterNumeric          N/A  avgt   50     6290.620 ±    15.773  us/op\nTimeseriesBenchmark.queryFilteredSingleQueryableIndex                N/A               N/A      N/A                     N/A              1                N/A            750000  basic.timeFilterAlphanumeric          N/A  avgt   50     6471.658 ±   299.896  us/op\nTimeseriesBenchmark.queryFilteredSingleQueryableIndex                N/A               N/A      N/A                     N/A              1                N/A            750000    basic.timeFilterByInterval          N/A  avgt   50     2479.302 ±    59.828  us/op\n\nTimeseriesBenchmark.queryMultiQueryableIndex                         N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50   120032.731 ±   621.255  us/op\nTimeseriesBenchmark.queryMultiQueryableIndex                         N/A               N/A      N/A                     N/A              1                N/A            750000       basic.timeFilterNumeric          N/A  avgt   50    18943.730 ±    65.554  us/op\nTimeseriesBenchmark.queryMultiQueryableIndex                         N/A               N/A      N/A                     N/A              1                N/A            750000  basic.timeFilterAlphanumeric          N/A  avgt   50   100933.078 ±  2310.198  us/op\nTimeseriesBenchmark.queryMultiQueryableIndex                         N/A               N/A      N/A                     N/A              1                N/A            750000    basic.timeFilterByInterval          N/A  avgt   50     7436.541 ±    17.117  us/op\n\nTimeseriesBenchmark.querySingleIncrementalIndex                      N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50  1475372.472 ± 18449.360  us/op\nTimeseriesBenchmark.querySingleIncrementalIndex                      N/A               N/A      N/A                     N/A              1                N/A            750000       basic.timeFilterNumeric          N/A  avgt   50    71939.309 ±  2731.547  us/op\nTimeseriesBenchmark.querySingleIncrementalIndex                      N/A               N/A      N/A                     N/A              1                N/A            750000  basic.timeFilterAlphanumeric          N/A  avgt   50   141903.521 ±  5035.643  us/op\nTimeseriesBenchmark.querySingleIncrementalIndex                      N/A               N/A      N/A                     N/A              1                N/A            750000    basic.timeFilterByInterval          N/A  avgt   50    16727.688 ±  1267.306  us/op\n\nTimeseriesBenchmark.querySingleQueryableIndex                        N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A          N/A  avgt   50   116995.377 ±   615.622  us/op\nTimeseriesBenchmark.querySingleQueryableIndex                        N/A               N/A      N/A                     N/A              1                N/A            750000       basic.timeFilterNumeric          N/A  avgt   50    19125.325 ±    48.044  us/op\nTimeseriesBenchmark.querySingleQueryableIndex                        N/A               N/A      N/A                     N/A              1                N/A            750000  basic.timeFilterAlphanumeric          N/A  avgt   50    98972.813 ±  1321.584  us/op\nTimeseriesBenchmark.querySingleQueryableIndex                        N/A               N/A      N/A                     N/A              1                N/A            750000    basic.timeFilterByInterval          N/A  avgt   50     7352.158 ±    15.437  us/op\n\nTopNBenchmark.queryMultiQueryableIndex                               N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A           10  avgt   50   152508.462 ±   987.978  us/op\nTopNBenchmark.queryMultiQueryableIndex                               N/A               N/A      N/A                     N/A              1                N/A            750000             basic.numericSort           10  avgt   50   679353.675 ±  2679.153  us/op\nTopNBenchmark.queryMultiQueryableIndex                               N/A               N/A      N/A                     N/A              1                N/A            750000        basic.alphanumericSort           10  avgt   50   622041.620 ±  2630.078  us/op\n\nTopNBenchmark.querySingleIncrementalIndex                            N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A           10  avgt   50  1442705.970 ± 26961.480  us/op\nTopNBenchmark.querySingleIncrementalIndex                            N/A               N/A      N/A                     N/A              1                N/A            750000             basic.numericSort           10  avgt   50   509306.590 ± 20151.568  us/op\nTopNBenchmark.querySingleIncrementalIndex                            N/A               N/A      N/A                     N/A              1                N/A            750000        basic.alphanumericSort           10  avgt   50   463259.929 ±  9762.551  us/op\n\nTopNBenchmark.querySingleQueryableIndex                              N/A               N/A      N/A                     N/A              1                N/A            750000                       basic.A           10  avgt   50   143790.261 ±   813.707  us/op\nTopNBenchmark.querySingleQueryableIndex                              N/A               N/A      N/A                     N/A              1                N/A            750000             basic.numericSort           10  avgt   50   303716.142 ±  7365.814  us/op\nTopNBenchmark.querySingleQueryableIndex                              N/A               N/A      N/A                     N/A              1                N/A            750000        basic.alphanumericSort           10  avgt   50   280224.281 ±  2190.230  us/op\n```\n","created_at":"2016-10-14T21:32:17Z","updated_at":"2016-11-11T03:01:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9dfa202e45c1143433a5efc49fd17afff00d8bfc","assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/druid-io/druid/milestones/21","html_url":"https://github.com/druid-io/druid/milestones/0.9.3","labels_url":"https://api.github.com/repos/druid-io/druid/milestones/21/labels","id":1831000,"number":21,"title":"0.9.3","description":"","creator":{"login":"fjy","id":428325,"avatar_url":"https://avatars.githubusercontent.com/u/428325?v=3","gravatar_id":"","url":"https://api.github.com/users/fjy","html_url":"https://github.com/fjy","followers_url":"https://api.github.com/users/fjy/followers","following_url":"https://api.github.com/users/fjy/following{/other_user}","gists_url":"https://api.github.com/users/fjy/gists{/gist_id}","starred_url":"https://api.github.com/users/fjy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fjy/subscriptions","organizations_url":"https://api.github.com/users/fjy/orgs","repos_url":"https://api.github.com/users/fjy/repos","events_url":"https://api.github.com/users/fjy/events{/privacy}","received_events_url":"https://api.github.com/users/fjy/received_events","type":"User","site_admin":false},"open_issues":57,"closed_issues":63,"state":"open","created_at":"2016-06-15T22:35:58Z","updated_at":"2016-11-10T20:55:52Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/druid-io/druid/pulls/3570/commits","review_comments_url":"https://api.github.com/repos/druid-io/druid/pulls/3570/comments","review_comment_url":"https://api.github.com/repos/druid-io/druid/pulls/comments{/number}","comments_url":"https://api.github.com/repos/druid-io/druid/issues/3570/comments","statuses_url":"https://api.github.com/repos/druid-io/druid/statuses/1cf3832de61a4088730e7182a05e7471196fa36e","head":{"label":"jon-wei:dimtype_pt2","ref":"dimtype_pt2","sha":"1cf3832de61a4088730e7182a05e7471196fa36e","user":{"login":"jon-wei","id":8729063,"avatar_url":"https://avatars.githubusercontent.com/u/8729063?v=3","gravatar_id":"","url":"https://api.github.com/users/jon-wei","html_url":"https://github.com/jon-wei","followers_url":"https://api.github.com/users/jon-wei/followers","following_url":"https://api.github.com/users/jon-wei/following{/other_user}","gists_url":"https://api.github.com/users/jon-wei/gists{/gist_id}","starred_url":"https://api.github.com/users/jon-wei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jon-wei/subscriptions","organizations_url":"https://api.github.com/users/jon-wei/orgs","repos_url":"https://api.github.com/users/jon-wei/repos","events_url":"https://api.github.com/users/jon-wei/events{/privacy}","received_events_url":"https://api.github.com/users/jon-wei/received_events","type":"User","site_admin":false},"repo":{"id":41450391,"name":"druid","full_name":"jon-wei/druid","owner":{"login":"jon-wei","id":8729063,"avatar_url":"https://avatars.githubusercontent.com/u/8729063?v=3","gravatar_id":"","url":"https://api.github.com/users/jon-wei","html_url":"https://github.com/jon-wei","followers_url":"https://api.github.com/users/jon-wei/followers","following_url":"https://api.github.com/users/jon-wei/following{/other_user}","gists_url":"https://api.github.com/users/jon-wei/gists{/gist_id}","starred_url":"https://api.github.com/users/jon-wei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jon-wei/subscriptions","organizations_url":"https://api.github.com/users/jon-wei/orgs","repos_url":"https://api.github.com/users/jon-wei/repos","events_url":"https://api.github.com/users/jon-wei/events{/privacy}","received_events_url":"https://api.github.com/users/jon-wei/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jon-wei/druid","description":"Column oriented distributed data store ideal for powering interactive applications","fork":true,"url":"https://api.github.com/repos/jon-wei/druid","forks_url":"https://api.github.com/repos/jon-wei/druid/forks","keys_url":"https://api.github.com/repos/jon-wei/druid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jon-wei/druid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jon-wei/druid/teams","hooks_url":"https://api.github.com/repos/jon-wei/druid/hooks","issue_events_url":"https://api.github.com/repos/jon-wei/druid/issues/events{/number}","events_url":"https://api.github.com/repos/jon-wei/druid/events","assignees_url":"https://api.github.com/repos/jon-wei/druid/assignees{/user}","branches_url":"https://api.github.com/repos/jon-wei/druid/branches{/branch}","tags_url":"https://api.github.com/repos/jon-wei/druid/tags","blobs_url":"https://api.github.com/repos/jon-wei/druid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jon-wei/druid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jon-wei/druid/git/refs{/sha}","trees_url":"https://api.github.com/repos/jon-wei/druid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jon-wei/druid/statuses/{sha}","languages_url":"https://api.github.com/repos/jon-wei/druid/languages","stargazers_url":"https://api.github.com/repos/jon-wei/druid/stargazers","contributors_url":"https://api.github.com/repos/jon-wei/druid/contributors","subscribers_url":"https://api.github.com/repos/jon-wei/druid/subscribers","subscription_url":"https://api.github.com/repos/jon-wei/druid/subscription","commits_url":"https://api.github.com/repos/jon-wei/druid/commits{/sha}","git_commits_url":"https://api.github.com/repos/jon-wei/druid/git/commits{/sha}","comments_url":"https://api.github.com/repos/jon-wei/druid/comments{/number}","issue_comment_url":"https://api.github.com/repos/jon-wei/druid/issues/comments{/number}","contents_url":"https://api.github.com/repos/jon-wei/druid/contents/{+path}","compare_url":"https://api.github.com/repos/jon-wei/druid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jon-wei/druid/merges","archive_url":"https://api.github.com/repos/jon-wei/druid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jon-wei/druid/downloads","issues_url":"https://api.github.com/repos/jon-wei/druid/issues{/number}","pulls_url":"https://api.github.com/repos/jon-wei/druid/pulls{/number}","milestones_url":"https://api.github.com/repos/jon-wei/druid/milestones{/number}","notifications_url":"https://api.github.com/repos/jon-wei/druid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jon-wei/druid/labels{/name}","releases_url":"https://api.github.com/repos/jon-wei/druid/releases{/id}","deployments_url":"https://api.github.com/repos/jon-wei/druid/deployments","created_at":"2015-08-26T21:18:05Z","updated_at":"2016-01-12T02:23:00Z","pushed_at":"2016-11-10T21:22:24Z","git_url":"git://github.com/jon-wei/druid.git","ssh_url":"git@github.com:jon-wei/druid.git","clone_url":"https://github.com/jon-wei/druid.git","svn_url":"https://github.com/jon-wei/druid","homepage":"http://druid.io","size":116289,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"druid-io:master","ref":"master","sha":"1acc816196c8723d121915ab1f7c33de3fbfacd4","user":{"login":"druid-io","id":4203474,"avatar_url":"https://avatars.githubusercontent.com/u/4203474?v=3","gravatar_id":"","url":"https://api.github.com/users/druid-io","html_url":"https://github.com/druid-io","followers_url":"https://api.github.com/users/druid-io/followers","following_url":"https://api.github.com/users/druid-io/following{/other_user}","gists_url":"https://api.github.com/users/druid-io/gists{/gist_id}","starred_url":"https://api.github.com/users/druid-io/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/druid-io/subscriptions","organizations_url":"https://api.github.com/users/druid-io/orgs","repos_url":"https://api.github.com/users/druid-io/repos","events_url":"https://api.github.com/users/druid-io/events{/privacy}","received_events_url":"https://api.github.com/users/druid-io/received_events","type":"Organization","site_admin":false},"repo":{"id":6358188,"name":"druid","full_name":"druid-io/druid","owner":{"login":"druid-io","id":4203474,"avatar_url":"https://avatars.githubusercontent.com/u/4203474?v=3","gravatar_id":"","url":"https://api.github.com/users/druid-io","html_url":"https://github.com/druid-io","followers_url":"https://api.github.com/users/druid-io/followers","following_url":"https://api.github.com/users/druid-io/following{/other_user}","gists_url":"https://api.github.com/users/druid-io/gists{/gist_id}","starred_url":"https://api.github.com/users/druid-io/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/druid-io/subscriptions","organizations_url":"https://api.github.com/users/druid-io/orgs","repos_url":"https://api.github.com/users/druid-io/repos","events_url":"https://api.github.com/users/druid-io/events{/privacy}","received_events_url":"https://api.github.com/users/druid-io/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/druid-io/druid","description":"Column oriented distributed data store ideal for powering interactive applications","fork":false,"url":"https://api.github.com/repos/druid-io/druid","forks_url":"https://api.github.com/repos/druid-io/druid/forks","keys_url":"https://api.github.com/repos/druid-io/druid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/druid-io/druid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/druid-io/druid/teams","hooks_url":"https://api.github.com/repos/druid-io/druid/hooks","issue_events_url":"https://api.github.com/repos/druid-io/druid/issues/events{/number}","events_url":"https://api.github.com/repos/druid-io/druid/events","assignees_url":"https://api.github.com/repos/druid-io/druid/assignees{/user}","branches_url":"https://api.github.com/repos/druid-io/druid/branches{/branch}","tags_url":"https://api.github.com/repos/druid-io/druid/tags","blobs_url":"https://api.github.com/repos/druid-io/druid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/druid-io/druid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/druid-io/druid/git/refs{/sha}","trees_url":"https://api.github.com/repos/druid-io/druid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/druid-io/druid/statuses/{sha}","languages_url":"https://api.github.com/repos/druid-io/druid/languages","stargazers_url":"https://api.github.com/repos/druid-io/druid/stargazers","contributors_url":"https://api.github.com/repos/druid-io/druid/contributors","subscribers_url":"https://api.github.com/repos/druid-io/druid/subscribers","subscription_url":"https://api.github.com/repos/druid-io/druid/subscription","commits_url":"https://api.github.com/repos/druid-io/druid/commits{/sha}","git_commits_url":"https://api.github.com/repos/druid-io/druid/git/commits{/sha}","comments_url":"https://api.github.com/repos/druid-io/druid/comments{/number}","issue_comment_url":"https://api.github.com/repos/druid-io/druid/issues/comments{/number}","contents_url":"https://api.github.com/repos/druid-io/druid/contents/{+path}","compare_url":"https://api.github.com/repos/druid-io/druid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/druid-io/druid/merges","archive_url":"https://api.github.com/repos/druid-io/druid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/druid-io/druid/downloads","issues_url":"https://api.github.com/repos/druid-io/druid/issues{/number}","pulls_url":"https://api.github.com/repos/druid-io/druid/pulls{/number}","milestones_url":"https://api.github.com/repos/druid-io/druid/milestones{/number}","notifications_url":"https://api.github.com/repos/druid-io/druid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/druid-io/druid/labels{/name}","releases_url":"https://api.github.com/repos/druid-io/druid/releases{/id}","deployments_url":"https://api.github.com/repos/druid-io/druid/deployments","created_at":"2012-10-23T19:08:07Z","updated_at":"2016-11-10T22:59:31Z","pushed_at":"2016-11-10T22:24:01Z","git_url":"git://github.com/druid-io/druid.git","ssh_url":"git@github.com:druid-io/druid.git","clone_url":"https://github.com/druid-io/druid.git","svn_url":"https://github.com/druid-io/druid","homepage":"http://druid.io","size":164962,"stargazers_count":3963,"watchers_count":3963,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":943,"mirror_url":null,"open_issues_count":567,"forks":943,"open_issues":567,"watchers":3963,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/druid-io/druid/pulls/3570"},"html":{"href":"https://github.com/druid-io/druid/pull/3570"},"issue":{"href":"https://api.github.com/repos/druid-io/druid/issues/3570"},"comments":{"href":"https://api.github.com/repos/druid-io/druid/issues/3570/comments"},"review_comments":{"href":"https://api.github.com/repos/druid-io/druid/pulls/3570/comments"},"review_comment":{"href":"https://api.github.com/repos/druid-io/druid/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/druid-io/druid/pulls/3570/commits"},"statuses":{"href":"https://api.github.com/repos/druid-io/druid/statuses/1cf3832de61a4088730e7182a05e7471196fa36e"}}}}
{"actor":{"display_login":"jon-wei"}}