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

ibessonov 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 cf946e9f94 IGNITE-20398 Filter null values for any cfg (#2580)
cf946e9f94 is described below

commit cf946e9f9475be1aba308a9a6b7b2c36a489b48d
Author: Mikhail <pochat...@users.noreply.github.com>
AuthorDate: Wed Sep 13 15:35:59 2023 +0300

    IGNITE-20398 Filter null values for any cfg (#2580)
---
 .../processor/ConfigurationProcessor.java          |   3 +-
 .../configuration/ConfigurationTreeGenerator.java  |  10 +-
 .../ConfigurationNotificationUtils.java            |  42 ++++-
 .../notifications/ConfigurationNotifier.java       |  44 ++---
 .../configuration/util/ConfigurationUtil.java      | 138 +++++++++++++++-
 .../configuration/util/ConfigurationUtilTest.java  | 106 ++++++++++++
 .../ignite/internal/util/CollectionUtils.java      | 184 +++------------------
 .../ignite/internal/util/CollectionUtilsTest.java  |  88 +---------
 .../persistence/compaction/Compactor.java          |   2 +-
 .../persistence/store/FilePageStoreManager.java    |   5 +-
 .../persistence/store/GroupPageStoresMap.java      |   7 +-
 .../store/FilePageStoreManagerTest.java            |   8 +-
 .../persistence/store/GroupPageStoresMapTest.java  |   9 +-
 13 files changed, 338 insertions(+), 308 deletions(-)

diff --git 
a/modules/configuration-annotation-processor/src/main/java/org/apache/ignite/internal/configuration/processor/ConfigurationProcessor.java
 
b/modules/configuration-annotation-processor/src/main/java/org/apache/ignite/internal/configuration/processor/ConfigurationProcessor.java
index bc86798d14..e399bcaad4 100644
--- 
a/modules/configuration-annotation-processor/src/main/java/org/apache/ignite/internal/configuration/processor/ConfigurationProcessor.java
+++ 
b/modules/configuration-annotation-processor/src/main/java/org/apache/ignite/internal/configuration/processor/ConfigurationProcessor.java
@@ -33,7 +33,6 @@ import static 
org.apache.ignite.internal.configuration.processor.ConfigurationPr
 import static org.apache.ignite.internal.util.ArrayUtils.nullOrEmpty;
 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.viewReadOnly;
 
 import com.google.auto.service.AutoService;
 import com.squareup.javapoet.ClassName;
@@ -760,7 +759,7 @@ public class ConfigurationProcessor extends 
AbstractProcessor {
     /** {@inheritDoc} */
     @Override
     public Set<String> getSupportedAnnotationTypes() {
-        return Set.copyOf(viewReadOnly(supportedAnnotationTypes(), 
Class::getCanonicalName));
+        return 
supportedAnnotationTypes().stream().map(Class::getCanonicalName).collect(toSet());
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationTreeGenerator.java
 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationTreeGenerator.java
index 74784db651..b8447ff8e6 100644
--- 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationTreeGenerator.java
+++ 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationTreeGenerator.java
@@ -24,12 +24,12 @@ import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toMap;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.collectSchemas;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.isPolymorphicId;
+import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.mapIterable;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.polymorphicInstanceId;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.polymorphicSchemaExtensions;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.schemaExtensions;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.schemaFields;
 import static org.apache.ignite.internal.util.CollectionUtils.difference;
-import static org.apache.ignite.internal.util.CollectionUtils.viewReadOnly;
 
 import java.lang.reflect.Field;
 import java.util.Collection;
@@ -161,12 +161,14 @@ public class ConfigurationTreeGenerator implements 
ManuallyCloseable {
      * @param polymorphicSchemaExtensions polymorphic schema extensions
      * @return set of all schema classes
      */
-    private static Set<Class<?>> collectAllSchemas(Collection<RootKey<?, ?>> 
rootKeys,
+    private static Set<Class<?>> collectAllSchemas(
+            Collection<RootKey<?, ?>> rootKeys,
             Collection<Class<?>> internalSchemaExtensions,
-            Collection<Class<?>> polymorphicSchemaExtensions) {
+            Collection<Class<?>> polymorphicSchemaExtensions
+    ) {
         Set<Class<?>> allSchemas = new HashSet<>();
 
-        allSchemas.addAll(collectSchemas(viewReadOnly(rootKeys, 
RootKey::schemaClass)));
+        allSchemas.addAll(collectSchemas(mapIterable(rootKeys, 
RootKey::schemaClass)));
         allSchemas.addAll(collectSchemas(internalSchemaExtensions));
         allSchemas.addAll(collectSchemas(polymorphicSchemaExtensions));
 
diff --git 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/notifications/ConfigurationNotificationUtils.java
 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/notifications/ConfigurationNotificationUtils.java
index b47d09bb0c..9faf5bfa60 100644
--- 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/notifications/ConfigurationNotificationUtils.java
+++ 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/notifications/ConfigurationNotificationUtils.java
@@ -20,11 +20,8 @@ package 
org.apache.ignite.internal.configuration.notifications;
 import static java.util.Collections.emptyIterator;
 
 import java.io.Serializable;
-import java.util.Collection;
 import java.util.Iterator;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+import java.util.NoSuchElementException;
 import org.apache.ignite.configuration.notifications.ConfigurationListener;
 import 
org.apache.ignite.configuration.notifications.ConfigurationNamedListListener;
 import org.apache.ignite.internal.configuration.ConfigurationNode;
@@ -121,12 +118,39 @@ class ConfigurationNotificationUtils {
      * @param anyConfig  New {@link NamedListConfiguration#any "any"} 
configuration.
      * @return Merged {@link NamedListConfiguration#any "any"} configurations.
      */
-    static Collection<DynamicConfiguration<InnerNode, ?>> mergeAnyConfigs(
-            Collection<DynamicConfiguration<InnerNode, ?>> anyConfigs,
+    static Iterable<DynamicConfiguration<InnerNode, ?>> mergeAnyConfigs(
+            Iterable<DynamicConfiguration<InnerNode, ?>> anyConfigs,
             @Nullable DynamicConfiguration<InnerNode, ?> anyConfig
     ) {
-        return Stream.concat(anyConfigs.stream(), Stream.of(anyConfig))
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList());
+        if (anyConfig == null) {
+            return anyConfigs;
+        }
+
+        return () -> {
+            Iterator<DynamicConfiguration<InnerNode, ?>> innerIterator = 
anyConfigs.iterator();
+
+            return new Iterator<>() {
+                boolean finished = false;
+                @Override
+                public boolean hasNext() {
+                    return innerIterator.hasNext() || !finished;
+                }
+
+                @Override
+                public DynamicConfiguration<InnerNode, ?> next() {
+                    if (finished) {
+                        throw new NoSuchElementException();
+                    }
+
+                    if (innerIterator.hasNext()) {
+                        return innerIterator.next();
+                    }
+
+                    finished = true;
+
+                    return anyConfig;
+                }
+            };
+        };
     }
 }
diff --git 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/notifications/ConfigurationNotifier.java
 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/notifications/ConfigurationNotifier.java
index 0da13024f1..4d58120469 100644
--- 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/notifications/ConfigurationNotifier.java
+++ 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/notifications/ConfigurationNotifier.java
@@ -26,10 +26,10 @@ import static 
org.apache.ignite.internal.configuration.notifications.Configurati
 import static 
org.apache.ignite.internal.configuration.notifications.ConfigurationNotificationUtils.namedDynamicConfig;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.innerNodeVisitor;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.leafNodeVisitor;
+import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.mapIterable;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.namedListNodeVisitor;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.touch;
 import static org.apache.ignite.internal.util.CollectionUtils.concat;
-import static org.apache.ignite.internal.util.CollectionUtils.viewReadOnly;
 
 import java.io.Serializable;
 import java.lang.reflect.Field;
@@ -100,7 +100,7 @@ public class ConfigurationNotifier {
             @Nullable InnerNode oldInnerNode,
             InnerNode newInnerNode,
             DynamicConfiguration<InnerNode, ?> config,
-            Collection<DynamicConfiguration<InnerNode, ?>> anyConfigs,
+            Iterable<DynamicConfiguration<InnerNode, ?>> anyConfigs,
             ConfigurationNotificationContext ctx
     ) {
         assert !(config instanceof NamedListConfiguration);
@@ -111,7 +111,7 @@ public class ConfigurationNotifier {
 
         notifyPublicListeners(
                 listeners(config, ctx.notificationNum),
-                concat(viewReadOnly(anyConfigs, anyCfg -> listeners(anyCfg, 
ctx.notificationNum))),
+                concat(mapIterable(anyConfigs, anyCfg -> listeners(anyCfg, 
ctx.notificationNum))),
                 oldInnerNode.specificNode(),
                 newInnerNode.specificNode(),
                 ctx,
@@ -135,7 +135,7 @@ public class ConfigurationNotifier {
                 if (newLeaf != oldLeaf) {
                     notifyPublicListeners(
                             listeners(dynamicProperty(config, key), 
ctx.notificationNum),
-                            concat(viewReadOnly(anyConfigs, anyCfg -> 
listeners(dynamicProperty(anyCfg, key), ctx.notificationNum))),
+                            concat(mapIterable(anyConfigs, anyCfg -> 
listeners(dynamicProperty(anyCfg, key), ctx.notificationNum))),
                             oldLeaf,
                             newLeaf,
                             ctx,
@@ -159,7 +159,7 @@ public class ConfigurationNotifier {
                         oldNode,
                         newNode,
                         newConfig,
-                        viewReadOnly(anyConfigs, anyCfg -> 
dynamicConfig(anyCfg, key)),
+                        mapIterable(anyConfigs, anyCfg -> 
dynamicConfig(anyCfg, key)),
                         ctx
                 );
 
@@ -177,7 +177,7 @@ public class ConfigurationNotifier {
                 if (newNamedList != oldNamedList) {
                     notifyPublicListeners(
                             listeners(namedDynamicConfig(config, key), 
ctx.notificationNum),
-                            concat(viewReadOnly(anyConfigs, anyCfg -> 
listeners(namedDynamicConfig(anyCfg, key), ctx.notificationNum))),
+                            concat(mapIterable(anyConfigs, anyCfg -> 
listeners(namedDynamicConfig(anyCfg, key), ctx.notificationNum))),
                             oldNamedList,
                             newNamedList,
                             ctx,
@@ -191,7 +191,7 @@ public class ConfigurationNotifier {
                     Map<String, ConfigurationProperty<?>> namedListCfgMembers 
= namedListCfg.touchMembers();
 
                     // Lazy initialization.
-                    Collection<DynamicConfiguration<InnerNode, ?>> 
newAnyConfigs = null;
+                    Iterable<DynamicConfiguration<InnerNode, ?>> newAnyConfigs 
= null;
 
                     for (String name : namedListChanges.created) {
                         DynamicConfiguration<InnerNode, ?> newNodeCfg =
@@ -205,7 +205,7 @@ public class ConfigurationNotifier {
 
                         notifyPublicListeners(
                                 extendedListeners(namedDynamicConfig(config, 
key), ctx.notificationNum),
-                                concat(viewReadOnly(
+                                concat(mapIterable(
                                         anyConfigs,
                                         anyCfg -> 
extendedListeners(namedDynamicConfig(anyCfg, key), ctx.notificationNum)
                                 )),
@@ -217,7 +217,7 @@ public class ConfigurationNotifier {
 
                         if (newAnyConfigs == null) {
                             newAnyConfigs = mergeAnyConfigs(
-                                    viewReadOnly(anyConfigs, anyCfg -> 
any(namedDynamicConfig(anyCfg, key))),
+                                    mapIterable(anyConfigs, anyCfg -> 
any(namedDynamicConfig(anyCfg, key))),
                                     any(namedListCfg)
                             );
                         }
@@ -242,7 +242,7 @@ public class ConfigurationNotifier {
 
                         notifyPublicListeners(
                                 extendedListeners(namedDynamicConfig(config, 
key), ctx.notificationNum),
-                                concat(viewReadOnly(
+                                concat(mapIterable(
                                         anyConfigs,
                                         anyCfg -> 
extendedListeners(namedDynamicConfig(anyCfg, key), ctx.notificationNum)
                                 )),
@@ -256,7 +256,7 @@ public class ConfigurationNotifier {
 
                         notifyPublicListeners(
                                 listeners(delNodeCfg, ctx.notificationNum),
-                                concat(viewReadOnly(
+                                concat(mapIterable(
                                         anyConfigs,
                                         anyCfg -> 
listeners(any(namedDynamicConfig(anyCfg, key)), ctx.notificationNum)
                                 )),
@@ -277,7 +277,7 @@ public class ConfigurationNotifier {
 
                         notifyPublicListeners(
                                 extendedListeners(namedDynamicConfig(config, 
key), ctx.notificationNum),
-                                concat(viewReadOnly(
+                                concat(mapIterable(
                                         anyConfigs,
                                         anyCfg -> 
extendedListeners(namedDynamicConfig(anyCfg, key), ctx.notificationNum)
                                 )),
@@ -305,7 +305,7 @@ public class ConfigurationNotifier {
 
                         notifyPublicListeners(
                                 extendedListeners(namedDynamicConfig(config, 
key), ctx.notificationNum),
-                                concat(viewReadOnly(
+                                concat(mapIterable(
                                         anyConfigs,
                                         anyCfg -> 
extendedListeners(namedDynamicConfig(anyCfg, key), ctx.notificationNum)
                                 )),
@@ -317,7 +317,7 @@ public class ConfigurationNotifier {
 
                         if (newAnyConfigs == null) {
                             newAnyConfigs = mergeAnyConfigs(
-                                    viewReadOnly(anyConfigs, anyCfg -> 
any(namedDynamicConfig(anyCfg, key))),
+                                    mapIterable(anyConfigs, anyCfg -> 
any(namedDynamicConfig(anyCfg, key))),
                                     any(namedListCfg)
                             );
                         }
@@ -349,14 +349,14 @@ public class ConfigurationNotifier {
     private static void notifyListeners(
             InnerNode innerNode,
             DynamicConfiguration<InnerNode, ?> config,
-            Collection<DynamicConfiguration<InnerNode, ?>> anyConfigs,
+            Iterable<DynamicConfiguration<InnerNode, ?>> anyConfigs,
             ConfigurationNotificationContext ctx
     ) {
         assert !(config instanceof NamedListConfiguration);
 
         notifyPublicListeners(
                 listeners(config, ctx.notificationNum),
-                concat(viewReadOnly(anyConfigs, anyCfg -> listeners(anyCfg, 
ctx.notificationNum))),
+                concat(mapIterable(anyConfigs, anyCfg -> listeners(anyCfg, 
ctx.notificationNum))),
                 null,
                 innerNode.specificNode(),
                 ctx,
@@ -369,7 +369,7 @@ public class ConfigurationNotifier {
             public Void visitLeafNode(Field field, String key, Serializable 
leaf) {
                 notifyPublicListeners(
                         listeners(dynamicProperty(config, key), 
ctx.notificationNum),
-                        concat(viewReadOnly(
+                        concat(mapIterable(
                                 anyConfigs,
                                 anyCfg -> listeners(dynamicProperty(anyCfg, 
key), ctx.notificationNum)
                         )),
@@ -392,7 +392,7 @@ public class ConfigurationNotifier {
                 notifyListeners(
                         nestedInnerNode,
                         nestedNodeConfig,
-                        viewReadOnly(anyConfigs, anyCfg -> 
dynamicConfig(anyCfg, key)),
+                        mapIterable(anyConfigs, anyCfg -> 
dynamicConfig(anyCfg, key)),
                         ctx
                 );
 
@@ -406,7 +406,7 @@ public class ConfigurationNotifier {
             public Void visitNamedListNode(Field field, String key, 
NamedListNode<?> newNamedList) {
                 notifyPublicListeners(
                         listeners(namedDynamicConfig(config, key), 
ctx.notificationNum),
-                        concat(viewReadOnly(
+                        concat(mapIterable(
                                 anyConfigs,
                                 anyCfg -> listeners(namedDynamicConfig(anyCfg, 
key), ctx.notificationNum)
                         )),
@@ -419,7 +419,7 @@ public class ConfigurationNotifier {
                 // Created only.
 
                 // Lazy initialization.
-                Collection<DynamicConfiguration<InnerNode, ?>> newAnyConfigs = 
null;
+                Iterable<DynamicConfiguration<InnerNode, ?>> newAnyConfigs = 
null;
 
                 NamedListConfiguration<?, InnerNode, ?> namedListCfg = 
namedDynamicConfig(config, key);
 
@@ -436,7 +436,7 @@ public class ConfigurationNotifier {
 
                     notifyPublicListeners(
                             extendedListeners(namedDynamicConfig(config, key), 
ctx.notificationNum),
-                            concat(viewReadOnly(
+                            concat(mapIterable(
                                     anyConfigs,
                                     anyCfg -> 
extendedListeners(namedDynamicConfig(anyCfg, key), ctx.notificationNum)
                             )),
@@ -448,7 +448,7 @@ public class ConfigurationNotifier {
 
                     if (newAnyConfigs == null) {
                         newAnyConfigs = mergeAnyConfigs(
-                                viewReadOnly(anyConfigs, anyCfg -> 
any(namedDynamicConfig(anyCfg, key))),
+                                mapIterable(anyConfigs, anyCfg -> 
any(namedDynamicConfig(anyCfg, key))),
                                 any(namedDynamicConfig(config, key))
                         );
                     }
diff --git 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationUtil.java
 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationUtil.java
index c2003a8988..24e5f50a96 100644
--- 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationUtil.java
+++ 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/util/ConfigurationUtil.java
@@ -31,6 +31,7 @@ import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -42,6 +43,8 @@ import java.util.Queue;
 import java.util.RandomAccess;
 import java.util.Set;
 import java.util.UUID;
+import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.stream.Stream;
 import org.apache.ignite.configuration.ConfigurationProperty;
 import 
org.apache.ignite.configuration.ConfigurationWrongPolymorphicTypeIdException;
@@ -79,6 +82,9 @@ public class ConfigurationUtil {
     public static final ConfigurationSource EMPTY_CFG_SRC = new 
ConfigurationSource() {
     };
 
+    /** Special object for determining that there is no next element. */
+    private static final Object NO_NEXT_ELEMENT = new Object();
+
     /**
      * Seperator string for both public and internal representations of 
configuration keys.
      */
@@ -509,14 +515,11 @@ public class ConfigurationUtil {
      * @throws IllegalArgumentException If the configuration schemas does not 
contain {@link ConfigurationRoot}, {@link Config} or {@link
      *                                  PolymorphicConfig}.
      */
-    public static Set<Class<?>> collectSchemas(Collection<Class<?>> 
schemaClasses) {
-        if (schemaClasses.isEmpty()) {
-            return Set.of();
-        }
-
+    public static Set<Class<?>> collectSchemas(Iterable<Class<?>> 
schemaClasses) {
         Set<Class<?>> res = new HashSet<>();
 
-        Queue<Class<?>> queue = new ArrayDeque<>(Set.copyOf(schemaClasses));
+        Queue<Class<?>> queue = new ArrayDeque<>();
+        schemaClasses.forEach(queue::add);
 
         while (!queue.isEmpty()) {
             Class<?> cls = queue.poll();
@@ -886,6 +889,129 @@ public class ConfigurationUtil {
         }
     }
 
+    /**
+     * Maps iterable via provided mapper function. Filter all {@code null} 
mapped values.
+     *
+     * @param iterable Basic iterable.
+     * @param mapper Conversion function.
+     * @param <T1> Base type of the iterable.
+     * @param <T2> Type for view.
+     * @return Mapped iterable.
+     */
+    public static <T1, T2> Iterable<T2> mapIterable(
+            @Nullable Iterable<? extends T1> iterable,
+            @Nullable Function<? super T1, ? extends T2> mapper
+    ) {
+        if (iterable == null) {
+            return Collections.emptyList();
+        }
+
+        if (mapper == null) {
+            return (Iterable<T2>) iterable;
+        }
+
+        return () -> {
+            Iterator<? extends T1> innerIterator = iterable.iterator();
+            return new Iterator<>() {
+                @Nullable
+                private T2 next;
+
+                @Override
+                public boolean hasNext() {
+                    if (next != null) {
+                        return true;
+                    }
+
+                    while (innerIterator.hasNext()) {
+                        next = mapper.apply(innerIterator.next());
+                        if (next != null) {
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+
+                @Override
+                public T2 next() {
+                    if (!hasNext()) {
+                        throw new NoSuchElementException();
+                    }
+
+                    T2 result = next;
+                    next = null;
+                    return result;
+                }
+            };
+        };
+    }
+
+    /**
+     * Maps iterable via provided mapper function.
+     *
+     * @param iterable Basic iterable.
+     * @param mapper Conversion function.
+     * @param predicate Predicate to apply to each element of basic iterable.
+     * @param <T1> Base type of the iterable.
+     * @param <T2> Type for view.
+     * @return Mapped iterable.
+     */
+    public static <T1, T2> Iterable<T2> mapIterable(
+            @Nullable Iterable<? extends T1> iterable,
+            @Nullable Function<? super T1, ? extends T2> mapper,
+            @Nullable Predicate<? super T1> predicate
+    ) {
+        if (iterable == null) {
+            return Collections.emptyList();
+        }
+
+        if (mapper == null && predicate == null) {
+            return (Iterable<T2>) iterable;
+        }
+
+        return new Iterable<>() {
+            @Override
+            public Iterator<T2> iterator() {
+                Iterator<? extends T1> innerIterator = iterable.iterator();
+                return new Iterator<>() {
+                    @Nullable
+                    T1 current = advance();
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public boolean hasNext() {
+                        return current != NO_NEXT_ELEMENT;
+                    }
+
+                    /** {@inheritDoc} */
+                    @Override
+                    public T2 next() {
+                        T1 current = this.current;
+
+                        if (current == NO_NEXT_ELEMENT) {
+                            throw new NoSuchElementException();
+                        }
+
+                        this.current = advance();
+
+                        return mapper == null ? (T2) current : 
mapper.apply(current);
+                    }
+
+                    private @Nullable T1 advance() {
+                        while (innerIterator.hasNext()) {
+                            T1 next = innerIterator.next();
+
+                            if (predicate == null || predicate.test(next)) {
+                                return next;
+                            }
+                        }
+
+                        return (T1) NO_NEXT_ELEMENT;
+                    }
+                };
+            }
+        };
+    }
+
     /**
      * Leaf configuration source.
      */
diff --git 
a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/util/ConfigurationUtilTest.java
 
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/util/ConfigurationUtilTest.java
index 19a527214e..2ac4b6decf 100644
--- 
a/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/util/ConfigurationUtilTest.java
+++ 
b/modules/configuration/src/test/java/org/apache/ignite/internal/configuration/util/ConfigurationUtilTest.java
@@ -17,7 +17,9 @@
 
 package org.apache.ignite.internal.configuration.util;
 
+import static java.util.Collections.emptyList;
 import static java.util.Collections.singletonMap;
+import static java.util.function.Function.identity;
 import static java.util.stream.Collectors.toList;
 import static 
org.apache.ignite.configuration.annotation.ConfigurationType.DISTRIBUTED;
 import static 
org.apache.ignite.configuration.annotation.ConfigurationType.LOCAL;
@@ -31,6 +33,7 @@ import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.co
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.compressDeletedEntries;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.extensionsFields;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.find;
+import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.mapIterable;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.polymorphicSchemaExtensions;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.removeLastKey;
 import static 
org.apache.ignite.internal.configuration.util.ConfigurationUtil.schemaExtensions;
@@ -43,6 +46,7 @@ import static org.hamcrest.Matchers.hasToString;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.matchesPattern;
 import static org.hamcrest.Matchers.nullValue;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -55,12 +59,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import java.io.Serializable;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Set;
+import java.util.Spliterators;
 import java.util.UUID;
 import java.util.function.Consumer;
+import java.util.stream.StreamSupport;
 import org.apache.ignite.configuration.NamedListView;
 import org.apache.ignite.configuration.RootKey;
 import org.apache.ignite.configuration.annotation.Config;
@@ -1117,6 +1125,104 @@ public class ConfigurationUtilTest {
         assertNotSame(afterDefaults, beforeDefaults);
     }
 
+    /**
+     * Collect of elements.
+     *
+     * @param iterable Iterable.
+     * @param <T> Type of the elements.
+     * @return Collected elements.
+     */
+    private <T> List<? extends T> collect(Iterable<? extends T> iterable) {
+        return 
StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterable.iterator(), 
0), false).collect(toList());
+    }
+
+    @Test
+    void testMapIterable() {
+        assertFalse(mapIterable(null, null).iterator().hasNext());
+        assertFalse(mapIterable(emptyList(), null).iterator().hasNext());
+
+        assertEquals(List.of(1), collect(mapIterable(List.of(1), null)));
+        assertEquals(List.of(1), collect(mapIterable(List.of(1), identity())));
+
+        assertEquals(List.of("1", "2", "3"), collect(mapIterable(List.of(1, 2, 
3), String::valueOf)));
+
+        assertThrows(UnsupportedOperationException.class, () -> 
mapIterable(List.of(1), null).iterator().remove());
+
+        Iterator<Integer> iterator = mapIterable(Arrays.asList(1, 2, null, 3), 
identity()).iterator();
+
+        //Test iterator contracts
+        assertTrue(iterator.hasNext());
+        assertEquals(1, iterator.next());
+
+        assertEquals(2, iterator.next());
+
+        assertTrue(iterator.hasNext());
+        assertTrue(iterator.hasNext());
+        assertEquals(3, iterator.next());
+
+        assertFalse(iterator.hasNext());
+        assertFalse(iterator.hasNext());
+        assertThrows(NoSuchElementException.class, iterator::next);
+        assertThrows(NoSuchElementException.class, iterator::next);
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    void testMapIterableWithPredicate() {
+        assertFalse(mapIterable(null, null, null).iterator().hasNext());
+        assertFalse(mapIterable(emptyList(), null, null).iterator().hasNext());
+
+        assertEquals(List.of(1), collect(mapIterable(List.of(1), null, null)));
+        assertEquals(List.of(1), collect(mapIterable(List.of(1), identity(), 
null)));
+        assertEquals(List.of(1), collect(mapIterable(List.of(1), null, integer 
-> true)));
+        assertEquals(List.of(1), collect(mapIterable(List.of(1), identity(), 
integer -> true)));
+        assertEquals(List.of(), collect(mapIterable(List.of(1), null, integer 
-> false)));
+        assertEquals(List.of(), collect(mapIterable(List.of(1), identity(), 
integer -> false)));
+
+        assertEquals(List.of("1", "2", "3"), collect(mapIterable(List.of(1, 2, 
3), String::valueOf, null)));
+        assertEquals(List.of("3"), collect(mapIterable(List.of(1, 2, 3), 
String::valueOf, integer -> integer > 2)));
+
+        Iterator<String> iterator1 = mapIterable(List.of(1, 2, 3, 4), 
String::valueOf, integer -> true).iterator();
+        assertEquals("1", iterator1.next());
+        assertEquals("2", iterator1.next());
+        assertEquals("3", iterator1.next());
+        assertEquals("4", iterator1.next());
+
+        Iterator<String> iterator2 = mapIterable(List.of(1, 2, 3, 4), 
String::valueOf, null).iterator();
+        assertEquals("1", iterator2.next());
+        assertEquals("2", iterator2.next());
+        assertEquals("3", iterator2.next());
+        assertEquals("4", iterator2.next());
+
+        Iterator<Integer> iterator3 = mapIterable(List.of(1, 2, 3, 4), 
identity(), integer -> integer < 3).iterator();
+        assertEquals(1, iterator3.next());
+        assertEquals(2, iterator3.next());
+
+        Iterator<Integer> iterator4 = mapIterable(List.of(1, 2, 3, 4), 
identity(), integer -> false).iterator();
+        assertFalse(iterator4.hasNext());
+
+        assertDoesNotThrow(() -> mapIterable(Arrays.asList(new 
Integer[]{null}), null, null).iterator().next());
+        assertDoesNotThrow(() -> mapIterable(Arrays.asList(new 
Integer[]{null}), null, integer -> true).iterator().next());
+        assertDoesNotThrow(() -> mapIterable(Arrays.asList(null, 1), null, 
null).iterator().next());
+        assertDoesNotThrow(() -> mapIterable(Arrays.asList(null, 1), null, 
integer -> true).iterator().next());
+
+        assertThrows(
+                NoSuchElementException.class,
+                () -> mapIterable(Arrays.asList(new Integer[]{null}), null, 
integer -> false).iterator().next()
+        );
+
+        assertThrows(
+                NoSuchElementException.class,
+                () -> {
+                    Iterator<Object> iterator = 
mapIterable(Arrays.asList(null, 1), null, Objects::nonNull).iterator();
+                    iterator.next();
+                    iterator.next();
+                }
+        );
+
+        assertThrows(UnsupportedOperationException.class, () -> 
mapIterable(List.of(1), null, null).iterator().remove());
+    }
+
     /**
      * Patches super root and returns flat representation of the changes. 
Passed {@code superRoot} object will contain patched tree when
      * method execution is completed.
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 35fc6289ba..10602c7458 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
@@ -19,8 +19,6 @@ package org.apache.ignite.internal.util;
 
 import static java.util.Collections.addAll;
 import static java.util.Collections.emptyIterator;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.unmodifiableCollection;
 import static java.util.Collections.unmodifiableSet;
 import static java.util.stream.Collectors.toSet;
 
@@ -40,7 +38,6 @@ import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.function.Function;
-import java.util.function.Predicate;
 import java.util.stream.Collector;
 import java.util.stream.Collectors;
 import org.jetbrains.annotations.Nullable;
@@ -49,9 +46,6 @@ import org.jetbrains.annotations.Nullable;
  * Utility class provides various method to work with collections.
  */
 public final class CollectionUtils {
-    /** Special object for determining that there is no next element. */
-    private static final Object NO_NEXT_ELEMENT = new Object();
-
     /** Stub. */
     private CollectionUtils() {
         // No op.
@@ -316,14 +310,29 @@ public final class CollectionUtils {
      * @param <T> Type of the elements.
      * @return Concatenation of iterators.
      */
-    public static <T> Iterator<T> concat(@Nullable Collection<Iterator<? 
extends T>> iterators) {
-        if (iterators == null || iterators.isEmpty()) {
+    public static <T> Iterator<T> concat(@Nullable Iterable<Iterator<? extends 
T>> iterators) {
+        if (iterators == null) {
+            return emptyIterator();
+        }
+
+        return concat(iterators.iterator());
+    }
+
+    /**
+     * Create a lazy concatenation of iterators.
+     *
+     * <p>NOTE: {@link Iterator#remove} - not supported.
+     *
+     * @param iterators Iterators.
+     * @param <T> Type of the elements.
+     * @return Concatenation of iterators.
+     */
+    public static <T> Iterator<T> concat(@Nullable Iterator<Iterator<? extends 
T>> iterators) {
+        if (iterators == null || !iterators.hasNext()) {
             return emptyIterator();
         }
 
         return new Iterator<>() {
-            /** Super iterator. */
-            final Iterator<Iterator<? extends T>> it = iterators.iterator();
 
             /** Current iterator. */
             Iterator<? extends T> curr = emptyIterator();
@@ -331,8 +340,8 @@ public final class CollectionUtils {
             /** {@inheritDoc} */
             @Override
             public boolean hasNext() {
-                while (!curr.hasNext() && it.hasNext()) {
-                    curr = it.next();
+                while (!curr.hasNext() && iterators.hasNext()) {
+                    curr = iterators.next();
                 }
 
                 return curr.hasNext();
@@ -410,157 +419,6 @@ public final class CollectionUtils {
         };
     }
 
-    /**
-     * Create a collection view that can only be read.
-     *
-     * @param collection Basic collection.
-     * @param mapper Conversion function.
-     * @param <T1> Base type of the collection.
-     * @param <T2> Type for view.
-     * @return Read-only collection view.
-     */
-    public static <T1, T2> Collection<T2> viewReadOnly(
-            @Nullable Collection<? extends T1> collection,
-            @Nullable Function<? super T1, ? extends T2> mapper
-    ) {
-        if (nullOrEmpty(collection)) {
-            return emptyList();
-        }
-
-        if (mapper == null) {
-            return unmodifiableCollection((Collection<T2>) collection);
-        }
-
-        return new AbstractCollection<>() {
-            /** {@inheritDoc} */
-            @Override
-            public Iterator<T2> iterator() {
-                Iterator<? extends T1> iterator = collection.iterator();
-
-                return new Iterator<>() {
-                    /** {@inheritDoc} */
-                    @Override
-                    public boolean hasNext() {
-                        return iterator.hasNext();
-                    }
-
-                    /** {@inheritDoc} */
-                    @Override
-                    public T2 next() {
-                        return mapper.apply(iterator.next());
-                    }
-                };
-            }
-
-            /** {@inheritDoc} */
-            @Override
-            public int size() {
-                return collection.size();
-            }
-
-            /** {@inheritDoc} */
-            @Override
-            public boolean isEmpty() {
-                return collection.isEmpty();
-            }
-        };
-    }
-
-    /**
-     * Create a collection view that can only be read.
-     *
-     * @param collection Basic collection.
-     * @param mapper Conversion function.
-     * @param predicate Predicate to apply to each element of basic collection.
-     * @param <T1> Base type of the collection.
-     * @param <T2> Type for view.
-     * @return Read-only collection view.
-     */
-    public static <T1, T2> Collection<T2> viewReadOnly(
-            @Nullable Collection<? extends T1> collection,
-            @Nullable Function<? super T1, ? extends T2> mapper,
-            @Nullable Predicate<? super T1> predicate
-    ) {
-        if (collection == null) {
-            return emptyList();
-        }
-
-        if (mapper == null && predicate == null) {
-            return unmodifiableCollection((Collection<T2>) collection);
-        }
-
-        return new AbstractCollection<>() {
-            /** {@inheritDoc} */
-            @Override
-            public Iterator<T2> iterator() {
-                Iterator<? extends T1> iterator = collection.iterator();
-
-                return new Iterator<>() {
-                    @Nullable
-                    T1 current = advance();
-
-                    /** {@inheritDoc} */
-                    @Override
-                    public boolean hasNext() {
-                        return current != NO_NEXT_ELEMENT;
-                    }
-
-                    /** {@inheritDoc} */
-                    @Override
-                    public T2 next() {
-                        T1 current = this.current;
-
-                        if (current == NO_NEXT_ELEMENT) {
-                            throw new NoSuchElementException();
-                        }
-
-                        this.current = advance();
-
-                        return mapper == null ? (T2) current : 
mapper.apply(current);
-                    }
-
-                    private @Nullable T1 advance() {
-                        while (iterator.hasNext()) {
-                            T1 next = iterator.next();
-
-                            if (predicate == null || predicate.test(next)) {
-                                return next;
-                            }
-                        }
-
-                        return (T1) NO_NEXT_ELEMENT;
-                    }
-                };
-            }
-
-            /** {@inheritDoc} */
-            @Override
-            public int size() {
-                if (predicate == null) {
-                    return collection.size();
-                }
-
-                int count = 0;
-
-                for (Iterator<T2> iterator = iterator(); iterator.hasNext(); 
iterator.next()) {
-                    count++;
-                }
-
-                return count;
-            }
-
-            /** {@inheritDoc} */
-            @Override
-            public boolean isEmpty() {
-                if (predicate == null) {
-                    return collection.isEmpty();
-                }
-
-                return size() == 0;
-            }
-        };
-    }
-
     /**
      * Difference of two sets.
      *
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 b3cbc4107c..4bf160b553 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
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal.util;
 
 import static java.util.Collections.emptyIterator;
-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;
@@ -26,11 +25,9 @@ import static 
org.apache.ignite.internal.util.CollectionUtils.intersect;
 import static org.apache.ignite.internal.util.CollectionUtils.last;
 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.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.Matchers.is;
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -45,8 +42,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Objects;
 import java.util.Set;
 import java.util.Spliterators;
 import java.util.stream.StreamSupport;
@@ -83,87 +78,6 @@ public class CollectionUtilsTest {
         assertEquals(Set.of(1, 2), union(Set.of(1), 2));
     }
 
-    @Test
-    void testViewReadOnly() {
-        assertTrue(viewReadOnly(null, null).isEmpty());
-        assertTrue(viewReadOnly(List.of(), null).isEmpty());
-
-        assertEquals(List.of(1), collect(viewReadOnly(List.of(1), null)));
-        assertEquals(List.of(1), collect(viewReadOnly(List.of(1), 
identity())));
-
-        assertEquals(List.of("1", "2", "3"), collect(viewReadOnly(List.of(1, 
2, 3), String::valueOf)));
-
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null).add(1));
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null).addAll(List.of()));
-
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null).remove(1));
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null).removeAll(List.of()));
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null).removeIf(o -> true));
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null).clear());
-
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null).retainAll(List.of()));
-
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null).iterator().remove());
-    }
-
-    @Test
-    void testViewReadOnlyWithPredicate() {
-        assertTrue(viewReadOnly(null, null, null).isEmpty());
-        assertTrue(viewReadOnly(List.of(), null, null).isEmpty());
-
-        assertEquals(List.of(1), collect(viewReadOnly(List.of(1), null, 
null)));
-        assertEquals(List.of(1), collect(viewReadOnly(List.of(1), identity(), 
null)));
-        assertEquals(List.of(1), collect(viewReadOnly(List.of(1), null, 
integer -> true)));
-        assertEquals(List.of(1), collect(viewReadOnly(List.of(1), identity(), 
integer -> true)));
-        assertEquals(List.of(), collect(viewReadOnly(List.of(1), null, integer 
-> false)));
-        assertEquals(List.of(), collect(viewReadOnly(List.of(1), identity(), 
integer -> false)));
-
-        assertEquals(List.of("1", "2", "3"), collect(viewReadOnly(List.of(1, 
2, 3), String::valueOf, null)));
-        assertEquals(List.of("3"), collect(viewReadOnly(List.of(1, 2, 3), 
String::valueOf, integer -> integer > 2)));
-
-        assertEquals(4, viewReadOnly(List.of(1, 2, 3, 4), String::valueOf, 
integer -> true).size());
-        assertEquals(4, viewReadOnly(List.of(1, 2, 3, 4), String::valueOf, 
null).size());
-        assertEquals(2, viewReadOnly(List.of(1, 2, 3, 4), identity(), integer 
-> integer < 3).size());
-        assertEquals(0, viewReadOnly(List.of(1, 2, 3, 4), identity(), integer 
-> false).size());
-
-        assertFalse(viewReadOnly(List.of(1, 2, 3, 4), String::valueOf, integer 
-> true).isEmpty());
-        assertFalse(viewReadOnly(List.of(1, 2, 3, 4), String::valueOf, 
null).isEmpty());
-        assertFalse(viewReadOnly(List.of(1, 2, 3, 4), identity(), integer -> 
integer > 3).isEmpty());
-        assertTrue(viewReadOnly(List.of(1, 2, 3, 4), identity(), integer -> 
integer > 4).isEmpty());
-        assertTrue(viewReadOnly(List.of(1, 2, 3, 4), identity(), integer -> 
false).isEmpty());
-
-        assertDoesNotThrow(() -> viewReadOnly(Arrays.asList(new 
Integer[]{null}), null, null).iterator().next());
-        assertDoesNotThrow(() -> viewReadOnly(Arrays.asList(new 
Integer[]{null}), null, integer -> true).iterator().next());
-        assertDoesNotThrow(() -> viewReadOnly(Arrays.asList(null, 1), null, 
null).iterator().next());
-        assertDoesNotThrow(() -> viewReadOnly(Arrays.asList(null, 1), null, 
integer -> true).iterator().next());
-
-        assertThrows(
-                NoSuchElementException.class,
-                () -> viewReadOnly(Arrays.asList(new Integer[]{null}), null, 
integer -> false).iterator().next()
-        );
-
-        assertThrows(
-                NoSuchElementException.class,
-                () -> {
-                    Iterator<Object> iterator = 
viewReadOnly(Arrays.asList(null, 1), null, Objects::nonNull).iterator();
-                    iterator.next();
-                    iterator.next();
-                }
-        );
-
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null, null).add(1));
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null, null).addAll(List.of()));
-
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null, null).remove(1));
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null, null).removeAll(List.of()));
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null, null).removeIf(o -> true));
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null, null).clear());
-
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null, null).retainAll(List.of()));
-
-        assertThrows(UnsupportedOperationException.class, () -> 
viewReadOnly(List.of(1), null, null).iterator().remove());
-    }
-
     @Test
     void testSetDifference() {
         assertTrue(difference(null, Set.of(1, 2, 3, 4)).isEmpty());
@@ -263,7 +177,7 @@ public class CollectionUtilsTest {
     }
 
     @Test
-    void testConcatCollectionOfIterators() {
+    void testConcatIteratorOfIterators() {
         assertTrue(collect(concat((Collection<Iterator<?>>) null)).isEmpty());
         assertTrue(collect(concat(List.of())).isEmpty());
         assertTrue(collect(concat(List.of(emptyIterator(), 
emptyIterator()))).isEmpty());
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/compaction/Compactor.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/compaction/Compactor.java
index 0320202aee..c5e0cea1b4 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/compaction/Compactor.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/compaction/Compactor.java
@@ -190,7 +190,7 @@ public class Compactor extends IgniteWorker {
     void doCompaction() {
         while (true) {
             // Let's collect one delta file for each partition.
-            Queue<DeltaFileForCompaction> queue = 
filePageStoreManager.allPageStores().stream()
+            Queue<DeltaFileForCompaction> queue = 
filePageStoreManager.allPageStores()
                     .map(groupPartitionFilePageStore -> {
                         DeltaFilePageStoreIo deltaFileToCompaction = 
groupPartitionFilePageStore.pageStore().getDeltaFileToCompaction();
 
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/FilePageStoreManager.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/FilePageStoreManager.java
index fd1cc00176..d187724c3e 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/FilePageStoreManager.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/FilePageStoreManager.java
@@ -34,7 +34,6 @@ import java.nio.ByteBuffer;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.regex.Matcher;
@@ -317,7 +316,7 @@ public class FilePageStoreManager implements 
PageReadWriteManager {
     /**
      * Returns view for all page stores of all groups.
      */
-    public Collection<GroupPartitionPageStore<FilePageStore>> allPageStores() {
+    public Stream<GroupPartitionPageStore<FilePageStore>> allPageStores() {
         return groupPageStores.getAll();
     }
 
@@ -357,7 +356,7 @@ public class FilePageStoreManager implements 
PageReadWriteManager {
      * @param cleanFiles Delete files.
      */
     void stopAllGroupFilePageStores(boolean cleanFiles) {
-        List<FilePageStore> partitionPageStores = 
groupPageStores.getAll().stream()
+        List<FilePageStore> partitionPageStores = groupPageStores.getAll()
                 .map(GroupPartitionPageStore::pageStore)
                 .collect(toList());
 
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/GroupPageStoresMap.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/GroupPageStoresMap.java
index 8ae97ea6c9..17a7fa2de1 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/GroupPageStoresMap.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/GroupPageStoresMap.java
@@ -17,11 +17,10 @@
 
 package org.apache.ignite.internal.pagememory.persistence.store;
 
-import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
 import org.apache.ignite.internal.pagememory.persistence.GroupPartitionId;
-import org.apache.ignite.internal.util.CollectionUtils;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -89,8 +88,8 @@ public class GroupPageStoresMap<T extends PageStore> {
     /**
      * Returns a view of all page stores of all groups.
      */
-    public Collection<GroupPartitionPageStore<T>> getAll() {
-        return 
CollectionUtils.viewReadOnly(groupPartitionIdPageStore.entrySet(), 
GroupPartitionPageStore::new);
+    public Stream<GroupPartitionPageStore<T>> getAll() {
+        return 
groupPartitionIdPageStore.entrySet().stream().map(GroupPartitionPageStore::new);
     }
 
     /**
diff --git 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/store/FilePageStoreManagerTest.java
 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/store/FilePageStoreManagerTest.java
index 005d9ca4c0..19c233a0fd 100644
--- 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/store/FilePageStoreManagerTest.java
+++ 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/store/FilePageStoreManagerTest.java
@@ -47,6 +47,7 @@ import static org.mockito.Mockito.verify;
 
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Stream;
@@ -144,8 +145,9 @@ public class FilePageStoreManagerTest extends 
BaseIgniteAbstractTest {
                 assertThat(files.count(), is(0L));
             }
 
-            for (GroupPartitionPageStore<FilePageStore> filePageStore : 
manager.allPageStores()) {
-                filePageStore.pageStore().ensure();
+            Iterator<GroupPartitionPageStore<FilePageStore>> iterator = 
manager.allPageStores().iterator();
+            while (iterator.hasNext()) {
+                iterator.next().pageStore().ensure();
             }
 
             try (Stream<Path> files = Files.list(testGroupDir)) {
@@ -329,7 +331,7 @@ public class FilePageStoreManagerTest extends 
BaseIgniteAbstractTest {
         manager.initialize(new GroupPartitionId(1, 0));
         manager.initialize(new GroupPartitionId(2, 0));
 
-        List<Path> allPageStoreFiles = manager.allPageStores().stream()
+        List<Path> allPageStoreFiles = manager.allPageStores()
                 .map(GroupPartitionPageStore::pageStore)
                 .map(FilePageStore::filePath)
                 .collect(toList());
diff --git 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/store/GroupPageStoresMapTest.java
 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/store/GroupPageStoresMapTest.java
index 84fd1df75e..03abdaefe0 100644
--- 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/store/GroupPageStoresMapTest.java
+++ 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/store/GroupPageStoresMapTest.java
@@ -35,6 +35,7 @@ import static org.mockito.Mockito.when;
 
 import java.util.Collection;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 import org.apache.ignite.internal.pagememory.persistence.GroupPartitionId;
 import 
org.apache.ignite.internal.pagememory.persistence.store.GroupPageStoresMap.GroupPartitionPageStore;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
@@ -168,7 +169,7 @@ public class GroupPageStoresMapTest extends 
BaseIgniteAbstractTest {
 
     @Test
     void testGetAll() {
-        assertThat(groupPageStoresMap.getAll(), empty());
+        assertThat(groupPageStoresMap.getAll().collect(toList()), empty());
 
         FilePageStore filePageStore0 = mock(FilePageStore.class);
         FilePageStore filePageStore1 = mock(FilePageStore.class);
@@ -196,7 +197,7 @@ public class GroupPageStoresMapTest extends 
BaseIgniteAbstractTest {
 
         groupPageStoresMap.clear();
 
-        assertThat(groupPageStoresMap.getAll(), empty());
+        assertThat(groupPageStoresMap.getAll().collect(toList()), empty());
     }
 
     @Test
@@ -238,9 +239,9 @@ public class GroupPageStoresMapTest extends 
BaseIgniteAbstractTest {
     }
 
     private static <T extends PageStore> 
Collection<TestGroupPartitionPageStore<T>> getAll(
-            Collection<GroupPartitionPageStore<T>> groupPartitionPageStores
+            Stream<GroupPartitionPageStore<T>> groupPartitionPageStores
     ) {
-        return groupPartitionPageStores.stream()
+        return groupPartitionPageStores
                 .map(TestGroupPartitionPageStore::of)
                 .collect(toList());
     }

Reply via email to