From 7e59e496fc1c233d06f0172ceaceefd100469017 Mon Sep 17 00:00:00 2001 From: "koo.taejin" Date: Wed, 16 Nov 2022 23:33:13 +0900 Subject: [PATCH] [#691] Improve memory usage via reuse InputStreamBufferInput --- .../core/buffer/InputStreamBufferInput.java | 1 - .../dataformat/MessagePackFactory.java | 15 ++++++++ .../jackson/dataformat/MessagePackParser.java | 35 ++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java index d605fec3a..cb292b6ba 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java +++ b/msgpack-core/src/main/java/org/msgpack/core/buffer/InputStreamBufferInput.java @@ -61,7 +61,6 @@ public InputStreamBufferInput(InputStream in, int bufferSize) * @return the old resource */ public InputStream reset(InputStream in) - throws IOException { InputStream old = this.in; this.in = in; diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java index 1e7acc5e2..a0bf72fc4 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java @@ -40,6 +40,8 @@ public class MessagePackFactory private final MessagePack.PackerConfig packerConfig; private boolean reuseResourceInGenerator = true; private boolean reuseResourceInParser = true; + private boolean reuseInputStreamBufferInput = true; + private ExtensionTypeCustomDeserializers extTypeCustomDesers; public MessagePackFactory() @@ -58,6 +60,7 @@ public MessagePackFactory(MessagePackFactory src) this.packerConfig = src.packerConfig.clone(); this.reuseResourceInGenerator = src.reuseResourceInGenerator; this.reuseResourceInParser = src.reuseResourceInParser; + this.reuseInputStreamBufferInput = src.reuseInputStreamBufferInput; if (src.extTypeCustomDesers != null) { this.extTypeCustomDesers = new ExtensionTypeCustomDeserializers(src.extTypeCustomDesers); } @@ -75,6 +78,12 @@ public MessagePackFactory setReuseResourceInParser(boolean reuseResourceInParser return this; } + public MessagePackFactory setReuseInputStreamBufferInput(boolean reuseInputStreamBufferInput) + { + this.reuseInputStreamBufferInput = reuseInputStreamBufferInput; + return this; + } + public MessagePackFactory setExtTypeCustomDesers(ExtensionTypeCustomDeserializers extTypeCustomDesers) { this.extTypeCustomDesers = extTypeCustomDesers; @@ -167,6 +176,12 @@ boolean isReuseResourceInParser() return reuseResourceInParser; } + @VisibleForTesting + boolean isReuseInputStreamBufferInput() + { + return reuseInputStreamBufferInput; + } + @VisibleForTesting ExtensionTypeCustomDeserializers getExtTypeCustomDesers() { diff --git a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java index 2a95b69a0..9d89579f9 100644 --- a/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java +++ b/msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java @@ -49,6 +49,10 @@ public class MessagePackParser { private static final ThreadLocal> messageUnpackerHolder = new ThreadLocal>(); + + private static final ThreadLocal inputStreamBufferInputHolder = + new ThreadLocal<>(); + private final MessageUnpacker messageUnpacker; private static final BigInteger LONG_MIN = BigInteger.valueOf((long) Long.MIN_VALUE); @@ -130,7 +134,36 @@ public MessagePackParser( boolean reuseResourceInParser) throws IOException { - this(ctxt, features, new InputStreamBufferInput(in), objectCodec, in, reuseResourceInParser); + this(ctxt, features, objectCodec, in, reuseResourceInParser, true); + } + + public MessagePackParser( + IOContext ctxt, + int features, + ObjectCodec objectCodec, + InputStream in, + boolean reuseResourceInParser, + boolean reuseInputStreamBufferInput) + throws IOException + { + this(ctxt, features, getInputStreamBufferInput(in, reuseInputStreamBufferInput), objectCodec, in, reuseResourceInParser); + } + + private static InputStreamBufferInput getInputStreamBufferInput(InputStream in, boolean reuseInputStreamBufferInput) + { + if (reuseInputStreamBufferInput) { + final InputStreamBufferInput inputStreamBufferInput = inputStreamBufferInputHolder.get(); + if (inputStreamBufferInput != null) { + inputStreamBufferInput.reset(in); + return inputStreamBufferInput; + } + final InputStreamBufferInput newInputStreamBufferInput = new InputStreamBufferInput(in); + inputStreamBufferInputHolder.set(newInputStreamBufferInput); + return newInputStreamBufferInput; + } + else { + return new InputStreamBufferInput(in); + } } public MessagePackParser(IOContext ctxt, int features, ObjectCodec objectCodec, byte[] bytes)