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.
      */

Reply via email to