From 655768652f1ca62955b85d78d94a657f25ba0743 Mon Sep 17 00:00:00 2001 From: mariofusco Date: Tue, 16 Jan 2024 15:25:55 +0100 Subject: [PATCH 1/3] reuse in IOContext the BufferRecycler already contained in the ContentReference if any --- .../jackson/databind/ObjectMapper.java | 3 +- .../util/BufferRecyclersDatabindTest.java | 73 ++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java index f3467b8e38..d3a89bc898 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java +++ b/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java @@ -4033,8 +4033,7 @@ public String writeValueAsString(Object value) throws JsonProcessingException { // alas, we have to pull the recycler directly here... - SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler()); - try { + try (SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler())) { _writeValueAndClose(createGenerator(sw), value); return sw.getAndClear(); } catch (JsonProcessingException e) { diff --git a/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java b/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java index eac55dd7ca..6370ffcd0c 100644 --- a/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java @@ -1,6 +1,10 @@ package com.fasterxml.jackson.databind.util; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.nio.charset.StandardCharsets; +import java.util.function.Predicate; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @@ -54,6 +58,10 @@ public void testParserWithBoundedPool() throws Exception { _testParser(JsonRecyclerPools.sharedBoundedPool()); } + public void testParserWithHybridPool() throws Exception { + _testParser(new HybridTestPool()); + } + private void _testParser(RecyclerPool pool) throws Exception { ObjectMapper mapper = JsonMapper.builder( @@ -92,7 +100,7 @@ public void testGeneratorWithDequeuPool() throws Exception { public void testGeneratorWithLockFreePool() throws Exception { _testGenerator(JsonRecyclerPools.newLockFreePool()); - _testGenerator(JsonRecyclerPools.sharedLockFreePool()); +// _testGenerator(JsonRecyclerPools.sharedLockFreePool()); } public void testGeneratorWithBoundedPool() throws Exception { @@ -100,6 +108,10 @@ public void testGeneratorWithBoundedPool() throws Exception { _testGenerator(JsonRecyclerPools.sharedBoundedPool()); } + public void testGeneratorWithHybridPool() throws Exception { + _testGenerator(new HybridTestPool()); + } + private void _testGenerator(RecyclerPool pool) throws Exception { ObjectMapper mapper = JsonMapper.builder( @@ -115,4 +127,63 @@ private void _testGenerator(RecyclerPool pool) throws Exception assertEquals(EXP, new String(mapper.writeValueAsBytes(new Pojo4321(-42, "bogus")), StandardCharsets.UTF_8)); } + + public static class HybridTestPool implements RecyclerPool { + + private static final Predicate isVirtual = VirtualPredicate.findIsVirtualPredicate(); + + private final RecyclerPool nativePool = JsonRecyclerPools.threadLocalPool(); + private final RecyclerPool virtualPool = JsonRecyclerPools.newLockFreePool(); + + @Override + public BufferRecycler acquirePooled() { + return isVirtual.test(Thread.currentThread()) ? + virtualPool.acquirePooled() : + nativePool.acquirePooled(); + } + + @Override + public void releasePooled(BufferRecycler pooled) { + if (isVirtual.test(Thread.currentThread())) { + virtualPool.releasePooled(pooled); + } else { + nativePool.releasePooled(pooled); + } + } + + private static class VirtualPredicate { + private static final MethodHandle virtualMh = findVirtualMH(); + + private static MethodHandle findVirtualMH() { + try { + return MethodHandles.publicLookup().findVirtual(Thread.class, "isVirtual", + MethodType.methodType(boolean.class)); + } catch (Exception e) { + return null; + } + } + + private static Predicate findIsVirtualPredicate() { + if (virtualMh != null) { + return new Predicate() { + @Override + public boolean test(Thread thread) { + try { + return (boolean) virtualMh.invokeExact(thread); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + }; + } + + return new Predicate() { + @Override + public boolean test(Thread thread) { + return false; + } + }; + } + } + } } From c7dc3d82908095e9d54910051503cf5f7a550235 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 24 Jan 2024 14:35:58 -0800 Subject: [PATCH 2/3] Warnings removal --- .../util/BufferRecyclersDatabindTest.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java b/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java index 6370ffcd0c..3e9b50dcd7 100644 --- a/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java @@ -100,7 +100,7 @@ public void testGeneratorWithDequeuPool() throws Exception { public void testGeneratorWithLockFreePool() throws Exception { _testGenerator(JsonRecyclerPools.newLockFreePool()); -// _testGenerator(JsonRecyclerPools.sharedLockFreePool()); + _testGenerator(JsonRecyclerPools.sharedLockFreePool()); } public void testGeneratorWithBoundedPool() throws Exception { @@ -128,7 +128,9 @@ private void _testGenerator(RecyclerPool pool) throws Exception StandardCharsets.UTF_8)); } - public static class HybridTestPool implements RecyclerPool { + public static class HybridTestPool implements RecyclerPool + { + private static final long serialVersionUID = 1L; private static final Predicate isVirtual = VirtualPredicate.findIsVirtualPredicate(); @@ -151,19 +153,19 @@ public void releasePooled(BufferRecycler pooled) { } } - private static class VirtualPredicate { - private static final MethodHandle virtualMh = findVirtualMH(); + static class VirtualPredicate { + static final MethodHandle virtualMh = findVirtualMH(); - private static MethodHandle findVirtualMH() { + static MethodHandle findVirtualMH() { try { return MethodHandles.publicLookup().findVirtual(Thread.class, "isVirtual", - MethodType.methodType(boolean.class)); + MethodType.methodType(boolean.class)); } catch (Exception e) { return null; } } - private static Predicate findIsVirtualPredicate() { + static Predicate findIsVirtualPredicate() { if (virtualMh != null) { return new Predicate() { @Override From 2764f3e4e8da309d917612b962d5d0555d9a0f17 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 24 Jan 2024 14:37:26 -0800 Subject: [PATCH 3/3] ... --- .../jackson/databind/util/BufferRecyclersDatabindTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java b/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java index 3e9b50dcd7..5d0eee38bb 100644 --- a/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java @@ -128,7 +128,7 @@ private void _testGenerator(RecyclerPool pool) throws Exception StandardCharsets.UTF_8)); } - public static class HybridTestPool implements RecyclerPool + static class HybridTestPool implements RecyclerPool { private static final long serialVersionUID = 1L;