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()); }