Skip to content

Commit 4af0379

Browse files
committed
Release ByteBuf after encoding to JSON
Byte buffers of Json objects backed by ByteBuf are now released after encoding. [resolves #329]
1 parent 7ce5eb7 commit 4af0379

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/main/java/io/r2dbc/postgresql/codec/JsonCodec.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
import io.netty.buffer.ByteBuf;
2020
import io.netty.buffer.ByteBufAllocator;
21+
import io.netty.buffer.ByteBufUtil;
2122
import io.netty.buffer.Unpooled;
23+
import io.netty.util.ReferenceCountUtil;
2224
import io.r2dbc.postgresql.client.Parameter;
2325
import io.r2dbc.postgresql.message.Format;
2426
import io.r2dbc.postgresql.type.PostgresqlObjectId;
@@ -91,7 +93,11 @@ Parameter doEncode(Json value) {
9193
ByteBuf buffer = (ByteBuf) toEncode;
9294
buffer.touch();
9395

94-
return this.byteBufAllocator.buffer(buffer.readableBytes() + 1).writeByte(1).writeBytes(buffer);
96+
try {
97+
return this.byteBufAllocator.buffer(buffer.readableBytes() + 1).writeByte(1).writeBytes(buffer);
98+
} finally {
99+
ReferenceCountUtil.safeRelease(buffer);
100+
}
95101
});
96102

97103
}

src/test/java/io/r2dbc/postgresql/codec/JsonCodecUnitTests.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616

1717
package io.r2dbc.postgresql.codec;
1818

19+
import io.netty.buffer.ByteBuf;
1920
import io.netty.buffer.Unpooled;
2021
import io.r2dbc.postgresql.client.Parameter;
2122
import io.r2dbc.postgresql.util.ByteBufUtils;
2223
import org.junit.jupiter.api.Test;
2324

2425
import java.io.ByteArrayInputStream;
2526
import java.nio.ByteBuffer;
27+
import java.nio.charset.StandardCharsets;
2628

2729
import static io.r2dbc.postgresql.client.Parameter.NULL_VALUE;
2830
import static io.r2dbc.postgresql.client.ParameterAssert.assertThat;
@@ -34,6 +36,7 @@
3436
import static io.r2dbc.postgresql.util.TestByteBufAllocator.TEST;
3537
import static org.assertj.core.api.Assertions.assertThat;
3638
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
39+
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
3740

3841
/**
3942
* Unit tests for {@link JsonCodec}.
@@ -110,6 +113,32 @@ void doEncode() {
110113
.hasValue(Unpooled.wrappedBuffer(Unpooled.wrappedBuffer(new byte[]{1}), ByteBufUtils.encode(TEST, json)));
111114
}
112115

116+
@Test
117+
void doEncodeReleasedByteBuf() {
118+
String json = "{\"name\":\"John Doe\"}";
119+
JsonCodec jsonCodec = new JsonCodec(TEST);
120+
121+
ByteBuf buffer = TEST.buffer();
122+
buffer.writeCharSequence(json, StandardCharsets.UTF_8);
123+
124+
assertThat(jsonCodec.doEncode(Json.of(buffer)))
125+
.hasValue(Unpooled.wrappedBuffer(Unpooled.wrappedBuffer(new byte[]{1}), ByteBufUtils.encode(TEST, json)));
126+
127+
assertThat(buffer.refCnt()).isZero();
128+
}
129+
130+
@Test
131+
void doEncodeReleasedJsonOutput() {
132+
String json = "{\"name\":\"John Doe\"}";
133+
JsonCodec jsonCodec = new JsonCodec(TEST);
134+
Json decodedBytes = jsonCodec.decode(ByteBufUtils.encode(TEST, json), JSON.getObjectId(), FORMAT_TEXT, Json.class);
135+
136+
assertThat(jsonCodec.doEncode(decodedBytes))
137+
.hasValue(Unpooled.wrappedBuffer(Unpooled.wrappedBuffer(new byte[]{1}), ByteBufUtils.encode(TEST, json)));
138+
139+
assertThatIllegalStateException().isThrownBy(decodedBytes::asString).withMessage("JSON is already released");
140+
}
141+
113142
@Test
114143
void doEncodeNoValue() {
115144
assertThatIllegalArgumentException().isThrownBy(() -> new JsonCodec(TEST).doEncode(null))

0 commit comments

Comments
 (0)