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

jakevin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 302da03b18 [enhancement](Nereids): Use long bitmap in DPHyp (#14725)
302da03b18 is described below

commit 302da03b1884fd2ad4569730e0628ea5ccda0dca
Author: 谢健 <[email protected]>
AuthorDate: Thu Dec 1 20:47:45 2022 +0800

    [enhancement](Nereids): Use long bitmap in DPHyp (#14725)
---
 .../doris/nereids/jobs/joinorder/JoinOrderJob.java |  20 ++-
 .../jobs/joinorder/hypergraph/CircleDetector.java  |  50 ++++---
 .../nereids/jobs/joinorder/hypergraph/Edge.java    |  71 ++++-----
 .../jobs/joinorder/hypergraph/GraphSimplifier.java |  63 ++++----
 .../jobs/joinorder/hypergraph/HyperGraph.java      |  57 +++----
 .../nereids/jobs/joinorder/hypergraph/Node.java    |  44 +-----
 .../joinorder/hypergraph/SubgraphEnumerator.java   | 165 +++++++++++----------
 .../jobs/joinorder/hypergraph/bitmap/Bitmap.java   | 134 -----------------
 .../joinorder/hypergraph/bitmap/LongBitmap.java    | 156 +++++++++++++++++++
 ...BitSetIterator.java => LongBitmapIterator.java} |  18 +--
 ...terator.java => LongBitmapReverseIterator.java} |  22 ++-
 ...Iterator.java => LongBitmapSubsetIterator.java} |  49 ++----
 .../hypergraph/receiver/AbstractReceiver.java      |   9 +-
 .../joinorder/hypergraph/receiver/Counter.java     |  32 ++--
 .../hypergraph/receiver/PlanReceiver.java          |  25 ++--
 .../java/org/apache/doris/nereids/memo/Memo.java   |  10 ++
 .../jobs/joinorder/hypergraph/BitSetTest.java      |  43 ------
 .../jobs/joinorder/hypergraph/BitmapTest.java      |  64 ++++++++
 .../joinorder/hypergraph/GraphSimplifierTest.java  |   2 -
 .../hypergraph/SubgraphEnumeratorTest.java         |  67 ++++-----
 .../doris/nereids/util/HyperGraphBuilder.java      |  11 +-
 21 files changed, 557 insertions(+), 555 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJob.java
index 4b5e20ad0d..1ef38df1d4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJob.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/JoinOrderJob.java
@@ -77,7 +77,25 @@ public class JoinOrderJob extends Job {
                 throw new RuntimeException("DPHyp can not enumerate all sub 
graphs with limit=" + limit);
             }
         }
