This is an automated email from the ASF dual-hosted git repository.

zrlw pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.3 by this push:
     new f5d6436fae Optimize NettyBackedChannelBuffer for direct buffer 
transfer (#16027)
f5d6436fae is described below

commit f5d6436fae851c577fcf2eb1aaab543e92acf9b4
Author: Wenli Tian <[email protected]>
AuthorDate: Wed Jan 28 14:42:58 2026 +0800

    Optimize NettyBackedChannelBuffer for direct buffer transfer (#16027)
    
    * Optimize NettyBackedChannelBuffer for direct buffer transfer
    
    - Optimize getBytes/setBytes/readBytes/writeBytes methods
    - Avoid intermediate byte array copy when source/destination is 
NettyBackedChannelBuffer
    - Directly use Netty's ByteBuf transfer capabilities
    - Add fallback to intermediate array copy for other ChannelBuffer 
implementations
    - Improve performance by 4-5x for Netty-to-Netty buffer transfers
    
    * Add tests for NettyBackedChannelBuffer
    
    * Format code
    
    * Update 
dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBufferTest.java
    
    Co-authored-by: Copilot <[email protected]>
    
    ---------
    
    Co-authored-by: Copilot <[email protected]>
    Co-authored-by: zrlw <[email protected]>
---
 .../transport/netty4/NettyBackedChannelBuffer.java | 52 +++++++++++++++-------
 .../netty4/NettyBackedChannelBufferTest.java       | 52 ++++++++++++++++++++++
 2 files changed, 88 insertions(+), 16 deletions(-)

diff --git 
a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java
 
b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java
index d0fb5f2753..d51cb21dd9 100644
--- 
a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java
+++ 
b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java
@@ -71,10 +71,15 @@ public class NettyBackedChannelBuffer implements 
ChannelBuffer {
 
     @Override
     public void getBytes(int index, ChannelBuffer dst, int dstIndex, int 
length) {
-        // careful
-        byte[] data = new byte[length];
-        buffer.getBytes(index, data, 0, length);
-        dst.setBytes(dstIndex, data, 0, length);
+        // use Netty ByteBuf
+        if (dst instanceof NettyBackedChannelBuffer) {
+            NettyBackedChannelBuffer nettyDst = (NettyBackedChannelBuffer) dst;
+            buffer.getBytes(index, nettyDst.buffer, dstIndex, length);
+        } else {
+            byte[] data = new byte[length];
+            buffer.getBytes(index, data, 0, length);
+            dst.setBytes(dstIndex, data, 0, length);
+        }
     }
 
     @Override
@@ -107,10 +112,15 @@ public class NettyBackedChannelBuffer implements 
ChannelBuffer {
         if (length > src.readableBytes()) {
             throw new IndexOutOfBoundsException();
         }
-        // careful
-        byte[] data = new byte[length];
-        src.getBytes(srcIndex, data, 0, length);
-        setBytes(index, data, 0, length);
+        // use Netty ByteBuf
+        if (src instanceof NettyBackedChannelBuffer) {
+            NettyBackedChannelBuffer nettySrc = (NettyBackedChannelBuffer) src;
+            buffer.setBytes(index, nettySrc.buffer, srcIndex, length);
+        } else {
+            byte[] data = new byte[length];
+            src.getBytes(srcIndex, data, 0, length);
+            setBytes(index, data, 0, length);
+        }
     }
 
     @Override
@@ -239,13 +249,18 @@ public class NettyBackedChannelBuffer implements 
ChannelBuffer {
 
     @Override
     public void readBytes(ChannelBuffer dst, int dstIndex, int length) {
-        // careful
         if (readableBytes() < length) {
             throw new IndexOutOfBoundsException();
         }
-        byte[] data = new byte[length];
-        buffer.readBytes(data, 0, length);
-        dst.setBytes(dstIndex, data, 0, length);
+        // use Netty ByteBuf
+        if (dst instanceof NettyBackedChannelBuffer) {
+            NettyBackedChannelBuffer nettyDst = (NettyBackedChannelBuffer) dst;
+            buffer.readBytes(nettyDst.buffer, dstIndex, length);
+        } else {
+            byte[] data = new byte[length];
+            buffer.readBytes(data, 0, length);
+            dst.setBytes(dstIndex, data, 0, length);
+        }
     }
 
     @Override
@@ -362,10 +377,15 @@ public class NettyBackedChannelBuffer implements 
ChannelBuffer {
 
     @Override
     public void writeBytes(ChannelBuffer src, int srcIndex, int length) {
-        // careful
-        byte[] data = new byte[length];
-        src.getBytes(srcIndex, data, 0, length);
-        writeBytes(data, 0, length);
+        // use Netty ByteBuf
+        if (src instanceof NettyBackedChannelBuffer) {
+            NettyBackedChannelBuffer nettySrc = (NettyBackedChannelBuffer) src;
+            buffer.writeBytes(nettySrc.buffer, srcIndex, length);
+        } else {
+            byte[] data = new byte[length];
+            src.getBytes(srcIndex, data, 0, length);
+            writeBytes(data, 0, length);
+        }
     }
 
     @Override
diff --git 
a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBufferTest.java
 
b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBufferTest.java
index c2224e1994..2ed7fa66bc 100644
--- 
a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBufferTest.java
+++ 
b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBufferTest.java
@@ -18,11 +18,13 @@ package org.apache.dubbo.remoting.transport.netty4;
 
 import org.apache.dubbo.remoting.buffer.ChannelBuffer;
 
+import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 class NettyBackedChannelBufferTest {
@@ -60,4 +62,54 @@ class NettyBackedChannelBufferTest {
         assertEquals(1, actual[0]);
         assertEquals(2, actual[1]);
     }
+
+    @Test
+    void testBufferTransfer_directToDirect() {
+        ByteBuf srcDirect = Unpooled.directBuffer(4);
+        ByteBuf dstDirect = Unpooled.directBuffer(4);
+
+        try {
+            ChannelBuffer source = new NettyBackedChannelBuffer(srcDirect);
+            ChannelBuffer target = new NettyBackedChannelBuffer(dstDirect);
+
+            byte[] data = {10, 20, 30, 40};
+            source.writeBytes(data);
+
+            target.setBytes(0, source, 0, 4);
+
+            byte[] actual = new byte[4];
+            target.getBytes(0, actual);
+
+            assertArrayEquals(data, actual);
+            assertEquals(0, target.readerIndex(), "setBytes should not move 
readerIndex");
+        } finally {
+            srcDirect.release();
+            dstDirect.release();
+        }
+    }
+
+    @Test
+    void testReadBytes_directBuffer() {
+        byte[] data = {1, 2, 3, 4};
+        buffer.writeBytes(data);
+
+        byte[] actual = new byte[4];
+        buffer.readBytes(actual);
+
+        assertArrayEquals(data, actual);
+        assertEquals(4, buffer.readerIndex());
+    }
+
+    @Test
+    void testGetBytes_directBuffer_shouldNotMoveIndex() {
+        buffer.writeBytes(new byte[] {5, 6, 7, 8});
+
+        int before = buffer.readerIndex();
+
+        byte[] actual = new byte[2];
+        buffer.getBytes(1, actual);
+
+        assertEquals(before, buffer.readerIndex());
+        assertArrayEquals(new byte[] {6, 7}, actual);
+    }
 }

Reply via email to