You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2021/12/17 08:53:28 UTC

[ignite-3] branch main updated: IGNITE-15870 Calcite. Replace usages of Lists and Sets of int to IntList\IntSet (#498)

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

amashenkov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 53bd8bf  IGNITE-15870 Calcite. Replace usages of Lists and Sets of int to IntList\IntSet (#498)
53bd8bf is described below

commit 53bd8bf90eb757c14f68a3ff5227bd29cd0e491b
Author: Berkof <sa...@mail.ru>
AuthorDate: Fri Dec 17 15:53:22 2021 +0700

    IGNITE-15870 Calcite. Replace usages of Lists and Sets of int to IntList\IntSet (#498)
---
 .../query/calcite/externalize/RelJson.java         |  5 ++-
 .../query/calcite/metadata/IgniteMdCollation.java  |  4 +-
 .../query/calcite/prepare/PlannerHelper.java       |  6 ++-
 .../rel/IgniteCorrelatedNestedLoopJoin.java        |  6 +--
 .../query/calcite/rel/IgniteProject.java           |  9 ++--
 .../calcite/rel/agg/IgniteSortAggregateBase.java   |  3 +-
 .../FilterSpoolMergeToSortedIndexSpoolRule.java    |  3 +-
 .../query/calcite/trait/IgniteDistributions.java   |  4 +-
 .../processors/query/calcite/trait/TraitUtils.java |  5 ++-
 .../processors/query/calcite/util/Commons.java     | 14 +++++--
 .../query/calcite/util/IndexConditions.java        | 14 +++----
 .../processors/query/calcite/util/RexUtils.java    | 10 +++--
 .../query/calcite/exec/rel/BaseAggregateTest.java  |  8 ++--
 .../ignite/internal/util/CollectionUtils.java      | 13 ++++++
 .../ignite/internal/util/CollectionUtilsTest.java  | 48 ++++++++++++++++++++++
 15 files changed, 114 insertions(+), 38 deletions(-)

diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJson.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJson.java
index f32666e..13698d9 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJson.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/externalize/RelJson.java
@@ -98,6 +98,7 @@ import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.validate.SqlNameMatchers;
 import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.ImmutableIntList;
 import org.apache.calcite.util.Util;
 import org.apache.ignite.internal.processors.query.calcite.rel.InternalIgniteRel;
 import org.apache.ignite.internal.processors.query.calcite.trait.DistributionFunction;
@@ -588,11 +589,11 @@ class RelJson {
         Map<String, Object> map = (Map<String, Object>) distribution;
         Number cacheId = (Number) map.get("cacheId");
         if (cacheId != null) {
-            return IgniteDistributions.hash((List<Integer>) map.get("keys"),
+            return IgniteDistributions.hash(ImmutableIntList.copyOf((List<Integer>) map.get("keys")),
                     DistributionFunction.affinity(cacheId.intValue(), cacheId));
         }
 
-        return IgniteDistributions.hash((List<Integer>) map.get("keys"), DistributionFunction.hash());
+        return IgniteDistributions.hash(ImmutableIntList.copyOf((List<Integer>) map.get("keys")), DistributionFunction.hash());
     }
 
     RelDataType toType(RelDataTypeFactory typeFactory, Object o) {
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdCollation.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdCollation.java
index bbb7d50..394eafa 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdCollation.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdCollation.java
@@ -22,10 +22,10 @@ import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 import com.google.common.collect.ImmutableList;
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
@@ -318,7 +318,7 @@ public class IgniteMdCollation implements MetadataHandler<BuiltInMetadata.Collat
             if (project.e instanceof RexInputRef) {
                 targets.compute(((RexSlot) project.e).getIndex(), (k, v) -> {
                             if (v == null) {
-                                return new ArrayList<>(Collections.singleton(project.i));
+                                return IntArrayList.of(project.i);
                             } else {
                                 v.add(project.i);
 
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java
index 4db76c2..922783b 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerHelper.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.query.calcite.prepare;
 
+import it.unimi.dsi.fastutil.ints.IntSet;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -44,6 +45,7 @@ import org.apache.ignite.internal.processors.query.calcite.schema.InternalIgnite
 import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
 import org.apache.ignite.internal.processors.query.calcite.util.Commons;
 import org.apache.ignite.internal.processors.query.calcite.util.HintUtils;
+import org.apache.ignite.internal.util.CollectionUtils;
 import org.apache.ignite.lang.IgniteLogger;
 
 /**
@@ -226,12 +228,12 @@ public class PlannerHelper {
                 return (IgniteRel) scan;
             }
 
-            Set<Integer> indexedCols = Set.copyOf(
+            IntSet indexedCols = CollectionUtils.setOf(
                     tbl.getIndex(((AbstractIndexScan) scan).indexName()).collation().getKeys());
 
             spoolNeeded = modifyNode.getUpdateColumnList().stream()
                     .map(tbl.descriptor()::columnDescriptor)
-                    .map(ColumnDescriptor::fieldIndex)
+                    .mapToInt(ColumnDescriptor::fieldIndex)
                     .anyMatch(indexedCols::contains);
 
             return (IgniteRel) scan;
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteCorrelatedNestedLoopJoin.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteCorrelatedNestedLoopJoin.java
index 641bd2c..329f300 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteCorrelatedNestedLoopJoin.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteCorrelatedNestedLoopJoin.java
@@ -18,8 +18,8 @@
 package org.apache.ignite.internal.processors.query.calcite.rel;
 
 import static org.apache.ignite.internal.processors.query.calcite.util.Commons.maxPrefix;
-import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 
+import it.unimi.dsi.fastutil.ints.IntList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -107,9 +107,9 @@ public class IgniteCorrelatedNestedLoopJoin extends AbstractIgniteJoin {
         RelCollation leftCollation = TraitUtils.collation(left);
         RelCollation rightCollation = TraitUtils.collation(right);
 
-        List<Integer> newRightCollationFields = maxPrefix(rightCollation.getKeys(), joinInfo.leftKeys);
+        IntList newRightCollationFields = maxPrefix(rightCollation.getKeys(), joinInfo.leftKeys);
 
-        if (nullOrEmpty(newRightCollationFields)) {
+        if (newRightCollationFields.isEmpty()) {
             return List.of(Pair.of(nodeTraits.replace(RelCollations.EMPTY), inputTraits));
         }
 
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteProject.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteProject.java
index c7664ae..1a6ff77 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteProject.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteProject.java
@@ -23,6 +23,7 @@ import static org.apache.ignite.internal.processors.query.calcite.trait.IgniteDi
 import static org.apache.ignite.internal.processors.query.calcite.trait.TraitUtils.changeTraits;
 
 import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -110,9 +111,11 @@ public class IgniteProject extends Project implements TraitsAwareIgniteRel {
                 input.getRowType().getFieldCount(), getProjects());
 
         ImmutableIntList keys = distribution.getKeys();
-        List<Integer> srcKeys = new ArrayList<>(keys.size());
+        IntArrayList srcKeys = new IntArrayList(keys.size());
 
-        for (int key : keys) {
+        int key;
+        for (int i = 0; i < keys.size(); i++) {
+            key = keys.getInt(i);
             int src = mapping.getSourceOpt(key);
 
             if (src == -1) {
@@ -123,7 +126,7 @@ public class IgniteProject extends Project implements TraitsAwareIgniteRel {
         }
 
         if (srcKeys.size() == keys.size()) {
-            return Pair.of(nodeTraits, List.of(in.replace(hash(srcKeys, distribution.function()))));
+            return Pair.of(nodeTraits, List.of(in.replace(hash(ImmutableIntList.of(srcKeys.elements()), distribution.function()))));
         }
 
         return Pair.of(nodeTraits.replace(single()), List.of(in.replace(single())));
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/agg/IgniteSortAggregateBase.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/agg/IgniteSortAggregateBase.java
index 53c9ffb..798ac47 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/agg/IgniteSortAggregateBase.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/agg/IgniteSortAggregateBase.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.query.calcite.rel.agg;
 
 import static org.apache.ignite.internal.processors.query.calcite.util.Commons.maxPrefix;
 
+import it.unimi.dsi.fastutil.ints.IntList;
 import java.util.List;
 import org.apache.calcite.plan.RelTraitSet;
 import org.apache.calcite.rel.RelCollation;
@@ -59,7 +60,7 @@ interface IgniteSortAggregateBase extends TraitsAwareIgniteRel {
     ) {
         RelCollation inputCollation = TraitUtils.collation(inputTraits.get(0));
 
-        List<Integer> newCollation = maxPrefix(inputCollation.getKeys(), getGroupSet().asSet());
+        IntList newCollation = maxPrefix(inputCollation.getKeys(), getGroupSet().asSet());
 
         if (newCollation.size() < getGroupSet().cardinality()) {
             return List.of();
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterSpoolMergeToSortedIndexSpoolRule.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterSpoolMergeToSortedIndexSpoolRule.java
index 8f6ab4a..eff2e0f 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterSpoolMergeToSortedIndexSpoolRule.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/FilterSpoolMergeToSortedIndexSpoolRule.java
@@ -19,7 +19,6 @@ package org.apache.ignite.internal.processors.query.calcite.rule;
 
 import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 
-import java.util.List;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
@@ -78,7 +77,7 @@ public class FilterSpoolMergeToSortedIndexSpoolRule extends RelRule<FilterSpoolM
             return;
         }
 
-        RelCollation collation = TraitUtils.createCollation(List.copyOf(idxCond.keys()));
+        RelCollation collation = TraitUtils.createCollation(idxCond.keys());
 
         RelNode res = new IgniteSortedIndexSpool(
                 cluster,
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/IgniteDistributions.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/IgniteDistributions.java
index 3dad001..eb022e7 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/IgniteDistributions.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/IgniteDistributions.java
@@ -121,8 +121,8 @@ public class IgniteDistributions {
      * @param function Specific hash function.
      * @return Hash distribution.
      */
-    public static IgniteDistribution hash(List<Integer> keys, DistributionFunction function) {
-        return canonize(new DistributionTrait(ImmutableIntList.copyOf(keys), function));
+    public static IgniteDistribution hash(ImmutableIntList keys, DistributionFunction function) {
+        return canonize(new DistributionTrait(keys, function));
     }
 
     /**
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/TraitUtils.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/TraitUtils.java
index c53da16..d1983cd 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/TraitUtils.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/trait/TraitUtils.java
@@ -29,6 +29,7 @@ import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 
 import com.google.common.collect.ImmutableList;
 import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntSet;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -575,9 +576,9 @@ public class TraitUtils {
      * @param keys The keys to create collation from.
      * @return New collation.
      */
-    public static RelCollation createCollation(List<Integer> keys) {
+    public static RelCollation createCollation(IntSet keys) {
         return RelCollations.of(
-                keys.stream().map(RelFieldCollation::new).collect(Collectors.toList())
+                keys.intStream().mapToObj(RelFieldCollation::new).collect(Collectors.toList())
         );
     }
 
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/Commons.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/Commons.java
index 01be38e..b5f7f0d 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/Commons.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/Commons.java
@@ -20,6 +20,9 @@ package org.apache.ignite.internal.processors.query.calcite.util;
 import static org.apache.ignite.internal.processors.query.calcite.util.BaseQueryContext.CLUSTER;
 import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
 import java.io.Reader;
 import java.io.StringReader;
 import java.math.BigDecimal;
@@ -598,12 +601,14 @@ public final class Commons {
      * @param elems Elems.
      * @return The longest possible prefix of {@code seq}.
      */
-    public static <T> List<T> maxPrefix(List<T> seq, Collection<T> elems) {
-        List<T> res = new ArrayList<>();
+    public static IntList maxPrefix(ImmutableIntList seq, Collection<Integer> elems) {
+        IntList res = new IntArrayList();
 
-        Set<T> elems0 = new HashSet<>(elems);
+        IntOpenHashSet elems0 = new IntOpenHashSet(elems);
 
-        for (T e : seq) {
+        int e;
+        for (int i = 0; i < seq.size(); i++) {
+            e = seq.getInt(i);
             if (!elems0.remove(e)) {
                 break;
             }
@@ -614,6 +619,7 @@ public final class Commons {
         return res;
     }
 
+
     /**
      * Quietly closes given object ignoring possible checked exception.
      *
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IndexConditions.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IndexConditions.java
index f10a9c1..a567d78 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IndexConditions.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IndexConditions.java
@@ -19,10 +19,10 @@ package org.apache.ignite.internal.processors.query.calcite.util;
 
 import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 
-import java.util.Collections;
-import java.util.HashSet;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
+import it.unimi.dsi.fastutil.ints.IntSets;
 import java.util.List;
-import java.util.Set;
 import org.apache.calcite.rel.RelInput;
 import org.apache.calcite.rel.RelWriter;
 import org.apache.calcite.rex.RexNode;
@@ -107,12 +107,12 @@ public class IndexConditions {
      * Keys.
      * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
      */
-    public Set<Integer> keys() {
+    public IntSet keys() {
         if (upperBound == null && lowerBound == null) {
-            return Collections.emptySet();
+            return IntSets.EMPTY_SET;
         }
 
-        Set<Integer> keys = new HashSet<>();
+        IntSet keys = new IntOpenHashSet();
 
         int cols = lowerBound != null ? lowerBound.size() : upperBound.size();
 
@@ -123,7 +123,7 @@ public class IndexConditions {
             }
         }
 
-        return Collections.unmodifiableSet(keys);
+        return IntSets.unmodifiable(keys);
     }
 
     /**
diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/RexUtils.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/RexUtils.java
index 8aa4c14..f9995f7 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/RexUtils.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/RexUtils.java
@@ -25,6 +25,9 @@ import static org.apache.calcite.sql.SqlKind.LESS_THAN_OR_EQUAL;
 import static org.apache.ignite.internal.util.CollectionUtils.nullOrEmpty;
 
 import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
+import it.unimi.dsi.fastutil.ints.IntSets;
 import it.unimi.dsi.fastutil.objects.ObjectIterator;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -626,17 +629,16 @@ public class RexUtils {
         return cors;
     }
 
-
     /**
      * NotNullKeys.
      * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
      */
-    public static Set<Integer> notNullKeys(List<RexNode> row) {
+    public static IntSet notNullKeys(List<RexNode> row) {
         if (nullOrEmpty(row)) {
-            return Collections.emptySet();
+            return IntSets.EMPTY_SET;
         }
 
-        Set<Integer> keys = new HashSet<>();
+        IntSet keys = new IntOpenHashSet();
 
         for (int i = 0; i < row.size(); ++i) {
             if (isNotNull(row.get(i))) {
diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/BaseAggregateTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/BaseAggregateTest.java
index 24e26dc..291e79f 100644
--- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/BaseAggregateTest.java
+++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/BaseAggregateTest.java
@@ -24,11 +24,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Set;
 import java.util.function.Supplier;
-import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import org.apache.calcite.rel.RelCollations;
 import org.apache.calcite.rel.core.AggregateCall;
@@ -490,12 +490,12 @@ public abstract class BaseAggregateTest extends AbstractExecutionTest {
                 RootNode<Object[]> root = new RootNode<>(ctx, aggRowType);
                 root.register(aggChain);
 
-                Set<Integer> grpId = IntStream.range(0, grps).boxed().collect(Collectors.toSet());
+                IntSet grpId = new IntOpenHashSet(IntStream.range(0, grps).toArray());
 
                 while (root.hasNext()) {
                     Object[] row = root.next();
 
-                    grpId.remove(row[0]);
+                    grpId.remove(((Integer) row[0]).intValue());
 
                     assertEquals((rowsInGroup - 1) * rowsInGroup / 2, row[1]);
                 }
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/CollectionUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/CollectionUtils.java
index ef81650..335d34c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/CollectionUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/CollectionUtils.java
@@ -23,6 +23,9 @@ import static java.util.Collections.emptyList;
 import static java.util.Collections.unmodifiableCollection;
 import static java.util.Collections.unmodifiableSet;
 
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
+import it.unimi.dsi.fastutil.ints.IntSets;
 import java.util.AbstractCollection;
 import java.util.Collection;
 import java.util.Collections;
@@ -285,4 +288,14 @@ public final class CollectionUtils {
     private CollectionUtils() {
         // No op.
     }
+
+    /**
+     * Get unmodifiable copy set of specified collection.
+     *
+     * @param coll Collection of integer to copy.
+     * @return Unmodifiable copy set.
+     */
+    public static IntSet setOf(Collection<Integer> coll) {
+        return IntSets.unmodifiable(new IntOpenHashSet(coll));
+    }
 }
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/CollectionUtilsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/CollectionUtilsTest.java
index 95a30ea..246a3f1 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/util/CollectionUtilsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/util/CollectionUtilsTest.java
@@ -21,13 +21,18 @@ import static java.util.function.Function.identity;
 import static java.util.stream.Collectors.toList;
 import static org.apache.ignite.internal.util.CollectionUtils.concat;
 import static org.apache.ignite.internal.util.CollectionUtils.difference;
+import static org.apache.ignite.internal.util.CollectionUtils.setOf;
 import static org.apache.ignite.internal.util.CollectionUtils.union;
 import static org.apache.ignite.internal.util.CollectionUtils.viewReadOnly;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.StreamSupport;
@@ -125,4 +130,47 @@ public class CollectionUtilsTest {
     private <T> List<? extends T> collect(Iterable<? extends T> iterable) {
         return StreamSupport.stream(iterable.spliterator(), false).collect(toList());
     }
+
+    /**
+     * Test setOf by populated and empty list.
+     */
+    @Test
+    void testSetOfList() {
+        List<Integer> list = Arrays.asList(1, 2, 3, 234, 3);
+
+        testSetOf(list);
+
+        testSetOf(Collections.emptyList());
+    }
+
+    /**
+     * Test setOf by populated and empty sets.
+     */
+    @Test
+    void testSetOfSet() {
+        Set<Integer> set = new HashSet<>();
+        set.add(1);
+        set.add(2);
+        set.add(3);
+        set.add(234);
+
+        testSetOf(set);
+
+        testSetOf(Collections.emptySet());
+    }
+
+    private void testSetOf(Collection<Integer> data) {
+        Set<Integer> copy = setOf(data);
+
+        assertNotNull(copy);
+
+        for (Integer i : data) {
+            assertTrue(copy.contains(i));
+        }
+
+        assertEquals(new HashSet<>(data).size(), copy.size());
+
+        assertThrows(UnsupportedOperationException.class, () -> copy.add(42));
+        assertThrows(UnsupportedOperationException.class, () -> copy.remove(3));
+    }
 }