99package org .elasticsearch .common .io .stream ;
1010
1111import org .elasticsearch .Version ;
12- import org .elasticsearch .common .bytes .BytesReference ;
12+ import org .elasticsearch .common .bytes .ReleasableBytesReference ;
13+ import org .elasticsearch .common .lease .Releasable ;
1314
1415import java .io .IOException ;
1516import java .io .UncheckedIOException ;
3233 * to force their buffering in serialized format by calling
3334 * {@link #asSerialized(Reader, NamedWriteableRegistry)}.
3435 */
35- public abstract class DelayableWriteable <T extends Writeable > implements Writeable {
36+ public abstract class DelayableWriteable <T extends Writeable > implements Writeable , Releasable {
3637 /**
3738 * Build a {@linkplain DelayableWriteable} that wraps an existing object
3839 * but is serialized so that deserializing it can be delayed.
@@ -46,7 +47,7 @@ public static <T extends Writeable> DelayableWriteable<T> referencing(T referenc
4647 * when {@link #expand()} is called.
4748 */
4849 public static <T extends Writeable > DelayableWriteable <T > delayed (Writeable .Reader <T > reader , StreamInput in ) throws IOException {
49- return new Serialized <>(reader , in .getVersion (), in .namedWriteableRegistry (), in .readBytesReference ());
50+ return new Serialized <>(reader , in .getVersion (), in .namedWriteableRegistry (), in .readReleasableBytesReference ());
5051 }
5152
5253 private DelayableWriteable () {}
@@ -98,7 +99,8 @@ public Serialized<T> asSerialized(Reader<T> reader, NamedWriteableRegistry regis
9899 } catch (IOException e ) {
99100 throw new RuntimeException ("unexpected error writing writeable to buffer" , e );
100101 }
101- return new Serialized <>(reader , Version .CURRENT , registry , buffer .bytes ());
102+ // TODO: this path is currently not used in production code, if it ever is this should start using pooled buffers
103+ return new Serialized <>(reader , Version .CURRENT , registry , ReleasableBytesReference .wrap (buffer .bytes ()));
102104 }
103105
104106 @ Override
@@ -118,19 +120,25 @@ private BytesStreamOutput writeToBuffer(Version version) throws IOException {
118120 return buffer ;
119121 }
120122 }
123+
124+ @ Override
125+ public void close () {
126+ //noop
127+ }
121128 }
122129
123130 /**
124- * A {@link Writeable} stored in serialized form.
131+ * A {@link Writeable} stored in serialized form backed by a {@link ReleasableBytesReference}. Once an instance is no longer used its
132+ * backing memory must be manually released by invoking {@link #close()} on it.
125133 */
126134 public static class Serialized <T extends Writeable > extends DelayableWriteable <T > {
127135 private final Writeable .Reader <T > reader ;
128136 private final Version serializedAtVersion ;
129137 private final NamedWriteableRegistry registry ;
130- private final BytesReference serialized ;
138+ private final ReleasableBytesReference serialized ;
131139
132- private Serialized (Writeable .Reader <T > reader , Version serializedAtVersion ,
133- NamedWriteableRegistry registry , BytesReference serialized ) {
140+ private Serialized (Writeable .Reader <T > reader , Version serializedAtVersion , NamedWriteableRegistry registry ,
141+ ReleasableBytesReference serialized ) {
134142 this .reader = reader ;
135143 this .serializedAtVersion = serializedAtVersion ;
136144 this .registry = registry ;
@@ -186,6 +194,11 @@ public long getSerializedSize() {
186194 // We're already serialized
187195 return serialized .length ();
188196 }
197+
198+ @ Override
199+ public void close () {
200+ serialized .close ();
201+ }
189202 }
190203
191204 /**
0 commit comments