This is an automated email from the ASF dual-hosted git repository.
anton-vinogradov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new db3ffdfcd6f IGNITE-28835 BinaryMarshaller: marshal directly into
OutputStream to avoid a full-object copy (#13295)
db3ffdfcd6f is described below
commit db3ffdfcd6fce625d648868e234d3d9a5d9cb9f6
Author: Anton Vinogradov <[email protected]>
AuthorDate: Mon Jul 6 18:31:05 2026 +0300
IGNITE-28835 BinaryMarshaller: marshal directly into OutputStream to avoid
a full-object copy (#13295)
---
.../ignite/internal/binary/BinaryMarshaller.java | 9 +------
.../internal/binary/GridBinaryMarshaller.java | 31 ++++++++++++++++++++++
.../internal/binary/BinaryMarshallerSelfTest.java | 23 ++++++++++++++++
3 files changed, 55 insertions(+), 8 deletions(-)
diff --git
a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java
b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java
index db0a86e86fa..7411659d663 100644
---
a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java
+++
b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/BinaryMarshaller.java
@@ -83,14 +83,7 @@ public class BinaryMarshaller extends
AbstractNodeNameAwareMarshaller {
/** {@inheritDoc} */
@Override protected void marshal0(@Nullable Object obj, OutputStream out)
throws IgniteCheckedException {
- byte[] arr = marshal(obj);
-
- try {
- out.write(arr);
- }
- catch (Exception e) {
- throw new BinaryObjectException("Failed to marshal the object: " +
obj, e);
- }
+ impl.marshal(obj, out, false);
}
/** {@inheritDoc} */
diff --git
a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
index 651781e1403..75e5252f130 100644
---
a/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
+++
b/modules/binary/api/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.binary;
+import java.io.IOException;
+import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
@@ -257,6 +259,35 @@ public class GridBinaryMarshaller {
}
}
+ /**
+ * Marshals the object directly into the given stream, without allocating
a trimmed copy of the whole result.
+ *
+ * @param obj Object to marshal.
+ * @param out Output stream.
+ * @param failIfUnregistered Throw exception if class isn't registered.
+ * @throws BinaryObjectException In case of error.
+ */
+ public void marshal(@Nullable Object obj, OutputStream out, boolean
failIfUnregistered) throws BinaryObjectException {
+ try {
+ if (obj == null) {
+ out.write(NULL);
+
+ return;
+ }
+
+ try (BinaryWriterEx writer = BinaryUtils.writer(ctx,
failIfUnregistered, UNREGISTERED_TYPE_ID)) {
+ writer.marshal(obj);
+
+ BinaryOutputStream s = writer.out();
+
+ out.write(s.array(), 0, s.position());
+ }
+ }
+ catch (IOException e) {
+ throw new BinaryObjectException("Failed to marshal the object: " +
obj, e);
+ }
+ }
+
/**
* @param bytes Bytes array.
* @return Binary object.
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
index 6a76831a79b..6f724f526e5 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.binary;
+import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
@@ -753,6 +754,28 @@ public class BinaryMarshallerSelfTest extends
AbstractBinaryArraysTest {
assertTrue(obj.type == DeclaredBodyEnum.TWO);
}
+ /**
+ * Marshalling into an {@link java.io.OutputStream} must produce exactly
the same bytes as marshalling into an array.
+ *
+ * @throws Exception If failed.
+ */
+ @Test
+ public void testMarshalToStreamMatchesArray() throws Exception {
+ BinaryMarshaller marsh = binaryMarshaller();
+
+ for (Object obj : new Object[] {null, "string", 42, simpleObject()}) {
+ byte[] arr = marsh.marshal(obj);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ marsh.marshal(obj, out);
+
+ assertArrayEquals("Mismatch for " + obj, arr, out.toByteArray());
+
+ assertEquals(obj, marsh.unmarshal(out.toByteArray(), null));
+ }
+ }
+
/**
* @throws Exception If failed.
*/