You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by GitBox <gi...@apache.org> on 2019/08/01 11:57:46 UTC

[GitHub] [incubator-druid] esevastyanov commented on a change in pull request #8157: Enum of ResponseContext keys

esevastyanov commented on a change in pull request #8157: Enum of ResponseContext keys
URL: https://github.com/apache/incubator-druid/pull/8157#discussion_r309659574
 
 

 ##########
 File path: processing/src/main/java/org/apache/druid/query/context/ResponseContext.java
 ##########
 @@ -76,56 +253,158 @@ public static ResponseContext createEmpty()
     return DefaultResponseContext.createEmpty();
   }
 
-  protected abstract Map<String, Object> getDelegate();
+  /**
+   * Deserializes a string into {@link ResponseContext} using given {@link ObjectMapper}.
+   * @throws IllegalStateException if one of the deserialized map keys has not been registered.
+   */
+  public static ResponseContext deserialize(String responseContext, ObjectMapper objectMapper) throws IOException
+  {
+    final Map<String, Object> keyNameToObjects = objectMapper.readValue(
+        responseContext,
+        JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT
+    );
+    final ResponseContext context = ResponseContext.createEmpty();
+    keyNameToObjects.forEach((keyName, value) -> {
+      final BaseKey key = Key.keyOf(keyName);
+      context.add(key, value);
+    });
+    return context;
+  }
+
+  protected abstract Map<BaseKey, Object> getDelegate();
 
-  public Object put(String key, Object value)
+  /**
+   * Associates the specified object with the specified key.
+   * @throws IllegalStateException if the key has not been registered.
+   */
+  public Object put(BaseKey key, Object value)
   {
-    return getDelegate().put(key, value);
+    final BaseKey registeredKey = Key.keyOf(key.getName());
+    return getDelegate().put(registeredKey, value);
   }
 
-  public Object get(String key)
+  public Object get(BaseKey key)
   {
     return getDelegate().get(key);
   }
 
-  public Object remove(String key)
+  public Object remove(BaseKey key)
   {
     return getDelegate().remove(key);
   }
 
-  public void putAll(Map<? extends String, ?> m)
+  /**
+   * Adds (merges) a new value associated with a key to an old value.
+   * See merge function of a context key for a specific implementation.
+   * @throws IllegalStateException if the key has not been registered.
+   */
+  public Object add(BaseKey key, Object value)
   {
-    getDelegate().putAll(m);
+    final BaseKey registeredKey = Key.keyOf(key.getName());
+    return getDelegate().merge(registeredKey, value, key.getMergeFunction());
   }
 
-  public void putAll(ResponseContext responseContext)
+  /**
+   * Merges a response context into the current.
+   * @throws IllegalStateException If a key of the {@code responseContext} has not been registered.
+   */
+  public void merge(ResponseContext responseContext)
   {
-    getDelegate().putAll(responseContext.getDelegate());
+    responseContext.getDelegate().forEach((key, newValue) -> {
+      if (newValue != null) {
+        add(key, newValue);
+      }
+    });
   }
 
-  public int size()
+  /**
+   * Serializes the context given that the resulting string length is less than the provided limit.
+   * This method tries to remove some elements from context collections if it's needed to satisfy the limit.
+   * The resulting string might be correctly deserialized to {@link ResponseContext}.
+   */
+  public SerializationResult serializeWith(ObjectMapper objectMapper, int maxCharsNumber) throws JsonProcessingException
   {
-    return getDelegate().size();
+    final String fullSerializedString = objectMapper.writeValueAsString(getDelegate());
+    if (fullSerializedString.length() <= maxCharsNumber) {
+      return new SerializationResult(fullSerializedString, fullSerializedString);
+    } else {
+      // Indicates that the context is truncated during serialization.
+      add(Key.TRUNCATED, true);
+      final ObjectNode contextJsonNode = objectMapper.valueToTree(getDelegate());
+      final ArrayList<Map.Entry<String, JsonNode>> sortedNodesByLength = Lists.newArrayList(contextJsonNode.fields());
+      final Comparator<Map.Entry<String, JsonNode>> valueLengthReversedComparator =
+          Comparator.comparing((Map.Entry<String, JsonNode> e) -> e.getValue().toString().length()).reversed();
+      sortedNodesByLength.sort(valueLengthReversedComparator);
+      int needToRemoveCharsNumber = fullSerializedString.length() - maxCharsNumber;
+      // In general, the complexity of this block is O(n*m*log(m)) where n - context size, m - context's array size
+      for (Map.Entry<String, JsonNode> e : sortedNodesByLength) {
 
 Review comment:
   looks nice. updated

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

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