You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/12/12 15:01:22 UTC

[dubbo] branch 3.0 updated: [3.0] Reduce Memory Allocation when routing (#9392)

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

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


The following commit(s) were added to refs/heads/3.0 by this push:
     new dcf25da  [3.0] Reduce Memory Allocation when routing (#9392)
dcf25da is described below

commit dcf25dac8acb15b4119ba4ebe659f55a0d7dcb95
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Sun Dec 12 23:01:10 2021 +0800

    [3.0] Reduce Memory Allocation when routing (#9392)
    
    * [3.0] Reduce Memory Allocation when routing
    
    * revert and copy
    
    * Revert "revert and copy"
    
    This reverts commit 754393b8ca959a0ad5ce0867f0e098211541bc01.
    
    * fix copy
    
    * fix ut
---
 .../org/apache/dubbo/rpc/cluster/RouterChain.java    | 11 ++++++-----
 .../dubbo/rpc/cluster/router/state/BitList.java      | 20 +++++++++++++++++---
 .../router/mock/MockInvokersSelectorTest.java        |  4 ++--
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
index b088c14..a679fc7 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/RouterChain.java
@@ -35,6 +35,7 @@ import org.apache.dubbo.rpc.model.ModuleModel;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -108,7 +109,7 @@ public class RouterChain<T> {
      */
     public void initWithRouters(List<Router> builtinRouters) {
         this.builtinRouters = builtinRouters;
-        this.routers = new ArrayList<>(builtinRouters);
+        this.routers = new LinkedList<>(builtinRouters);
     }
 
     /**
@@ -121,7 +122,7 @@ public class RouterChain<T> {
     }
 
     private void setStateRouters(List<StateRouter<T>> stateRouters) {
-        this.stateRouters = new ArrayList<>(stateRouters);
+        this.stateRouters = new LinkedList<>(stateRouters);
     }
 
     /**
@@ -133,7 +134,7 @@ public class RouterChain<T> {
      * @param routers routers from 'router://' rules in 2.6.x or before.
      */
     public void addRouters(List<Router> routers) {
-        List<Router> newRouters = new ArrayList<>();
+        List<Router> newRouters = new LinkedList<>();
         newRouters.addAll(builtinRouters);
         newRouters.addAll(routers);
         CollectionUtils.sort(newRouters);
@@ -141,7 +142,7 @@ public class RouterChain<T> {
     }
 
     public void addStateRouters(List<StateRouter<T>> stateRouters) {
-        List<StateRouter<T>> newStateRouters = new ArrayList<>();
+        List<StateRouter<T>> newStateRouters = new LinkedList<>();
         newStateRouters.addAll(builtinStateRouters);
         newStateRouters.addAll(stateRouters);
         CollectionUtils.sort(newStateRouters);
@@ -184,7 +185,7 @@ public class RouterChain<T> {
         if (routers.isEmpty()) {
             return resultInvokers;
         }
-        List<Invoker<T>> commonRouterResult = new ArrayList<>(resultInvokers);
+        List<Invoker<T>> commonRouterResult = resultInvokers.cloneToArrayList();
         // 2. route common router
         for (Router router : routers) {
             // Copy resultInvokers to a arrayList. BitList not support
diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java
index 52e80cb..b021b6e 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/state/BitList.java
@@ -19,6 +19,7 @@ package org.apache.dubbo.rpc.cluster.router.state;
 import org.apache.dubbo.common.utils.CollectionUtils;
 
 import java.util.AbstractList;
+import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.Collections;
 import java.util.Iterator;
@@ -106,9 +107,8 @@ public class BitList<E> extends AbstractList<E> {
      * @return a new bitList only contains those elements contain in both two list and source bitList's tailList
      */
     public BitList<E> and(BitList<E> target) {
-        BitSet resultSet = (BitSet) rootSet.clone();
-        resultSet.and(target.rootSet);
-        return new BitList<>(originList, resultSet, tailList);
+        rootSet.and(target.rootSet);
+        return this;
     }
 
     public boolean hasMoreElementInTailList() {
@@ -274,6 +274,11 @@ public class BitList<E> extends AbstractList<E> {
     }
 
     @Override
+    public boolean isEmpty() {
+        return this.rootSet.isEmpty() && (tailList == null || tailList.isEmpty());
+    }
+
+    @Override
     public ListIterator<E> listIterator() {
         return new BitListIterator<>(this, 0);
     }
@@ -465,6 +470,15 @@ public class BitList<E> extends AbstractList<E> {
         }
     }
 
+    public ArrayList<E> cloneToArrayList() {
+        if (rootSet.cardinality() == originList.size() && (tailList == null || tailList.isEmpty())) {
+            return new ArrayList<>(originList);
+        }
+        ArrayList<E> arrayList = new ArrayList<>(size());
+        arrayList.addAll(this);
+        return arrayList;
+    }
+
     @Override
     public BitList<E> clone() {
         return new BitList<>(originList, (BitSet) rootSet.clone(), tailList == null ? null : new LinkedList<>(tailList));
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelectorTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelectorTest.java
index 7cf5ecf..fcd0750 100644
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelectorTest.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelectorTest.java
@@ -53,7 +53,7 @@ public class MockInvokersSelectorTest {
 
         selector.notify(providers);
         // rpcInvocation does not have an attached "invocation.need.mock" parameter, so normal invokers will be filtered out
-        List<Invoker<DemoService>> invokers = selector.route(providers, consumerURL, rpcInvocation, false).getResult();
+        List<Invoker<DemoService>> invokers = selector.route(providers.clone(), consumerURL, rpcInvocation, false).getResult();
         Assertions.assertEquals(invokers.size(),1);
         Assertions.assertTrue(invokers.contains(invoker3));
 
@@ -61,7 +61,7 @@ public class MockInvokersSelectorTest {
         Map<String,Object> attachments = new HashMap<>();
         attachments.put(INVOCATION_NEED_MOCK,"true");
         Mockito.when(rpcInvocation.getObjectAttachments()).thenReturn(attachments);
-        invokers = selector.route(providers, consumerURL, rpcInvocation, false).getResult();
+        invokers = selector.route(providers.clone(), consumerURL, rpcInvocation, false).getResult();
         Assertions.assertEquals(invokers.size(),2);
         Assertions.assertTrue(invokers.contains(invoker1));
         Assertions.assertTrue(invokers.contains(invoker2));