You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by nf...@apache.org on 2024/06/10 12:32:40 UTC

(jackrabbit-oak) branch trunk updated: OAK-10866 - Avoid creating an intermediate String when appending a string value to a JsopBuilder. (#1511)

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

nfsantos pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 998e3ad8f4 OAK-10866 - Avoid creating an intermediate String when appending a string value to a JsopBuilder. (#1511)
998e3ad8f4 is described below

commit 998e3ad8f49f7760ae2c775373b1ea4b3698ca36
Author: Nuno Santos <ns...@adobe.com>
AuthorDate: Mon Jun 10 14:32:34 2024 +0200

    OAK-10866 - Avoid creating an intermediate String when appending a string value to a JsopBuilder. (#1511)
---
 .../jackrabbit/oak/commons/json/JsopBuilder.java   | 41 ++++++++++++++++++++--
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/json/JsopBuilder.java b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/json/JsopBuilder.java
index ecfc75bdcc..6059ef1b73 100644
--- a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/json/JsopBuilder.java
+++ b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/json/JsopBuilder.java
@@ -163,7 +163,7 @@ public class JsopBuilder implements JsopWriter {
         if (JSON_NEWLINES) {
             buff.append('\n');
         }
-        buff.append(encode(name)).append(':');
+        encode(name, buff).append(':');
         needComma = false;
         return this;
     }
@@ -199,7 +199,10 @@ public class JsopBuilder implements JsopWriter {
      */
     @Override
     public JsopBuilder value(String value) {
-        return encodedValue(encode(value));
+        optionalCommaAndNewline(strLength(value));
+        encode(value, buff);
+        needComma = true;
+        return this;
     }
 
     /**
@@ -265,7 +268,7 @@ public class JsopBuilder implements JsopWriter {
         }
         for (int i = 0; i < length; i++) {
             char c = s.charAt(i);
-            if (c == '\"' || c == '\\' || c < ' ' || (c >= 0xd800 && c <= 0xdbff)) {
+            if (shouldEscape(c)) {
                 StringBuilder buff = new StringBuilder(length + 2 + length / 8);
                 buff.append('\"');
                 escape(s, length, buff);
@@ -275,6 +278,34 @@ public class JsopBuilder implements JsopWriter {
         return '\"' + s + '\"';
     }
 
+    /**
+     * Similar to #encode(String) but appends the result to the given buffer. This method exists to avoid the allocation
+     * of intermediate objects to represent the encoded String when the caller already has a buffer where the result
+     * should be appended.
+     *
+     * @param s the text to convert
+     * @param buff the target buffer
+     * @return the target buffer with the encoded string appended
+     */
+    private static StringBuilder encode(String s, StringBuilder buff) {
+        if (s == null) {
+            return buff.append("null");
+        }
+        int length = s.length();
+        if (length == 0) {
+            return buff.append("\"\"");
+        }
+        for (int i = 0; i < length; i++) {
+            char c = s.charAt(i);
+            if (shouldEscape(c)) {
+                buff.append('\"');
+                escape(s, length, buff);
+                return buff.append('\"');
+            }
+        }
+        return buff.append('\"').append(s).append('\"');
+    }
+
     /**
      * Escape a string into the target buffer.
      *
@@ -285,6 +316,10 @@ public class JsopBuilder implements JsopWriter {
         escape(s, s.length(), buff);
     }
 
+    private static boolean shouldEscape(char c) {
+        return c == '\"' || c == '\\' || c < ' ' || (c >= 0xd800 && c <= 0xdbff);
+    }
+
     /**
      * Escape a string for JSON into the target buffer.
      * <p>