You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2019/07/25 13:41:45 UTC

[johnzon] branch master updated: JOHNZON-218 ensure to not allocate BufferStrategy.BufferProvider in JsonProviderImpl when not needed

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4327ea2  JOHNZON-218 ensure to not allocate BufferStrategy.BufferProvider in JsonProviderImpl when not needed
4327ea2 is described below

commit 4327ea204ba84d25c7c4260771f63cf35bd51211
Author: Romain Manni-Bucau <rm...@gmail.com>
AuthorDate: Thu Jul 25 15:41:37 2019 +0200

    JOHNZON-218 ensure to not allocate BufferStrategy.BufferProvider in JsonProviderImpl when not needed
---
 .../org/apache/johnzon/core/JsonProviderImpl.java  | 55 +++++++++++++++++-----
 1 file changed, 43 insertions(+), 12 deletions(-)

diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
index 1a466ed..deeb3e2 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
@@ -27,6 +27,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collection;
 import java.util.Map;
+import java.util.function.Supplier;
 
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
@@ -52,15 +53,16 @@ import javax.json.stream.JsonParser;
 import javax.json.stream.JsonParserFactory;
 
 public class JsonProviderImpl extends JsonProvider implements Serializable {
-    private final BufferStrategy.BufferProvider<char[]> bufferProvider =
+    private final Supplier<BufferStrategy.BufferProvider<char[]>> bufferProvider = new Cached<>(() ->
         BufferStrategyFactory.valueOf(System.getProperty(AbstractJsonFactory.BUFFER_STRATEGY, "QUEUE"))
-            .newCharProvider(Integer.getInteger("org.apache.johnzon.default-char-provider.length", 1024));
+            .newCharProvider(Integer.getInteger("org.apache.johnzon.default-char-provider.length", 1024)));
 
     private final JsonReaderFactory readerFactory = new JsonReaderFactoryImpl(null);
     private final JsonParserFactory parserFactory = new JsonParserFactoryImpl(null);
     private final JsonGeneratorFactory generatorFactory = new JsonGeneratorFactoryImpl(null);
     private final JsonWriterFactory writerFactory = new JsonWriterFactoryImpl(null);
-    private final JsonBuilderFactoryImpl builderFactory = new JsonBuilderFactoryImpl(null, bufferProvider);
+    private final Supplier<JsonBuilderFactory> builderFactory = new Cached<>(() ->
+            new JsonBuilderFactoryImpl(null, bufferProvider.get()));
 
     @Override
     public JsonParser createParser(final InputStream in) {
@@ -124,31 +126,32 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
 
     @Override
     public JsonObjectBuilder createObjectBuilder() {
-        return builderFactory.createObjectBuilder();
+        return builderFactory.get().createObjectBuilder();
     }
 
     @Override
     public JsonObjectBuilder createObjectBuilder(JsonObject jsonObject) {
-        return builderFactory.createObjectBuilder(jsonObject);
+        return builderFactory.get().createObjectBuilder(jsonObject);
     }
 
     @Override
     public JsonObjectBuilder createObjectBuilder(Map<String, Object> initialValues) {
-        return builderFactory.createObjectBuilder(initialValues);
+        return builderFactory.get().createObjectBuilder(initialValues);
     }
 
     @Override
     public JsonArrayBuilder createArrayBuilder() {
-        return builderFactory.createArrayBuilder();
+        return builderFactory.get().createArrayBuilder();
     }
 
     @Override
     public JsonArrayBuilder createArrayBuilder(JsonArray initialData) {
-        return builderFactory.createArrayBuilder(initialData);
+        return builderFactory.get().createArrayBuilder(initialData);
     }
 
+    @Override
     public JsonArrayBuilder createArrayBuilder(Collection<?> initialData) {
-        return builderFactory.createArrayBuilder(initialData);
+        return builderFactory.get().createArrayBuilder(initialData);
     }
 
     @Override
@@ -183,8 +186,9 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
 
     @Override
     public JsonBuilderFactory createBuilderFactory(final Map<String, ?> config) {
+        final JsonBuilderFactory builderFactory = this.builderFactory.get();
         return (config == null || config.isEmpty()) ?
-                builderFactory : new JsonBuilderFactoryImpl(config, bufferProvider);
+                builderFactory : new JsonBuilderFactoryImpl(config, bufferProvider.get());
     }
 
     @Override
@@ -202,6 +206,7 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
         return new JsonPointerImpl(this, path);
     }
 
+    @Override
     public JsonPatch createPatch(JsonArray array) {
         return createPatchBuilder(array).build();
     }
@@ -211,12 +216,38 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
         return new JsonPatchDiff(this, source, target).calculateDiff();
     }
 
+    @Override
     public JsonMergePatch createMergePatch(JsonValue patch) {
-        return new JsonMergePatchImpl(patch, bufferProvider);
+        return new JsonMergePatchImpl(patch, bufferProvider.get());
     }
 
     @Override
     public JsonMergePatch createMergeDiff(JsonValue source, JsonValue target) {
-        return new JsonMergePatchDiff(source, target, bufferProvider).calculateDiff();
+        return new JsonMergePatchDiff(source, target, bufferProvider.get()).calculateDiff();
+    }
+
+    /**
+     * Enables to not allocate potentially big instances or delay the initialization but ensure it happens only once.
+     * @param <T> the type of the cached instance.
+     */
+    private static class Cached<T> implements Supplier<T> {
+        private final Supplier<T> delegate;
+        private volatile T computed;
+
+        private Cached(final Supplier<T> delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public T get() {
+            if (computed == null) {
+                synchronized (this) {
+                    if (computed == null) {
+                        computed = delegate.get();
+                    }
+                }
+            }
+            return computed;
+        }
     }
 }