-        return planReceiver.getBestPlan(hyperGraph.getNodesMap());
+
+        Group optimized = planReceiver.getBestPlan(hyperGraph.getNodesMap());
+        return copyToMemo(optimized);
+    }
+
+    private Group copyToMemo(Group root) {
+        if (!root.isJoinGroup()) {
+            return root;
+        }
+        GroupExpression groupExpression = root.getLogicalExpression();
+        int arity = groupExpression.arity();
+        for (int i = 0; i < arity; i++) {
+            Group childGroup = groupExpression.child(i);
+            Group newChildGroup = copyToMemo(childGroup);
+            groupExpression.setChild(i, newChildGroup);
+        }
+        Group newRoot = 
context.getCascadesContext().getMemo().copyInGroupExpression(groupExpression);
+        newRoot.setStatistics(root.getStatistics());
+        return newRoot;
     }
 
     /**
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetector.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetector.java
index 7f97904cf6..e4c5513fd4 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetector.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/CircleDetector.java
@@ -17,12 +17,11 @@
 
 package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 
 import com.google.common.base.Preconditions;
 
 import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.List;
 
 /**
@@ -38,16 +37,16 @@ public class CircleDetector {
     // record the node in certain order, named i2n in paper
     List<Integer> nodes = new ArrayList<>();
     // stored the dependency of each node
-    List<BitSet> directedEdges = new ArrayList<>();
+    List<Long> directedEdges = new ArrayList<>();
     // the nodes are after than this node
-    List<BitSet> subNodes = new ArrayList<>();
+    List<Long> subNodes = new ArrayList<>();
 
     CircleDetector(int size) {
         for (int i = 0; i < size; i++) {
             orders.add(i);
             nodes.add(i);
-            directedEdges.add(Bitmap.newBitmap());
-            subNodes.add(Bitmap.newBitmap(i));
+            directedEdges.add(LongBitmap.newBitmap());
+            subNodes.add(LongBitmap.newBitmap(i));
         }
     }
 
@@ -63,19 +62,21 @@ public class CircleDetector {
         if (checkCircleWithEdge(node1, node2)) {
             return false;
         }
-        Bitmap.set(directedEdges.get(node1), node2);
+        directedEdges.set(node1, LongBitmap.set(directedEdges.get(node1), 
node2));
         int order1 = orders.get(node1);
         int order2 = orders.get(node2);
         if (order1 >= order2) {
             shift(order2, order1 + 1, subNodes.get(node2));
         }
-        for (BitSet nodes : subNodes) {
-            // add all subNodes which contains node1 into subNodes of node2.
-            if (Bitmap.get(nodes, node1)) {
-                Bitmap.or(nodes, subNodes.get(node2));
+        int size = subNodes.size();
+        for (int i = 0; i < size; i++) {
+            // add the subNodes which contains node1 with subNodes of node2.
+            long nodes = subNodes.get(i);
+            if (LongBitmap.get(nodes, node1)) {
+                subNodes.set(i, LongBitmap.or(nodes, subNodes.get(node2)));
             }
         }
-        Bitmap.or(subNodes.get(node1), subNodes.get(node2));
+        subNodes.set(node1, LongBitmap.or(subNodes.get(node1), 
subNodes.get(node2)));
         return true;
     }
 
@@ -86,13 +87,14 @@ public class CircleDetector {
      * @param node2 the end node of the edge
      */
     public void deleteDirectedEdge(int node1, int node2) {
-        Preconditions.checkArgument(Bitmap.get(directedEdges.get(node1), 
node2),
+        Preconditions.checkArgument(LongBitmap.get(directedEdges.get(node1), 
node2),
                 String.format("The edge %d -> %d is not existed", node1, 
node2));
-        for (BitSet nodes : subNodes) {
-            Bitmap.clear(nodes);
+        int size = subNodes.size();
+        for (int i = 0; i < size; i++) {
+            subNodes.set(i, LongBitmap.newBitmap());
         }
 
-        int size = orders.size();
+        size = orders.size();
         for (int i = 0; i < size; i++) {
             getSubNodes(i);
         }
@@ -111,30 +113,30 @@ public class CircleDetector {
      */
     public boolean checkCircleWithEdge(int node1, int node2) {
         // return true when there is a circle
-        return Bitmap.get(subNodes.get(node2), node1);
+        return LongBitmap.get(subNodes.get(node2), node1);
     }
 
-    private BitSet getSubNodes(int node) {
-        if (Bitmap.getCardinality(subNodes.get(node)) != 0) {
+    private long getSubNodes(int node) {
+        if (LongBitmap.getCardinality(subNodes.get(node)) != 0) {
             return subNodes.get(node);
         }
 
-        for (int nextNode : Bitmap.getIterator(directedEdges.get(node))) {
+        for (int nextNode : LongBitmap.getIterator(directedEdges.get(node))) {
             Preconditions.checkArgument(orders.get(nextNode) > 
orders.get(node),
                     String.format("node %d must come after node %d", nextNode, 
node));
-            Bitmap.or(subNodes.get(node), getSubNodes(nextNode));
+            subNodes.set(node, LongBitmap.or(subNodes.get(node), 
getSubNodes(nextNode)));
         }
         return subNodes.get(node);
     }
 
-    private void shift(int startOrder, int endOrder, BitSet visited) {
+    private void shift(int startOrder, int endOrder, long visited) {
         // Reorder the nodes between order1 and order2. We always keep the 
nodes visited comes
         // before the other nodes and their relative order is not changed. 
Because those two parts
         // is not connected, we can do it safely.
         List<Integer> shiftNodes = new ArrayList<>();
         for (int o = startOrder; o < endOrder; o++) {
             int node = nodes.get(o);
-            if (Bitmap.get(visited, node)) {
+            if (LongBitmap.get(visited, node)) {
                 shiftNodes.add(node);
             } else {
                 // the relative orders of visited nodes are not changed
@@ -158,7 +160,7 @@ public class CircleDetector {
         StringBuilder builder = new StringBuilder();
         int size = directedEdges.size();
         for (int i = 0; i < size; i++) {
-            if (Bitmap.getCardinality(directedEdges.get(i)) != 0) {
+            if (LongBitmap.getCardinality(directedEdges.get(i)) != 0) {
                 builder.append(String.format("%d -> %s; ", i, 
directedEdges.get(i)));
             }
         }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
index 8ea7e167fc..cb05321d5b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Edge.java
@@ -17,13 +17,11 @@
 
 package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.trees.plans.GroupPlan;
 import org.apache.doris.nereids.trees.plans.Plan;
 import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
 
-import java.util.BitSet;
-
 /**
  * Edge in HyperGraph
  */
@@ -34,9 +32,9 @@ public class Edge {
 
     // The endpoints (hyperNodes) of this hyperEdge.
     // left and right may not overlap, and both must have at least one bit set.
-    private BitSet left = Bitmap.newBitmap();
-    private BitSet right = Bitmap.newBitmap();
-    private BitSet referenceNodes = Bitmap.newBitmap();
+    private long left = LongBitmap.newBitmap();
+    private long right = LongBitmap.newBitmap();
+    private long referenceNodes = LongBitmap.newBitmap();
 
     /**
      * Create simple edge.
@@ -52,71 +50,64 @@ public class Edge {
     }
 
     public boolean isSimple() {
-        return Bitmap.getCardinality(left) == 1 && 
Bitmap.getCardinality(right) == 1;
+        return LongBitmap.getCardinality(left) == 1 && 
LongBitmap.getCardinality(right) == 1;
     }
 
-    public void addLeftNode(BitSet left) {
-        Bitmap.or(this.left, left);
-        Bitmap.or(referenceNodes, left);
+    public void addLeftNode(long left) {
+        this.left = LongBitmap.or(this.left, left);
+        referenceNodes = LongBitmap.or(referenceNodes, left);
     }
 
-    public void addLeftNodes(BitSet... bitSets) {
-        for (BitSet bitSet : bitSets) {
-            Bitmap.or(this.left, bitSet);
-            Bitmap.or(referenceNodes, bitSet);
+    public void addLeftNodes(long... bitmaps) {
+        for (long bitmap : bitmaps) {
+            this.left = LongBitmap.or(this.left, bitmap);
+            referenceNodes = LongBitmap.or(referenceNodes, bitmap);
         }
     }
 
-    public void addRightNode(BitSet right) {
-        Bitmap.or(this.right, right);
-        Bitmap.or(referenceNodes, right);
+    public void addRightNode(long right) {
+        this.right = LongBitmap.or(this.right, right);
+        referenceNodes = LongBitmap.or(referenceNodes, right);
     }
 
-    public void addRightNodes(BitSet... bitSets) {
-        for (BitSet bitSet : bitSets) {
-            Bitmap.or(this.right, bitSet);
-            Bitmap.or(referenceNodes, bitSet);
+    public void addRightNodes(long... bitmaps) {
+        for (long bitmap : bitmaps) {
+            LongBitmap.or(this.right, bitmap);
+            LongBitmap.or(referenceNodes, bitmap);
         }
     }
 
-    public BitSet getLeft() {
+    public long getLeft() {
         return left;
     }
 
-    public void setLeft(BitSet left) {
-        referenceNodes.clear();
+    public void setLeft(long left) {
+        referenceNodes = LongBitmap.clear(referenceNodes);
         this.left = left;
     }
 
-    public BitSet getRight() {
+    public long getRight() {
         return right;
     }
 
-    public void setRight(BitSet right) {
-        referenceNodes.clear();
+    public void setRight(long right) {
+        referenceNodes = LongBitmap.clear(referenceNodes);
         this.right = right;
     }
 
     public boolean isSub(Edge edge) {
         // When this join reference nodes is a subset of other join, then this 
join must appear before that join
-        BitSet otherBitset = edge.getReferenceNodes();
-        return Bitmap.isSubset(getReferenceNodes(), otherBitset);
+        long otherBitmap = edge.getReferenceNodes();
+        return LongBitmap.isSubset(getReferenceNodes(), otherBitmap);
     }
 
-    public BitSet getReferenceNodes() {
-        if (referenceNodes.cardinality() == 0) {
-            referenceNodes = Bitmap.newBitmapUnion(left, right);
+    public long getReferenceNodes() {
+        if (LongBitmap.getCardinality(referenceNodes) == 0) {
+            referenceNodes = LongBitmap.newBitmapUnion(left, right);
         }
         return referenceNodes;
     }
 
-    public Edge reverse(int index) {
-        Edge newEdge = new Edge(join, index);
-        newEdge.addLeftNode(right);
-        newEdge.addRightNode(left);
-        return newEdge;
-    }
-
     public int getIndex() {
         return index;
     }
@@ -134,7 +125,7 @@ public class Edge {
 
     @Override
     public String toString() {
-        return String.format("<%s - %s>", left, right);
+        return String.format("<%s - %s>", LongBitmap.toString(left), 
LongBitmap.toString(right));
     }
 }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
index 83dc41c747..c73a2d9b08 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifier.java
@@ -17,7 +17,7 @@
 
 package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.Counter;
 import org.apache.doris.nereids.memo.Group;
 import org.apache.doris.nereids.memo.GroupExpression;
@@ -30,7 +30,6 @@ import 
org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
 import com.google.common.base.Preconditions;
 
 import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Optional;
@@ -56,7 +55,7 @@ public class GraphSimplifier {
     // It cached the plan in simplification. we don't store it in hyper graph,
     // because it's just used for simulating join. In fact, the graph 
simplifier
     // just generate the partial order of join operator.
-    private HashMap<BitSet, Plan> cachePlan = new HashMap<>();
+    private HashMap<Long, Plan> cachePlan = new HashMap<>();
 
     private Stack<SimplificationStep> appliedSteps = new 
Stack<SimplificationStep>();
     private Stack<SimplificationStep> unAppliedSteps = new 
Stack<SimplificationStep>();
@@ -99,7 +98,7 @@ public class GraphSimplifier {
             for (int j = i + 1; j < edgeSize; j++) {
                 Edge edge1 = graph.getEdge(i);
                 Edge edge2 = graph.getEdge(j);
-                List<BitSet> superset = new ArrayList<>();
+                List<Long> superset = new ArrayList<>();
                 tryGetSuperset(edge1.getLeft(), edge2.getLeft(), superset);
                 tryGetSuperset(edge1.getLeft(), edge2.getRight(), superset);
                 tryGetSuperset(edge1.getRight(), edge2.getLeft(), superset);
@@ -300,13 +299,13 @@ public class GraphSimplifier {
                 || circleDetector.checkCircleWithEdge(edgeIndex2, edgeIndex1)) 
{
             return Optional.empty();
         }
-        BitSet left1 = edge1.getLeft();
-        BitSet right1 = edge1.getRight();
-        BitSet left2 = edge2.getLeft();
-        BitSet right2 = edge2.getRight();
+        long left1 = edge1.getLeft();
+        long right1 = edge1.getRight();
+        long left2 = edge2.getLeft();
+        long right2 = edge2.getRight();
         Edge edge1Before2;
         Edge edge2Before1;
-        List<BitSet> superBitset = new ArrayList<>();
+        List<Long> superBitset = new ArrayList<>();
         if (tryGetSuperset(left1, left2, superBitset)) {
             // (common Join1 right1) Join2 right2
             edge1Before2 = threeLeftJoin(superBitset.get(0), edge1, right1, 
edge2, right2);
@@ -335,35 +334,35 @@ public class GraphSimplifier {
         return Optional.of(simplificationStep);
     }
 
-    Edge threeLeftJoin(BitSet bitSet1, Edge edge1, BitSet bitSet2, Edge edge2, 
BitSet bitSet3) {
+    Edge threeLeftJoin(long bitmap1, Edge edge1, long bitmap2, Edge edge2, 
long bitmap3) {
         // (plan1 edge1 plan2) edge2 plan3
         // The join may have redundant table, e.g., t1,t2 join t3 join t2,t4
         // Therefore, the cost is not accurate
         Preconditions.checkArgument(
-                cachePlan.containsKey(bitSet1) && 
cachePlan.containsKey(bitSet2) && cachePlan.containsKey(bitSet3));
-        LogicalJoin leftPlan = simulateJoin(cachePlan.get(bitSet1), 
edge1.getJoin(), cachePlan.get(bitSet2));
-        LogicalJoin join = simulateJoin(leftPlan, edge2.getJoin(), 
cachePlan.get(bitSet3));
+                cachePlan.containsKey(bitmap1) && 
cachePlan.containsKey(bitmap2) && cachePlan.containsKey(bitmap3));
+        LogicalJoin leftPlan = simulateJoin(cachePlan.get(bitmap1), 
edge1.getJoin(), cachePlan.get(bitmap2));
+        LogicalJoin join = simulateJoin(leftPlan, edge2.getJoin(), 
cachePlan.get(bitmap3));
         Edge edge = new Edge(join, -1);
-        BitSet newLeft = Bitmap.newBitmapUnion(bitSet1, bitSet2);
+        long newLeft = LongBitmap.newBitmapUnion(bitmap1, bitmap2);
         // To avoid overlapping the left and the right, the newLeft is 
calculated, Note the
         // newLeft is not totally include the bitset1 and bitset2, we use 
circle detector to trace the dependency
-        Bitmap.andNot(newLeft, bitSet3);
+        newLeft = LongBitmap.andNot(newLeft, bitmap3);
         edge.addLeftNodes(newLeft);
         edge.addRightNode(edge2.getRight());
         cachePlan.put(newLeft, leftPlan);
         return edge;
     }
 
-    Edge threeRightJoin(BitSet bitSet1, Edge edge1, BitSet bitSet2, Edge 
edge2, BitSet bitSet3) {
+    Edge threeRightJoin(long bitmap1, Edge edge1, long bitmap2, Edge edge2, 
long bitmap3) {
         Preconditions.checkArgument(
-                cachePlan.containsKey(bitSet1) && 
cachePlan.containsKey(bitSet2) && cachePlan.containsKey(bitSet3));
+                cachePlan.containsKey(bitmap1) && 
cachePlan.containsKey(bitmap2) && cachePlan.containsKey(bitmap3));
         // plan1 edge1 (plan2 edge2 plan3)
-        LogicalJoin rightPlan = simulateJoin(cachePlan.get(bitSet2), 
edge2.getJoin(), cachePlan.get(bitSet3));
-        LogicalJoin join = simulateJoin(cachePlan.get(bitSet1), 
edge1.getJoin(), rightPlan);
+        LogicalJoin rightPlan = simulateJoin(cachePlan.get(bitmap2), 
edge2.getJoin(), cachePlan.get(bitmap3));
+        LogicalJoin join = simulateJoin(cachePlan.get(bitmap1), 
edge1.getJoin(), rightPlan);
         Edge edge = new Edge(join, -1);
 
-        BitSet newRight = Bitmap.newBitmapUnion(bitSet2, bitSet3);
-        Bitmap.andNot(newRight, bitSet1);
+        long newRight = LongBitmap.newBitmapUnion(bitmap2, bitmap3);
+        newRight = LongBitmap.andNot(newRight, bitmap1);
         edge.addLeftNode(edge1.getLeft());
         edge.addRightNode(newRight);
         cachePlan.put(newRight, rightPlan);
@@ -403,12 +402,12 @@ public class GraphSimplifier {
         return step;
     }
 
-    private boolean tryGetSuperset(BitSet bitSet1, BitSet bitSet2, 
List<BitSet> superset) {
-        if (Bitmap.isSubset(bitSet1, bitSet2)) {
-            superset.add(bitSet2);
+    private boolean tryGetSuperset(long bitmap1, long bitmap2, List<Long> 
superset) {
+        if (LongBitmap.isSubset(bitmap1, bitmap2)) {
+            superset.add(bitmap2);
             return true;
-        } else if (Bitmap.isSubset(bitSet2, bitSet1)) {
-            superset.add(bitSet1);
+        } else if (LongBitmap.isSubset(bitmap2, bitmap1)) {
+            superset.add(bitmap1);
             return true;
         }
         return false;
@@ -465,13 +464,13 @@ public class GraphSimplifier {
         double benefit;
         int beforeIndex;
         int afterIndex;
-        BitSet newLeft;
-        BitSet newRight;
-        BitSet oldLeft;
-        BitSet oldRight;
+        long newLeft;
+        long newRight;
+        long oldLeft;
+        long oldRight;
 
-        SimplificationStep(double benefit, int beforeIndex, int afterIndex, 
BitSet newLeft, BitSet newRight,
-                BitSet oldLeft, BitSet oldRight) {
+        SimplificationStep(double benefit, int beforeIndex, int afterIndex, 
long newLeft, long newRight,
+                long oldLeft, long oldRight) {
             this.afterIndex = afterIndex;
             this.beforeIndex = beforeIndex;
             this.benefit = benefit;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
index 004824cf47..7e3f96af02 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/HyperGraph.java
@@ -17,7 +17,7 @@
 
 package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.memo.Group;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.Slot;
@@ -29,7 +29,6 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.List;
 import java.util.Set;
 
@@ -49,8 +48,8 @@ public class HyperGraph {
         return nodes;
     }
 
-    public BitSet getNodesMap() {
-        return Bitmap.newBitmapBetween(0, nodes.size());
+    public long getNodesMap() {
+        return LongBitmap.newBitmapBetween(0, nodes.size());
     }
 
     public Edge getEdge(int index) {
@@ -79,33 +78,35 @@ public class HyperGraph {
             LogicalJoin singleJoin = new LogicalJoin(join.getJoinType(), 
ImmutableList.of(expression), join.left(),
                     join.right());
             Edge edge = new Edge(singleJoin, edges.size());
-            BitSet bitSet = findNodes(expression.getInputSlots());
-            Preconditions.checkArgument(bitSet.cardinality() == 2,
+            long bitmap = findNodes(expression.getInputSlots());
+            Preconditions.checkArgument(LongBitmap.getCardinality(bitmap) == 2,
                     String.format("HyperGraph has not supported polynomial %s 
yet", expression));
-            int leftIndex = Bitmap.nextSetBit(bitSet, 0);
-            BitSet left = Bitmap.newBitmap(leftIndex);
+            int leftIndex = LongBitmap.nextSetBit(bitmap, 0);
+            long left = LongBitmap.newBitmap(leftIndex);
             edge.addLeftNode(left);
-            int rightIndex = Bitmap.nextSetBit(bitSet, leftIndex + 1);
-            BitSet right = Bitmap.newBitmap(rightIndex);
+            int rightIndex = LongBitmap.nextSetBit(bitmap, leftIndex + 1);
+            long right = LongBitmap.newBitmap(rightIndex);
             edge.addRightNode(right);
-            edge.getReferenceNodes().stream().forEach(index -> 
nodes.get(index).attachEdge(edge));
+            for (int nodeIndex : 
LongBitmap.getIterator(edge.getReferenceNodes())) {
+                nodes.get(nodeIndex).attachEdge(edge);
+            }
             edges.add(edge);
         }
         // In MySQL, each edge is reversed and store in edges again for 
reducing the branch miss
         // We don't implement this trick now.
     }
 
-    private BitSet findNodes(Set<Slot> slots) {
-        BitSet bitSet = Bitmap.newBitmap();
+    private long findNodes(Set<Slot> slots) {
+        long bitmap = LongBitmap.newBitmap();
         for (Node node : nodes) {
             for (Slot slot : node.getPlan().getOutput()) {
                 if (slots.contains(slot)) {
-                    Bitmap.set(bitSet, node.getIndex());
+                    bitmap = LongBitmap.set(bitmap, node.getIndex());
                     break;
                 }
             }
         }
-        return bitSet;
+        return bitmap;
     }
 
     /**
@@ -115,7 +116,7 @@ public class HyperGraph {
      * @param newLeft The new left of updated edge
      * @param newRight The new right of update edge
      */
-    public void modifyEdge(int edgeIndex, BitSet newLeft, BitSet newRight) {
+    public void modifyEdge(int edgeIndex, long newLeft, long newRight) {
         // When modify an edge in hyper graph, we need to update the left and 
right nodes
         // For these nodes that are only in the old edge, we need remove the 
edge from them
         // For these nodes that are only in the new edge, we need to add the 
edge to them
@@ -126,12 +127,12 @@ public class HyperGraph {
         edges.get(edgeIndex).setRight(newRight);
     }
 
-    private void updateEdges(Edge edge, BitSet oldNodes, BitSet newNodes) {
-        BitSet removeNodes = Bitmap.newBitmapDiff(oldNodes, newNodes);
-        Bitmap.getIterator(removeNodes).forEach(index -> 
nodes.get(index).removeEdge(edge));
+    private void updateEdges(Edge edge, long oldNodes, long newNodes) {
+        long removeNodes = LongBitmap.newBitmapDiff(oldNodes, newNodes);
+        LongBitmap.getIterator(removeNodes).forEach(index -> 
nodes.get(index).removeEdge(edge));
 
-        BitSet addedNodes = Bitmap.newBitmapDiff(newNodes, oldNodes);
-        Bitmap.getIterator(addedNodes).forEach(index -> 
nodes.get(index).attachEdge(edge));
+        long addedNodes = LongBitmap.newBitmapDiff(newNodes, oldNodes);
+        LongBitmap.getIterator(addedNodes).forEach(index -> 
nodes.get(index).attachEdge(edge));
     }
 
     /**
@@ -168,8 +169,8 @@ public class HyperGraph {
                     arrowHead = ",arrowhead=none";
                 }
 
-                int leftIndex = edge.getLeft().nextSetBit(0);
-                int rightIndex = edge.getRight().nextSetBit(0);
+                int leftIndex = LongBitmap.lowestOneIndex(edge.getLeft());
+                int rightIndex = LongBitmap.lowestOneIndex(edge.getRight());
                 builder.append(String.format("%s -> %s [label=\"%s\"%s]\n", 
graphvisNodes.get(leftIndex),
                         graphvisNodes.get(rightIndex), label, arrowHead));
             } else {
@@ -178,7 +179,7 @@ public class HyperGraph {
 
                 String leftLabel = "";
                 String rightLabel = "";
-                if (edge.getLeft().cardinality() == 1) {
+                if (LongBitmap.getCardinality(edge.getLeft()) == 1) {
                     rightLabel = label;
                 } else {
                     leftLabel = label;
@@ -186,16 +187,16 @@ public class HyperGraph {
 
                 int finalI = i;
                 String finalLeftLabel = leftLabel;
-                edge.getLeft().stream().forEach(nodeIndex -> {
+                for (int nodeIndex : LongBitmap.getIterator(edge.getLeft())) {
                     builder.append(String.format("%s -> e%d [arrowhead=none, 
label=\"%s\"]\n",
                             graphvisNodes.get(nodeIndex), finalI, 
finalLeftLabel));
-                });
+                }
 
                 String finalRightLabel = rightLabel;
-                edge.getRight().stream().forEach(nodeIndex -> {
+                for (int nodeIndex : LongBitmap.getIterator(edge.getRight())) {
                     builder.append(String.format("%s -> e%d [arrowhead=none, 
label=\"%s\"]\n",
                             graphvisNodes.get(nodeIndex), finalI, 
finalRightLabel));
-                });
+                }
             }
         }
         builder.append("}\n");
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Node.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Node.java
index ed7fd964c3..e25be46ad2 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Node.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/Node.java
@@ -17,14 +17,12 @@
 
 package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.memo.Group;
 import org.apache.doris.nereids.trees.plans.Plan;
 
 import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.List;
-import javax.annotation.Nullable;
 
 /**
  * HyperGraph Node.
@@ -33,54 +31,18 @@ public class Node {
     private final int index;
     private Group group;
     private List<Edge> edges = new ArrayList<>();
-    // We split these into simple edges (only one node on each side) and 
complex edges (others)
-    // because we can often quickly discard all simple edges by testing the 
set of interesting nodes
-    // against the “simple_neighborhood” bitmap. These data will be calculated 
before enumerate.
-    private List<Edge> complexEdges = new ArrayList<>();
-    private BitSet simpleNeighborhood = new BitSet();
-    private List<Edge> simpleEdges = new ArrayList<>();
-    private BitSet complexNeighborhood = new BitSet();
 
     public Node(int index, Group group) {
         this.group = group;
         this.index = index;
     }
 
-    /**
-     * Try to find the edge between this node and nodes
-     *
-     * @param nodes the other side of the edge
-     * @return The edge between this node and parameters
-     */
-    @Nullable
-    public Edge tryGetEdgeWith(BitSet nodes) {
-        if (Bitmap.isOverlap(simpleNeighborhood, nodes)) {
-            for (Edge edge : simpleEdges) {
-                if (Bitmap.isSubset(edge.getLeft(), nodes) || 
Bitmap.isSubset(edge.getRight(), nodes)) {
-                    return edge;
-                }
-            }
-            throw new RuntimeException(String.format("There is no simple Edge 
<%d - %s>", index, nodes));
-        } else if (Bitmap.isOverlap(complexNeighborhood, nodes)) {
-            for (Edge edge : complexEdges) {
-                // TODO: Right now we check all edges. But due to the simple 
cmp, we can only check that the edge with
-                // one side that equal to this node
-                if ((Bitmap.isSubset(edge.getLeft(), nodes) && 
Bitmap.isSubset(edge.getRight(),
-                        Bitmap.newBitmap(index))) || 
(Bitmap.isSubset(edge.getRight(), nodes) && Bitmap.isSubset(
-                        edge.getLeft(), Bitmap.newBitmap(index)))) {
-                    return edge;
-                }
-            }
-        }
-        return null;
-    }
-
     public int getIndex() {
         return index;
     }
 
-    public BitSet getNodeMap() {
-        return Bitmap.newBitmap(index);
+    public long getNodeMap() {
+        return LongBitmap.newBitmap(index);
     }
 
     public Plan getPlan() {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumerator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumerator.java
index f196d262c8..4cf59f37b5 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumerator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumerator.java
@@ -17,8 +17,8 @@
 
 package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
-import 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.SubsetIterator;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
+import 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmapSubsetIterator;
 import 
org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.AbstractReceiver;
 
 import com.google.common.base.Preconditions;
@@ -71,11 +71,11 @@ public class SubgraphEnumerator {
         neighborhoodCalculator = new NeighborhoodCalculator();
 
         // We skip the last element because it can't generate valid csg-cmp 
pair
-        BitSet forbiddenNodes = Bitmap.newBitmapBetween(0, size - 1);
+        long forbiddenNodes = LongBitmap.newBitmapBetween(0, size - 1);
         for (int i = size - 2; i >= 0; i--) {
-            BitSet csg = Bitmap.newBitmap(i);
-            Bitmap.unset(forbiddenNodes, i);
-            if (!emitCsg(csg) || !enumerateCsgRec(csg, 
Bitmap.newBitmap(forbiddenNodes))) {
+            long csg = LongBitmap.newBitmap(i);
+            forbiddenNodes = LongBitmap.unset(forbiddenNodes, i);
+            if (!emitCsg(csg) || !enumerateCsgRec(csg, 
LongBitmap.clone(forbiddenNodes))) {
                 return false;
             }
         }
@@ -84,11 +84,11 @@ public class SubgraphEnumerator {
 
     // The general purpose of EnumerateCsgRec is to extend a given set csg, 
which
     // induces a connected subgraph of G to a larger set with the same 
property.
-    private boolean enumerateCsgRec(BitSet csg, BitSet forbiddenNodes) {
-        BitSet neighborhood = neighborhoodCalculator.calcNeighborhood(csg, 
forbiddenNodes, edgeCalculator);
-        SubsetIterator subsetIterator = Bitmap.getSubsetIterator(neighborhood);
-        for (BitSet subset : subsetIterator) {
-            BitSet newCsg = Bitmap.newBitmapUnion(csg, subset);
+    private boolean enumerateCsgRec(long csg, long forbiddenNodes) {
+        long neighborhood = neighborhoodCalculator.calcNeighborhood(csg, 
forbiddenNodes, edgeCalculator);
+        LongBitmapSubsetIterator subsetIterator = 
LongBitmap.getSubsetIterator(neighborhood);
+        for (long subset : subsetIterator) {
+            long newCsg = LongBitmap.newBitmapUnion(csg, subset);
             if (receiver.contain(newCsg)) {
                 edgeCalculator.unionEdges(csg, subset);
                 if (!emitCsg(newCsg)) {
@@ -96,22 +96,22 @@ public class SubgraphEnumerator {
                 }
             }
         }
-        Bitmap.or(forbiddenNodes, neighborhood);
+        forbiddenNodes = LongBitmap.or(forbiddenNodes, neighborhood);
         subsetIterator.reset();
-        for (BitSet subset : subsetIterator) {
-            BitSet newCsg = Bitmap.newBitmapUnion(csg, subset);
-            if (!enumerateCsgRec(newCsg, Bitmap.newBitmap(forbiddenNodes))) {
+        for (long subset : subsetIterator) {
+            long newCsg = LongBitmap.newBitmapUnion(csg, subset);
+            if (!enumerateCsgRec(newCsg, LongBitmap.clone(forbiddenNodes))) {
                 return false;
             }
         }
         return true;
     }
 
-    private boolean enumerateCmpRec(BitSet csg, BitSet cmp, BitSet 
forbiddenNodes) {
-        BitSet neighborhood = neighborhoodCalculator.calcNeighborhood(cmp, 
forbiddenNodes, edgeCalculator);
-        SubsetIterator subsetIterator = new SubsetIterator(neighborhood);
-        for (BitSet subset : subsetIterator) {
-            BitSet newCmp = Bitmap.newBitmapUnion(cmp, subset);
+    private boolean enumerateCmpRec(long csg, long cmp, long forbiddenNodes) {
+        long neighborhood = neighborhoodCalculator.calcNeighborhood(cmp, 
forbiddenNodes, edgeCalculator);
+        LongBitmapSubsetIterator subsetIterator = new 
LongBitmapSubsetIterator(neighborhood);
+        for (long subset : subsetIterator) {
+            long newCmp = LongBitmap.newBitmapUnion(cmp, subset);
             // We need to check whether Cmp is connected and then try to find 
hyper edge
             if (receiver.contain(newCmp)) {
                 edgeCalculator.unionEdges(cmp, subset);
@@ -125,11 +125,11 @@ public class SubgraphEnumerator {
                 }
             }
         }
-        Bitmap.or(forbiddenNodes, neighborhood);
+        forbiddenNodes = LongBitmap.or(forbiddenNodes, neighborhood);
         subsetIterator.reset();
-        for (BitSet subset : subsetIterator) {
-            BitSet newCmp = Bitmap.newBitmapUnion(cmp, subset);
-            if (!enumerateCmpRec(csg, newCmp, 
Bitmap.newBitmap(forbiddenNodes))) {
+        for (long subset : subsetIterator) {
+            long newCmp = LongBitmap.newBitmapUnion(cmp, subset);
+            if (!enumerateCmpRec(csg, newCmp, 
LongBitmap.clone(forbiddenNodes))) {
                 return false;
             }
         }
@@ -139,14 +139,14 @@ public class SubgraphEnumerator {
     // EmitCsg takes as an argument a non-empty, proper subset csg of 
HyperGraph , which
     // induces a connected subgraph. It is then responsible to generate the 
seeds for
     // all cmp such that (csg, cmp) becomes a csg-cmp-pair.
-    private boolean emitCsg(BitSet csg) {
-        BitSet forbiddenNodes = Bitmap.newBitmapBetween(0, 
Bitmap.nextSetBit(csg, 0));
-        Bitmap.or(forbiddenNodes, csg);
-        BitSet neighborhoods = neighborhoodCalculator.calcNeighborhood(csg, 
Bitmap.newBitmap(forbiddenNodes),
+    private boolean emitCsg(long csg) {
+        long forbiddenNodes = LongBitmap.newBitmapBetween(0, 
LongBitmap.nextSetBit(csg, 0));
+        forbiddenNodes = LongBitmap.or(forbiddenNodes, csg);
+        long neighborhoods = neighborhoodCalculator.calcNeighborhood(csg, 
LongBitmap.clone(forbiddenNodes),
                 edgeCalculator);
 
-        for (int nodeIndex : Bitmap.getReverseIterator(neighborhoods)) {
-            BitSet cmp = Bitmap.newBitmap(nodeIndex);
+        for (int nodeIndex : LongBitmap.getReverseIterator(neighborhoods)) {
+            long cmp = LongBitmap.newBitmap(nodeIndex);
             // whether there is an edge between csg and cmp
             List<Edge> edges = edgeCalculator.connectCsgCmp(csg, cmp);
             if (edges.isEmpty()) {
@@ -165,9 +165,9 @@ public class SubgraphEnumerator {
             // 2. The cmp is {t2} and expanded from {t2} to {t2, t3}
             // We don't want get {t2, t3} twice. So In first enumeration, we
             // can exclude {t2}
-            BitSet newForbiddenNodes = Bitmap.newBitmapBetween(0, nodeIndex + 
1);
-            Bitmap.and(newForbiddenNodes, neighborhoods);
-            Bitmap.or(newForbiddenNodes, forbiddenNodes);
+            long newForbiddenNodes = LongBitmap.newBitmapBetween(0, nodeIndex 
+ 1);
+            newForbiddenNodes = LongBitmap.and(newForbiddenNodes, 
neighborhoods);
+            newForbiddenNodes = LongBitmap.or(newForbiddenNodes, 
forbiddenNodes);
             if (!enumerateCmpRec(csg, cmp, newForbiddenNodes)) {
                 return false;
             }
@@ -183,21 +183,22 @@ public class SubgraphEnumerator {
         // expand csg and cmp. In fact, we just need a seed node that can be 
expanded
         // to all subgraph. That is any one node of hyper nodes. In fact, the 
neighborhoods
         // is the minimum set that we choose one node from above v.
-        public BitSet calcNeighborhood(BitSet subgraph, BitSet forbiddenNodes, 
EdgeCalculator edgeCalculator) {
-            BitSet neighborhoods = Bitmap.newBitmap();
-            edgeCalculator.foundSimpleEdgesContain(subgraph)
-                    .forEach(edge -> 
neighborhoods.or(edge.getReferenceNodes()));
-            Bitmap.or(forbiddenNodes, subgraph);
-            Bitmap.andNot(neighborhoods, forbiddenNodes);
-            Bitmap.or(forbiddenNodes, neighborhoods);
+        public long calcNeighborhood(long subgraph, long forbiddenNodes, 
EdgeCalculator edgeCalculator) {
+            long neighborhoods = LongBitmap.newBitmap();
+            for (Edge edge : edgeCalculator.foundSimpleEdgesContain(subgraph)) 
{
+                neighborhoods = LongBitmap.or(neighborhoods, 
edge.getReferenceNodes());
+            }
+            forbiddenNodes = LongBitmap.or(forbiddenNodes, subgraph);
+            neighborhoods = LongBitmap.andNot(neighborhoods, forbiddenNodes);
+            forbiddenNodes = LongBitmap.or(forbiddenNodes, neighborhoods);
 
             for (Edge edge : 
edgeCalculator.foundComplexEdgesContain(subgraph)) {
-                BitSet left = edge.getLeft();
-                BitSet right = edge.getRight();
-                if (Bitmap.isSubset(left, subgraph) && 
!Bitmap.isOverlap(right, forbiddenNodes)) {
-                    Bitmap.set(neighborhoods, right.nextSetBit(0));
-                } else if (Bitmap.isSubset(right, subgraph) && 
!Bitmap.isOverlap(left, forbiddenNodes)) {
-                    Bitmap.set(neighborhoods, left.nextSetBit(0));
+                long left = edge.getLeft();
+                long right = edge.getRight();
+                if (LongBitmap.isSubset(left, subgraph) && 
!LongBitmap.isOverlap(right, forbiddenNodes)) {
+                    neighborhoods = LongBitmap.set(neighborhoods, 
LongBitmap.lowestOneIndex(right));
+                } else if (LongBitmap.isSubset(right, subgraph) && 
!LongBitmap.isOverlap(left, forbiddenNodes)) {
+                    neighborhoods = LongBitmap.set(neighborhoods, 
LongBitmap.lowestOneIndex(left));
                 }
             }
             return neighborhoods;
@@ -212,17 +213,17 @@ public class SubgraphEnumerator {
         // because we can often quickly discard all simple edges by testing 
the set of interesting nodes
         // against the “simple_neighborhood” bitmap. These data will be 
calculated before enumerate.
 
-        HashMap<BitSet, BitSet> containSimpleEdges = new HashMap<>();
-        HashMap<BitSet, BitSet> containComplexEdges = new HashMap<>();
+        HashMap<Long, BitSet> containSimpleEdges = new HashMap<>();
+        HashMap<Long, BitSet> containComplexEdges = new HashMap<>();
         // It cached all edges that overlap by this subgraph. All this edges 
must be
         // complex edges
-        HashMap<BitSet, BitSet> overlapEdges = new HashMap<>();
+        HashMap<Long, BitSet> overlapEdges = new HashMap<>();
 
         EdgeCalculator(List<Edge> edges) {
             this.edges = edges;
         }
 
-        public void initSubgraph(BitSet subgraph) {
+        public void initSubgraph(long subgraph) {
             BitSet simpleContains = new BitSet();
             BitSet complexContains = new BitSet();
             BitSet overlaps = new BitSet();
@@ -249,26 +250,29 @@ public class SubgraphEnumerator {
             containComplexEdges.put(subgraph, complexContains);
         }
 
-        public void unionEdges(BitSet bitSet1, BitSet bitSet2) {
+        public void unionEdges(long bitmap1, long bitmap2) {
             // When union two sub graphs, we only need to check overlap edges.
             // However, if all reference nodes are contained by the subgraph,
             // we should remove it.
-            if (!containSimpleEdges.containsKey(bitSet1)) {
-                initSubgraph(bitSet1);
+            if (!containSimpleEdges.containsKey(bitmap1)) {
+                initSubgraph(bitmap1);
             }
-            if (!containSimpleEdges.containsKey(bitSet2)) {
-                initSubgraph(bitSet2);
+            if (!containSimpleEdges.containsKey(bitmap2)) {
+                initSubgraph(bitmap2);
             }
-            BitSet subgraph = Bitmap.newBitmapUnion(bitSet1, bitSet2);
+            long subgraph = LongBitmap.newBitmapUnion(bitmap1, bitmap2);
             if (containSimpleEdges.containsKey(subgraph)) {
                 return;
             }
-            BitSet simpleContains = 
Bitmap.newBitmapUnion(containSimpleEdges.get(bitSet1),
-                    containSimpleEdges.get(bitSet2));
-            BitSet complexContains = 
Bitmap.newBitmapUnion(containComplexEdges.get(bitSet1),
-                    containComplexEdges.get(bitSet2));
-            BitSet overlaps = Bitmap.newBitmapUnion(overlapEdges.get(bitSet1),
-                    overlapEdges.get(bitSet2));
+            BitSet simpleContains = new BitSet();
+            simpleContains.or(containSimpleEdges.get(bitmap1));
+            simpleContains.or(containSimpleEdges.get(bitmap2));
+            BitSet complexContains = new BitSet();
+            simpleContains.or(containComplexEdges.get(bitmap1));
+            simpleContains.or(containComplexEdges.get(bitmap2));
+            BitSet overlaps = new BitSet();
+            simpleContains.or(overlapEdges.get(bitmap1));
+            simpleContains.or(overlapEdges.get(bitmap2));
             for (int index : overlaps.stream().toArray()) {
                 Edge edge = edges.get(index);
                 if (isContainEdge(subgraph, edge)) {
@@ -287,19 +291,22 @@ public class SubgraphEnumerator {
             overlapEdges.put(subgraph, overlaps);
         }
 
-        public List<Edge> connectCsgCmp(BitSet bitSet1, BitSet bitSet2) {
+        public List<Edge> connectCsgCmp(long csg, long cmp) {
             Preconditions.checkArgument(
-                    containSimpleEdges.containsKey(bitSet1) && 
containSimpleEdges.containsKey(bitSet2));
+                    containSimpleEdges.containsKey(csg) && 
containSimpleEdges.containsKey(cmp));
             List<Edge> foundEdges = new ArrayList<>();
-            BitSet edgeMap = 
Bitmap.newBitmapIntersect(containSimpleEdges.get(bitSet1),
-                    containSimpleEdges.get(bitSet2));
-            Bitmap.or(edgeMap, 
Bitmap.newBitmapIntersect(containComplexEdges.get(bitSet1),
-                    containComplexEdges.get(bitSet2)));
+            BitSet edgeMap = new BitSet();
+            edgeMap.or(containSimpleEdges.get(csg));
+            edgeMap.and(containSimpleEdges.get(cmp));
+            BitSet complexes = new BitSet();
+            complexes.or(containComplexEdges.get(csg));
+            complexes.and(containComplexEdges.get(cmp));
+            edgeMap.or(complexes);
             edgeMap.stream().forEach(index -> 
foundEdges.add(edges.get(index)));
             return foundEdges;
         }
 
-        public List<Edge> foundEdgesContain(BitSet subgraph) {
+        public List<Edge> foundEdgesContain(long subgraph) {
             
Preconditions.checkArgument(containSimpleEdges.containsKey(subgraph));
             BitSet edgeMap = containSimpleEdges.get(subgraph);
             edgeMap.or(containComplexEdges.get(subgraph));
@@ -308,7 +315,7 @@ public class SubgraphEnumerator {
             return foundEdges;
         }
 
-        public List<Edge> foundSimpleEdgesContain(BitSet subgraph) {
+        public List<Edge> foundSimpleEdgesContain(long subgraph) {
             List<Edge> foundEdges = new ArrayList<>();
             if (!containSimpleEdges.containsKey(subgraph)) {
                 return foundEdges;
@@ -318,7 +325,7 @@ public class SubgraphEnumerator {
             return foundEdges;
         }
 
-        public List<Edge> foundComplexEdgesContain(BitSet subgraph) {
+        public List<Edge> foundComplexEdgesContain(long subgraph) {
             List<Edge> foundEdges = new ArrayList<>();
             if (!containComplexEdges.containsKey(subgraph)) {
                 return foundEdges;
@@ -328,24 +335,24 @@ public class SubgraphEnumerator {
             return foundEdges;
         }
 
-        public int getEdgeSizeContain(BitSet subgraph) {
+        public int getEdgeSizeContain(long subgraph) {
             
Preconditions.checkArgument(containSimpleEdges.containsKey(subgraph));
             return containSimpleEdges.get(subgraph).cardinality() + 
containSimpleEdges.get(subgraph).cardinality();
         }
 
-        private boolean isContainEdge(BitSet subgraph, Edge edge) {
-            int containLeft = Bitmap.isSubset(edge.getLeft(), subgraph) ? 0 : 
1;
-            int containRight = Bitmap.isSubset(edge.getRight(), subgraph) ? 0 
: 1;
+        private boolean isContainEdge(long subgraph, Edge edge) {
+            int containLeft = LongBitmap.isSubset(edge.getLeft(), subgraph) ? 
0 : 1;
+            int containRight = LongBitmap.isSubset(edge.getRight(), subgraph) 
? 0 : 1;
             return containLeft + containRight == 1;
         }
 
-        private boolean isOverlapEdge(BitSet subgraph, Edge edge) {
-            int overlapLeft = Bitmap.isOverlap(edge.getLeft(), subgraph) ? 0 : 
1;
-            int overlapRight = Bitmap.isOverlap(edge.getRight(), subgraph) ? 0 
: 1;
+        private boolean isOverlapEdge(long subgraph, Edge edge) {
+            int overlapLeft = LongBitmap.isOverlap(edge.getLeft(), subgraph) ? 
0 : 1;
+            int overlapRight = LongBitmap.isOverlap(edge.getRight(), subgraph) 
? 0 : 1;
             return overlapLeft + overlapRight == 1;
         }
 
-        private BitSet removeInvalidEdges(BitSet subgraph, BitSet edgeMap) {
+        private BitSet removeInvalidEdges(long subgraph, BitSet edgeMap) {
             for (int index : edgeMap.stream().toArray()) {
                 Edge edge = edges.get(index);
                 if (!isOverlapEdge(subgraph, edge)) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/Bitmap.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/Bitmap.java
deleted file mode 100644
index 1942e29368..0000000000
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/Bitmap.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
-
-import java.util.BitSet;
-
-/**
- * This is helper class for some bitmap operation
- */
-public class Bitmap {
-    public static boolean isSubset(BitSet bitSet1, BitSet bitSet2) {
-        BitSet bitSet = new BitSet();
-        bitSet.or(bitSet1);
-        bitSet.andNot(bitSet2);
-        return bitSet.cardinality() == 0;
-    }
-
-    public static BitSet newBitmap(int... values) {
-        BitSet bitSet = new BitSet();
-        for (int v : values) {
-            bitSet.set(v);
-        }
-        return bitSet;
-    }
-
-    public static BitSet newBitmap(BitSet bitSet) {
-        BitSet n = new BitSet();
-        n.or(bitSet);
-        return n;
-    }
-
-    public static BitSet newBitmap() {
-        return new BitSet();
-    }
-
-    public static BitSet newBitmapUnion(BitSet... bitSets) {
-        BitSet u = new BitSet();
-        for (BitSet bitSet : bitSets) {
-            u.or(bitSet);
-        }
-        return u;
-    }
-
-    // return bitSet1 - bitSet2
-    public static BitSet newBitmapDiff(BitSet bitSet1, BitSet bitSet2) {
-        BitSet u = new BitSet();
-        u.or(bitSet1);
-        u.andNot(bitSet2);
-        return u;
-    }
-
-    //return bitset1 ∩ bitset2
-    public static BitSet newBitmapIntersect(BitSet bitSet1, BitSet bitSet2) {
-        BitSet intersect = newBitmap();
-        intersect.or(bitSet1);
-        intersect.and(bitSet2);
-        return intersect;
-    }
-
-    public static BitSet newBitmapBetween(int start, int end) {
-        BitSet bitSet = new BitSet();
-        bitSet.set(start, end);
-        return bitSet;
-    }
-
-    public static int nextSetBit(BitSet bitSet, int fromIndex) {
-        return bitSet.nextSetBit(fromIndex);
-    }
-
-    public static boolean get(BitSet bitSet, int index) {
-        return bitSet.get(index);
-    }
-
-    public static void set(BitSet bitSet, int index) {
-        bitSet.set(index);
-    }
-
-    public static void unset(BitSet bitSet, int index) {
-        bitSet.set(index, false);
-    }
-
-    public static void clear(BitSet bitSet) {
-        bitSet.clear();
-    }
-
-    public static int getCardinality(BitSet bitSet) {
-        return bitSet.cardinality();
-    }
-
-    public static BitSetIterator getIterator(BitSet bitSet) {
-        return new BitSetIterator(bitSet);
-    }
-
-    public static ReverseBitSetIterator getReverseIterator(BitSet bitSet) {
-        return new ReverseBitSetIterator(bitSet);
-    }
-
-    public static void or(BitSet bitSet1, BitSet bitSet2) {
-        bitSet1.or(bitSet2);
-    }
-
-    public static boolean isOverlap(BitSet bitSet1, BitSet bitSet2) {
-        return bitSet1.intersects(bitSet2);
-    }
-
-    public static void andNot(BitSet bitSet1, BitSet bitSet2) {
-        bitSet1.andNot(bitSet2);
-    }
-
-    public static void and(BitSet bitSet1, BitSet bitSet2) {
-        bitSet1.and(bitSet2);
-    }
-
-    public static SubsetIterator getSubsetIterator(BitSet bitSet) {
-        return new SubsetIterator(bitSet);
-    }
-
-}
-
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmap.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmap.java
new file mode 100644
index 0000000000..93a81f2580
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmap.java
@@ -0,0 +1,156 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
+
+import java.util.BitSet;
+
+/**
+ * This is helper class for some bitmap operation
+ */
+public class LongBitmap {
+    private static final long MASK = 0xffffffffffffffffL;
+    private static final int SIZE = Long.SIZE;
+
+    public static boolean isSubset(long bitmap1, long bitmap2) {
+        return (bitmap1 | bitmap2) == bitmap2;
+    }
+
+    public static long newBitmap(int... values) {
+        long bitmap = 0;
+        for (int v : values) {
+            bitmap |= (1L << v);
+        }
+        return bitmap;
+    }
+
+    public static long newBitmap(int value) {
+        return 1L << value;
+    }
+
+    public static long newBitmap() {
+        return 0;
+    }
+
+    public static long clone(long bitmap) {
+        return bitmap;
+    }
+
+    public static long newBitmapUnion(long... bitmaps) {
+        long u = 0;
+        for (long bitmap : bitmaps) {
+            u |= bitmap;
+        }
+        return u;
+    }
+
+    public static long newBitmapUnion(long b1, long b2) {
+        return b1 | b2;
+    }
+
+    // return bitSet1 - bitSet2
+    public static long newBitmapDiff(long bitmap1, long bitmap2) {
+        return bitmap1 & (~bitmap2);
+    }
+
+    //return bitset1 ∩ bitset2
+    public static long newBitmapIntersect(long bitmap1, long bitmap2) {
+        return bitmap1 & bitmap2;
+    }
+
+    public static long newBitmapBetween(int start, int end) {
+        long bitmap = 0;
+        for (int i = start; i < end; i++) {
+            bitmap |= (1L << i);
+        }
+        return bitmap;
+    }
+
+    public static int nextSetBit(long bitmap, int fromIndex) {
+        bitmap &= (MASK << fromIndex);
+        bitmap = bitmap & (-bitmap);
+        return Long.numberOfTrailingZeros(bitmap);
+    }
+
+    public static boolean get(long bitmap, int index) {
+        return (bitmap & (1L << index)) != 0;
+    }
+
+    public static long set(long bitmap, int index) {
+        return bitmap | (1L << index);
+    }
+
+    public static long unset(long bitmap, int index) {
+        return bitmap & (~(1L << index));
+    }
+
+    public static long clear(long bitSet) {
+        return 0;
+    }
+
+    public static int getCardinality(long bimap) {
+        return Long.bitCount(bimap);
+    }
+
+    public static LongBitmapIterator getIterator(long bitmap) {
+        return new LongBitmapIterator(bitmap);
+    }
+
+    public static LongBitmapReverseIterator getReverseIterator(long bitmap) {
+        return new LongBitmapReverseIterator(bitmap);
+    }
+
+    public static long or(long bitmap1, long bitmap2) {
+        return bitmap1 | bitmap2;
+    }
+
+    public static boolean isOverlap(long bitmap1, long bitmap2) {
+        return (bitmap1 & bitmap2) != 0;
+    }
+
+    public static long andNot(long bitmap1, long bitmap2) {
+        return (bitmap1 & ~(bitmap2));
+    }
+
+    public static long and(long bitmap1, long bitmap2) {
+        return bitmap1 & bitmap2;
+    }
+
+    public static LongBitmapSubsetIterator getSubsetIterator(long bitmap) {
+        return new LongBitmapSubsetIterator(bitmap);
+    }
+
+    public static long clearLowestBit(long bitmap) {
+        return bitmap & (bitmap - 1);
+    }
+
+    public static int previousSetBit(long bitmap, int fromIndex) {
+        long newBitmap = bitmap & (MASK >>> -(fromIndex + 1));
+        return SIZE - Long.numberOfLeadingZeros(newBitmap) - 1;
+    }
+
+    public static int lowestOneIndex(long bitmap) {
+        return Long.numberOfTrailingZeros(bitmap);
+    }
+
+    public static String toString(long bitmap) {
+        long[] longs = {bitmap};
+        BitSet bitSet = BitSet.valueOf(longs);
+        return bitSet.toString();
+    }
+}
+
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/BitSetIterator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapIterator.java
similarity index 79%
rename from 
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/BitSetIterator.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapIterator.java
index 77d55da361..0e2a72d5a2 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/BitSetIterator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapIterator.java
@@ -19,19 +19,17 @@ package 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
 
 import org.jetbrains.annotations.NotNull;
 
-import java.util.BitSet;
 import java.util.Iterator;
 
 /**
  * This is an Iterator for iterating bitmap
  */
-public class BitSetIterator implements Iterable<Integer> {
-    int lastIndex = -1;
-    int readNum = 0;
-    BitSet bitSet;
+public class LongBitmapIterator implements Iterable<Integer> {
+    private long bitmap;
+    private int lastIndex = 0;
 
-    BitSetIterator(BitSet bitSet) {
-        this.bitSet = bitSet;
+    LongBitmapIterator(long bitmap) {
+        this.bitmap = bitmap;
     }
 
     @NotNull
@@ -40,13 +38,13 @@ public class BitSetIterator implements Iterable<Integer> {
         class Iter implements Iterator<Integer> {
             @Override
             public boolean hasNext() {
-                return (readNum < bitSet.cardinality());
+                return bitmap != 0;
             }
 
             @Override
             public Integer next() {
-                lastIndex = bitSet.nextSetBit(lastIndex + 1);
-                readNum += 1;
+                lastIndex = LongBitmap.nextSetBit(bitmap, lastIndex);
+                bitmap = LongBitmap.clearLowestBit(bitmap);
                 return lastIndex;
             }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/ReverseBitSetIterator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapReverseIterator.java
similarity index 77%
rename from 
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/ReverseBitSetIterator.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapReverseIterator.java
index 125f05dc1c..ab1d2c82c9 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/ReverseBitSetIterator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapReverseIterator.java
@@ -19,20 +19,18 @@ package 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
 
 import org.jetbrains.annotations.NotNull;
 
-import java.util.BitSet;
 import java.util.Iterator;
 
 /**
  * This is an Iterator for iterating bitmap descending
  */
-public class ReverseBitSetIterator implements Iterable<Integer> {
-    int lastIndex = 0;
-    int readNum = 0;
-    BitSet bitSet;
-
-    ReverseBitSetIterator(BitSet bitSet) {
-        this.bitSet = bitSet;
-        lastIndex = bitSet.size();
+public class LongBitmapReverseIterator implements Iterable<Integer> {
+    private int lastIndex = 0;
+    private long bitmap;
+
+    LongBitmapReverseIterator(long bitmap) {
+        this.bitmap = bitmap;
+        lastIndex = 63;
     }
 
     @NotNull
@@ -41,13 +39,13 @@ public class ReverseBitSetIterator implements 
Iterable<Integer> {
         class Iter implements Iterator<Integer> {
             @Override
             public boolean hasNext() {
-                return (readNum < bitSet.cardinality());
+                return bitmap != 0;
             }
 
             @Override
             public Integer next() {
-                lastIndex = bitSet.previousSetBit(lastIndex - 1);
-                readNum += 1;
+                lastIndex = LongBitmap.previousSetBit(bitmap, lastIndex);
+                bitmap = LongBitmap.unset(bitmap, lastIndex);
                 return lastIndex;
             }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/SubsetIterator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapSubsetIterator.java
similarity index 53%
rename from 
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/SubsetIterator.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapSubsetIterator.java
index 8b7c2921df..f2c493e85d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/SubsetIterator.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/bitmap/LongBitmapSubsetIterator.java
@@ -19,63 +19,44 @@ package 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap;
 
 import org.jetbrains.annotations.NotNull;
 
-import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.Iterator;
-import java.util.List;
 
 /**
  * This is a class for iterating all true subset of a bitset, referenced in
  * 
https://groups.google.com/forum/#!msg/rec.games.chess/KnJvBnhgDKU/yCi5yBx18PQJ
  */
-public class SubsetIterator implements Iterable<BitSet> {
-    List<BitSet> subsets = new ArrayList<>();
-    int cursor = 0;
+public class LongBitmapSubsetIterator implements Iterable<Long> {
+    private long bitmap;
+    private long state;
 
     /**
      * Generate all subset for this bitSet
      *
-     * @param bitSet The bitset that need to be generated
+     * @param bitmap The bitset that need to be generated
      */
-    public SubsetIterator(BitSet bitSet) {
-        long[] setVal = bitSet.toLongArray();
-        int len = setVal.length;
-        long[] baseVal = new long[len];
-        subsets.add(new BitSet());
-        for (int i = 0; i < len; i++) {
-            long subVal = (-setVal[i]) & setVal[i];
-            int size = subsets.size();
-            while (subVal != 0) {
-                baseVal[i] = subVal;
-                for (int j = 0; j < size; j++) {
-                    BitSet newSubset = BitSet.valueOf(baseVal);
-                    newSubset.or(subsets.get(j));
-                    subsets.add(newSubset);
-                }
-                subVal = (subVal - setVal[i]) & setVal[i];
-            }
-            baseVal[i] = 0;
-        }
-        // remove empty subset
-        subsets.remove(0);
+    public LongBitmapSubsetIterator(long bitmap) {
+        this.bitmap = bitmap;
+        this.state = (-bitmap) & bitmap;
     }
 
     public void reset() {
-        cursor = 0;
+        state = (-bitmap) & bitmap;
     }
 
     @NotNull
     @Override
-    public Iterator<BitSet> iterator() {
-        class Iter implements Iterator<BitSet> {
+    public Iterator<Long> iterator() {
+        class Iter implements Iterator<Long> {
             @Override
             public boolean hasNext() {
-                return (cursor < subsets.size());
+                return state != 0;
             }
 
             @Override
-            public BitSet next() {
-                return subsets.get(cursor++);
+            public Long next() {
+                Long subset = state;
+                state = (state - bitmap) & bitmap;
+                return subset;
             }
 
             @Override
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/AbstractReceiver.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/AbstractReceiver.java
index cfe6dbeb23..975c351248 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/AbstractReceiver.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/AbstractReceiver.java
@@ -20,20 +20,19 @@ package 
org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver;
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.Edge;
 import org.apache.doris.nereids.memo.Group;
 
-import java.util.BitSet;
 import java.util.List;
 
 /**
  * A interface of receiver
  */
 public interface AbstractReceiver {
-    public boolean emitCsgCmp(BitSet csg, BitSet cmp, List<Edge> edges);
+    public boolean emitCsgCmp(long csg, long cmp, List<Edge> edges);
 
-    public void addGroup(BitSet bitSet, Group group);
+    public void addGroup(long bitSet, Group group);
 
-    public boolean contain(BitSet bitSet);
+    public boolean contain(long bitSet);
 
     public void reset();
 
-    public Group getBestPlan(BitSet bitSet);
+    public Group getBestPlan(long bitSet);
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/Counter.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/Counter.java
index 4a3969c12a..7326bee3f5 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/Counter.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/Counter.java
@@ -18,11 +18,11 @@
 package org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver;
 
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.Edge;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.memo.Group;
 
 import com.google.common.base.Preconditions;
 
-import java.util.BitSet;
 import java.util.HashMap;
 import java.util.List;
 
@@ -33,7 +33,7 @@ public class Counter implements AbstractReceiver {
     // limit define the max number of csg-cmp pair in this Receiver
     private int limit;
     private int emitCount = 0;
-    private HashMap<BitSet, Integer> counter = new HashMap<>();
+    private HashMap<Long, Integer> counter = new HashMap<>();
 
     public Counter() {
         this.limit = Integer.MAX_VALUE;
@@ -51,30 +51,28 @@ public class Counter implements AbstractReceiver {
      * @param edges the join operator
      * @return the left and the right can be connected by the edge
      */
-    public boolean emitCsgCmp(BitSet left, BitSet right, List<Edge> edges) {
+    public boolean emitCsgCmp(long left, long right, List<Edge> edges) {
         Preconditions.checkArgument(counter.containsKey(left));
         Preconditions.checkArgument(counter.containsKey(right));
         emitCount += 1;
         if (emitCount > limit) {
             return false;
         }
-        BitSet bitSet = new BitSet();
-        bitSet.or(left);
-        bitSet.or(right);
-        if (!counter.containsKey(bitSet)) {
-            counter.put(bitSet, counter.get(left) * counter.get(right));
+        long bitmap = LongBitmap.newBitmapUnion(left, right);
+        if (!counter.containsKey(bitmap)) {
+            counter.put(bitmap, counter.get(left) * counter.get(right));
         } else {
-            counter.put(bitSet, counter.get(bitSet) + counter.get(left) * 
counter.get(right));
+            counter.put(bitmap, counter.get(bitmap) + counter.get(left) * 
counter.get(right));
         }
         return true;
     }
 
-    public void addGroup(BitSet bitSet, Group group) {
-        counter.put(bitSet, 1);
+    public void addGroup(long bitmap, Group group) {
+        counter.put(bitmap, 1);
     }
 
-    public boolean contain(BitSet bitSet) {
-        return counter.containsKey(bitSet);
+    public boolean contain(long bitmap) {
+        return counter.containsKey(bitmap);
     }
 
     public void reset() {
@@ -82,15 +80,15 @@ public class Counter implements AbstractReceiver {
         emitCount = 0;
     }
 
-    public Group getBestPlan(BitSet bitSet) {
+    public Group getBestPlan(long bitmap) {
         throw new RuntimeException("Counter does not support getBestPlan()");
     }
 
-    public int getCount(BitSet bitSet) {
-        return counter.get(bitSet);
+    public int getCount(long bitmap) {
+        return counter.get(bitmap);
     }
 
-    public HashMap<BitSet, Integer> getAllCount() {
+    public HashMap<Long, Integer> getAllCount() {
         return counter;
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/PlanReceiver.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/PlanReceiver.java
index 0658edcc1b..93a2f0ce47 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/PlanReceiver.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/receiver/PlanReceiver.java
@@ -18,7 +18,7 @@
 package org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver;
 
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.Edge;
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
 import org.apache.doris.nereids.memo.Group;
 import org.apache.doris.nereids.memo.GroupExpression;
 import org.apache.doris.nereids.properties.PhysicalProperties;
@@ -31,7 +31,6 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.HashMap;
 import java.util.List;
 
@@ -40,7 +39,7 @@ import java.util.List;
  */
 public class PlanReceiver implements AbstractReceiver {
     // limit define the max number of csg-cmp pair in this Receiver
-    HashMap<BitSet, Group> planTable = new HashMap<>();
+    HashMap<Long, Group> planTable = new HashMap<>();
     int limit;
     int emitCount = 0;
 
@@ -61,14 +60,14 @@ public class PlanReceiver implements AbstractReceiver {
      * @return the left and the right can be connected by the edge
      */
     @Override
-    public boolean emitCsgCmp(BitSet left, BitSet right, List<Edge> edges) {
+    public boolean emitCsgCmp(long left, long right, List<Edge> edges) {
         Preconditions.checkArgument(planTable.containsKey(left));
         Preconditions.checkArgument(planTable.containsKey(right));
         emitCount += 1;
         if (emitCount > limit) {
             return false;
         }
-        BitSet fullKey = Bitmap.newBitmapUnion(left, right);
+        long fullKey = LongBitmap.newBitmapUnion(left, right);
         Group group1 = constructGroup(left, right, edges);
         Group group2 = constructGroup(right, left, edges);
         Group winnerGroup;
@@ -88,13 +87,13 @@ public class PlanReceiver implements AbstractReceiver {
     }
 
     @Override
-    public void addGroup(BitSet bitSet, Group group) {
-        planTable.put(bitSet, group);
+    public void addGroup(long bitmap, Group group) {
+        planTable.put(bitmap, group);
     }
 
     @Override
-    public boolean contain(BitSet bitSet) {
-        return planTable.containsKey(bitSet);
+    public boolean contain(long bitmap) {
+        return planTable.containsKey(bitmap);
     }
 
     @Override
@@ -104,9 +103,9 @@ public class PlanReceiver implements AbstractReceiver {
     }
 
     @Override
-    public Group getBestPlan(BitSet bitSet) {
-        Preconditions.checkArgument(planTable.containsKey(bitSet));
-        return planTable.get(bitSet);
+    public Group getBestPlan(long bitmap) {
+        Preconditions.checkArgument(planTable.containsKey(bitmap));
+        return planTable.get(bitmap);
     }
 
     private double getSimpleCost(Plan plan) {
@@ -116,7 +115,7 @@ public class PlanReceiver implements AbstractReceiver {
         return 
plan.getGroupExpression().get().getCostByProperties(PhysicalProperties.ANY);
     }
 
-    private Group constructGroup(BitSet left, BitSet right, List<Edge> edges) {
+    private Group constructGroup(long left, long right, List<Edge> edges) {
         Preconditions.checkArgument(planTable.containsKey(left));
         Preconditions.checkArgument(planTable.containsKey(right));
         Group leftGroup = planTable.get(left);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java
index 1ecec2d296..2fa73db681 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java
@@ -460,6 +460,16 @@ public class Memo {
         return CopyInResult.of(false, existedLogicalExpression);
     }
 
+    // This function is used to copy new group expression
+    // It's used in DPHyp after construct new group expression
+    public Group copyInGroupExpression(GroupExpression newGroupExpression) {
+        Group newGroup = new Group(groupIdGenerator.getNextId(), 
newGroupExpression,
+                newGroupExpression.getPlan().getLogicalProperties());
+        groups.put(newGroup.getGroupId(), newGroup);
+        groupExpressions.put(newGroupExpression, newGroupExpression);
+        return newGroup;
+    }
+
     private CopyInResult rewriteByNewGroupExpression(Group targetGroup, Plan 
newPlan,
             GroupExpression newGroupExpression) {
         if (targetGroup == null) {
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitSetTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitSetTest.java
deleted file mode 100644
index 20b69583ac..0000000000
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitSetTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.nereids.jobs.joinorder.hypergraph;
-
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
-import 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.SubsetIterator;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import java.util.BitSet;
-import java.util.HashSet;
-
-public class BitSetTest {
-    @Test
-    void subsetIteratorTest() {
-        BitSet bitSet = new BitSet();
-        bitSet.set(0, 3);
-        bitSet.set(64, 67);
-        SubsetIterator subsetIterator = new SubsetIterator(bitSet);
-        HashSet<BitSet> subsets = new HashSet<>();
-        for (BitSet subset : subsetIterator) {
-            Assertions.assertTrue(Bitmap.isSubset(subset, bitSet));
-            subsets.add(subset);
-        }
-        Assertions.assertEquals(subsets.size(), Math.pow(2, 6) - 1);
-    }
-}
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitmapTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitmapTest.java
new file mode 100644
index 0000000000..9939b66a4d
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/BitmapTest.java
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.jobs.joinorder.hypergraph;
+
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
+import 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmapSubsetIterator;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashSet;
+
+public class BitmapTest {
+    @Test
+    void subsetIteratorTest() {
+        int[] ints = {1, 3, 5, 12, 21, 32, 43, 54, 60, 63};
+        long bitmap = LongBitmap.newBitmap(ints);
+        LongBitmapSubsetIterator subsetIterator = new 
LongBitmapSubsetIterator(bitmap);
+        HashSet<Long> subsets = new HashSet<>();
+        for (long subset : subsetIterator) {
+            Assertions.assertTrue(LongBitmap.isSubset(subset, bitmap));
+            subsets.add(subset);
+        }
+        Assertions.assertEquals(subsets.size(), Math.pow(2, ints.length) - 1);
+        subsetIterator.reset();
+        subsets.clear();
+        for (long subset : subsetIterator) {
+            Assertions.assertTrue(LongBitmap.isSubset(subset, bitmap));
+            subsets.add(subset);
+        }
+        Assertions.assertEquals(subsets.size(), Math.pow(2, ints.length) - 1);
+    }
+
+    @Test
+    void iteratorTest() {
+        int[] ints = {1, 3, 6, 12, 43};
+        long bitmap = LongBitmap.newBitmap(ints);
+        int index = 0;
+        for (int v : LongBitmap.getIterator(bitmap)) {
+            Assertions.assertEquals(ints[index], v);
+            index += 1;
+        }
+        index = 0;
+        for (int v : LongBitmap.getReverseIterator(bitmap)) {
+            Assertions.assertEquals(ints[ints.length - 1 - index], v);
+            index += 1;
+        }
+    }
+}
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifierTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifierTest.java
index 817d0d36ba..3b616a7569 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifierTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/GraphSimplifierTest.java
@@ -22,7 +22,6 @@ import org.apache.doris.nereids.trees.plans.JoinType;
 import org.apache.doris.nereids.util.HyperGraphBuilder;
 
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 public class GraphSimplifierTest {
@@ -163,7 +162,6 @@ public class GraphSimplifierTest {
                 totalTime / times));
     }
 
-    @Disabled
     @Test
     void testComplexQuery() {
         HyperGraph hyperGraph = new HyperGraphBuilder()
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumeratorTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumeratorTest.java
index 4dabec273b..6e559efbbe 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumeratorTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/jobs/joinorder/hypergraph/SubgraphEnumeratorTest.java
@@ -17,8 +17,8 @@
 
 package org.apache.doris.nereids.jobs.joinorder.hypergraph;
 
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
-import 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.SubsetIterator;
+import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmap;
+import 
org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.LongBitmapSubsetIterator;
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.receiver.Counter;
 import org.apache.doris.nereids.trees.plans.JoinType;
 import org.apache.doris.nereids.util.HyperGraphBuilder;
@@ -26,7 +26,6 @@ import org.apache.doris.nereids.util.HyperGraphBuilder;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-import java.util.BitSet;
 import java.util.HashMap;
 import java.util.HashSet;
 
@@ -48,9 +47,8 @@ public class SubgraphEnumeratorTest {
         Counter counter = new Counter();
         SubgraphEnumerator subgraphEnumerator = new 
SubgraphEnumerator(counter, hyperGraph);
         subgraphEnumerator.enumerate();
-        BitSet fullSet = new BitSet();
-        fullSet.set(0, 5);
-        HashMap<BitSet, Integer> cache = new HashMap<>();
+        long fullSet = LongBitmap.newBitmapBetween(0, 5);
+        HashMap<Long, Integer> cache = new HashMap<>();
         countAndCheck(fullSet, hyperGraph, counter.getAllCount(), cache);
     }
 
@@ -69,12 +67,11 @@ public class SubgraphEnumeratorTest {
                 .addEdge(JoinType.INNER_JOIN, 1, 2)
                 .addEdge(JoinType.INNER_JOIN, 2, 3)
                 .build();
-        BitSet fullSet = new BitSet();
-        fullSet.set(0, 4);
+        long fullSet = LongBitmap.newBitmapBetween(0, 4);
         Counter counter = new Counter();
         SubgraphEnumerator subgraphEnumerator = new 
SubgraphEnumerator(counter, hyperGraph);
         subgraphEnumerator.enumerate();
-        HashMap<BitSet, Integer> cache = new HashMap<>();
+        HashMap<Long, Integer> cache = new HashMap<>();
         countAndCheck(fullSet, hyperGraph, counter.getAllCount(), cache);
     }
 
@@ -82,14 +79,13 @@ public class SubgraphEnumeratorTest {
     void testRandomQuery() {
         int tableNum = 10;
         int edgeNum = 40;
-        BitSet fullSet = new BitSet();
-        fullSet.set(0, tableNum);
+        long fullSet = LongBitmap.newBitmapBetween(0, tableNum);
         for (int i = 0; i < 10; i++) {
             HyperGraph hyperGraph = new 
HyperGraphBuilder().randomBuildWith(tableNum, edgeNum);
             Counter counter = new Counter();
             SubgraphEnumerator subgraphEnumerator = new 
SubgraphEnumerator(counter, hyperGraph);
             subgraphEnumerator.enumerate();
-            HashMap<BitSet, Integer> cache = new HashMap<>();
+            HashMap<Long, Integer> cache = new HashMap<>();
             countAndCheck(fullSet, hyperGraph, counter.getAllCount(), cache);
         }
     }
@@ -109,34 +105,33 @@ public class SubgraphEnumeratorTest {
                 String.format("enumerate %d tables %d edges cost %f ms", 
tableNum, edgeNum, endTime - startTime));
     }
 
-    private int countAndCheck(BitSet bitSet, HyperGraph hyperGraph, 
HashMap<BitSet, Integer> counter,
-            HashMap<BitSet, Integer> cache) {
-        if (cache.containsKey(bitSet)) {
-            return cache.get(bitSet);
+    private int countAndCheck(long bitmap, HyperGraph hyperGraph, 
HashMap<Long, Integer> counter,
+            HashMap<Long, Integer> cache) {
+        if (cache.containsKey(bitmap)) {
+            return cache.get(bitmap);
         }
-        if (bitSet.cardinality() == 1) {
-            Assertions.assertEquals(counter.get(bitSet), 1,
-                    String.format("The csg-cmp pairs of %s should be %d rather 
than %s", bitSet, 1,
-                            counter.get(bitSet)));
-            cache.put(bitSet, 1);
+        if (LongBitmap.getCardinality(bitmap) == 1) {
+            Assertions.assertEquals(counter.get(bitmap), 1,
+                    String.format("The csg-cmp pairs of %s should be %d rather 
than %s", bitmap, 1,
+                            counter.get(bitmap)));
+            cache.put(bitmap, 1);
             return 1;
         }
-        SubsetIterator subsetIterator = new SubsetIterator(bitSet);
+        LongBitmapSubsetIterator subsetIterator = new 
LongBitmapSubsetIterator(bitmap);
         int count = 0;
-        HashSet<BitSet> visited = new HashSet<>();
-        for (BitSet subset : subsetIterator) {
-            BitSet left = subset;
-            BitSet right = new BitSet();
-            right.or(bitSet);
-            right.andNot(left);
+        HashSet<Long> visited = new HashSet<>();
+        for (long subset : subsetIterator) {
+            long left = subset;
+            long right = LongBitmap.clone(bitmap);
+            right = LongBitmap.andNot(right, left);
             if (visited.contains(left) || visited.contains(right)) {
                 continue;
             }
             visited.add(left);
             visited.add(right);
             for (Edge edge : hyperGraph.getEdges()) {
-                if ((Bitmap.isSubset(edge.getLeft(), left) && 
Bitmap.isSubset(edge.getRight(), right)) || (
-                        Bitmap.isSubset(edge.getLeft(), right) && 
Bitmap.isSubset(edge.getRight(), left))) {
+                if ((LongBitmap.isSubset(edge.getLeft(), left) && 
LongBitmap.isSubset(edge.getRight(), right)) || (
+                        LongBitmap.isSubset(edge.getLeft(), right) && 
LongBitmap.isSubset(edge.getRight(), left))) {
                     count += countAndCheck(left, hyperGraph, counter, cache) * 
countAndCheck(right, hyperGraph,
                             counter, cache);
                     break;
@@ -144,14 +139,14 @@ public class SubgraphEnumeratorTest {
             }
         }
         if (count == 0) {
-            Assertions.assertEquals(counter.get(bitSet), null,
-                    String.format("The plan %s should be invalid", bitSet));
+            Assertions.assertEquals(counter.get(bitmap), null,
+                    String.format("The plan %s should be invalid", bitmap));
         } else {
-            Assertions.assertEquals(counter.get(bitSet), count,
-                    String.format("The csg-cmp pairs of %s should be %d rather 
than %d", bitSet, count,
-                            counter.get(bitSet)));
+            Assertions.assertEquals(counter.get(bitmap), count,
+                    String.format("The csg-cmp pairs of %s should be %d rather 
than %d", bitmap, count,
+                            counter.get(bitmap)));
         }
-        cache.put(bitSet, count);
+        cache.put(bitmap, count);
         return count;
     }
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/HyperGraphBuilder.java 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/HyperGraphBuilder.java
index 50d3b640f2..7a107880b9 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/HyperGraphBuilder.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/HyperGraphBuilder.java
@@ -23,7 +23,6 @@ import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.jobs.cascades.DeriveStatsJob;
 import org.apache.doris.nereids.jobs.joinorder.JoinOrderJob;
 import org.apache.doris.nereids.jobs.joinorder.hypergraph.HyperGraph;
-import org.apache.doris.nereids.jobs.joinorder.hypergraph.bitmap.Bitmap;
 import org.apache.doris.nereids.memo.Group;
 import org.apache.doris.nereids.trees.expressions.EqualTo;
 import org.apache.doris.nereids.trees.expressions.Expression;
@@ -118,9 +117,13 @@ public class HyperGraphBuilder {
         Preconditions.checkArgument(node2 >= 0 && node1 < rowCounts.size(),
                 String.format("%d must in [%d, %d)", node1, 0, 
rowCounts.size()));
 
-        BitSet leftBitmap = Bitmap.newBitmap(node1);
-        BitSet rightBitmap = Bitmap.newBitmap(node2);
-        BitSet fullBitmap = Bitmap.newBitmapUnion(leftBitmap, rightBitmap);
+        BitSet leftBitmap = new BitSet();
+        leftBitmap.set(node1);
+        BitSet rightBitmap = new BitSet();
+        rightBitmap.set(node2);
+        BitSet fullBitmap = new BitSet();
+        fullBitmap.or(leftBitmap);
+        fullBitmap.or(rightBitmap);
         Optional<BitSet> fullKey = findPlan(fullBitmap);
         if (!fullKey.isPresent()) {
             Optional<BitSet> leftKey = findPlan(leftBitmap);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to