From: Robert Varga Date: Sun, 25 Oct 2020 23:40:40 +0000 (+0100) Subject: Add DOMQueryResult streaming interfaces X-Git-Tag: v7.0.2~53 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=b620c86025390e3f86eaade9f9c0f102ce6313fa;p=mdsal.git Add DOMQueryResult streaming interfaces Current definition is really an implementation-specific. The API exposed from DOMQueryResult is eager, not allowing for eager termination of searching. Fix this by turning DOMQueryResult into an interface and add an eager implementation to match current behavior. Also update DefaultQueryResult to take advantage of lazy transformations. JIRA: MDSAL-605 Change-Id: I8375954e09ce6139aad0f83e883ed75771faceab Signed-off-by: Robert Varga --- diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQuery.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQuery.java index d0f73440e5..0539fd0c44 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQuery.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQuery.java @@ -37,7 +37,7 @@ public final class DefaultQuery implements QueryExpression } public QueryResult toQueryResult(final DOMQueryResult domResult) { - return new DefaultQueryResult<>(codec, domResult.items()); + return new DefaultQueryResult<>(codec, domResult); } @Override diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQueryResult.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQueryResult.java index 516a83e596..8281101cfa 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQueryResult.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQueryResult.java @@ -10,30 +10,27 @@ package org.opendaylight.mdsal.binding.dom.adapter.query; import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; -import com.google.common.base.Function; import com.google.common.base.VerifyException; -import com.google.common.collect.Lists; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.util.List; import java.util.Map.Entry; import java.util.Spliterator; +import java.util.function.Function; import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.gaul.modernizer_maven_annotations.SuppressModernizer; import org.opendaylight.mdsal.binding.api.query.QueryResult; import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree; import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode; import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode; +import org.opendaylight.mdsal.dom.api.query.DOMQueryResult; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @NonNullByDefault -@SuppressModernizer final class DefaultQueryResult implements QueryResult, Function>, QueryResult.Item> { private static final VarHandle ITEM_CODEC; @@ -47,22 +44,21 @@ final class DefaultQueryResult } } - private final List>> domResult; + private final DOMQueryResult domResult; private final BindingCodecTree codec; @SuppressWarnings("unused") @SuppressFBWarnings(value = "NP_STORE_INTO_NONNULL_FIELD", justification = "Ungrokked type annotation") private volatile @Nullable BindingDataObjectCodecTreeNode itemCodec = null; - DefaultQueryResult(final BindingCodecTree codec, - final List>> domResult) { + DefaultQueryResult(final BindingCodecTree codec, final DOMQueryResult domResult) { this.codec = requireNonNull(codec); this.domResult = requireNonNull(domResult); } @Override public Spliterator> spliterator() { - return Lists.transform(domResult, this).spliterator(); + return new DefaultQueryResultSpliterator<>(this, domResult.spliterator()); } @Override diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQueryResultSpliterator.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQueryResultSpliterator.java new file mode 100644 index 0000000000..b239ec273c --- /dev/null +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/query/DefaultQueryResultSpliterator.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.mdsal.binding.dom.adapter.query; + +import static java.util.Objects.requireNonNull; + +import java.util.Map.Entry; +import java.util.Spliterator; +import java.util.function.Consumer; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.mdsal.binding.api.query.QueryResult; +import org.opendaylight.mdsal.binding.api.query.QueryResult.Item; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +@NonNullByDefault +final class DefaultQueryResultSpliterator implements Spliterator> { + private final Spliterator>> domSpliterator; + private final DefaultQueryResult result; + + DefaultQueryResultSpliterator(final DefaultQueryResult result, + final Spliterator>> domSpliterator) { + this.result = requireNonNull(result); + this.domSpliterator = requireNonNull(domSpliterator); + } + + @Override + public boolean tryAdvance(final @Nullable Consumer> action) { + return domSpliterator.tryAdvance(dom -> action.accept(new DefaultQueryResultItem<>(result, dom))); + } + + @Override + public @Nullable Spliterator> trySplit() { + final Spliterator>> split = + domSpliterator.trySplit(); + return split == null ? null : new DefaultQueryResultSpliterator<>(result, split); + } + + @Override + public long estimateSize() { + return domSpliterator.estimateSize(); + } + + @Override + public long getExactSizeIfKnown() { + return domSpliterator.getExactSizeIfKnown(); + } + + @Override + public int characteristics() { + return domSpliterator.characteristics(); + } +} diff --git a/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/query/DOMQueryResult.java b/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/query/DOMQueryResult.java index 71386624cc..14025c8ad2 100644 --- a/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/query/DOMQueryResult.java +++ b/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/query/DOMQueryResult.java @@ -8,9 +8,11 @@ package org.opendaylight.mdsal.dom.api.query; import com.google.common.annotations.Beta; -import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Map.Entry; +import java.util.Spliterator; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @@ -21,24 +23,15 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; */ @Beta @NonNullByDefault -public final class DOMQueryResult implements Immutable { - private static final DOMQueryResult EMPTY_INSTANCE = new DOMQueryResult(ImmutableList.of()); +public interface DOMQueryResult extends Immutable { - private final ImmutableList>> items; + Spliterator>> spliterator(); - private DOMQueryResult(final List>> items) { - this.items = ImmutableList.copyOf(items); - } - - public static DOMQueryResult of() { - return EMPTY_INSTANCE; - } + Stream>> stream(); - public static DOMQueryResult of(final List>> items) { - return items.isEmpty() ? of() : new DOMQueryResult(items); - } + Stream>> parallelStream(); - public List>> items() { - return items; + default List>> items() { + return stream().collect(Collectors.toUnmodifiableList()); } } diff --git a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/query/DOMQueryEvaluator.java b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/query/DOMQueryEvaluator.java index 12df752e9d..671b8eadd9 100644 --- a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/query/DOMQueryEvaluator.java +++ b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/query/DOMQueryEvaluator.java @@ -64,7 +64,7 @@ public final class DOMQueryEvaluator { for (PathArgument arg : query.getRoot().getPathArguments()) { final Optional> next = NormalizedNodes.findNode(root, arg); if (next.isEmpty()) { - return DOMQueryResult.of(); + return EagerDOMQueryResult.of(); } evalRoot = next.orElseThrow(); } @@ -75,7 +75,7 @@ public final class DOMQueryEvaluator { final DOMQuery query) { final List>> result = new ArrayList<>(); evalPath(result, new ArrayDeque<>(query.getRoot().getPathArguments()), remaining, data, query); - return DOMQueryResult.of(result); + return EagerDOMQueryResult.of(result); } private static void evalPath(final List>> result, @@ -110,8 +110,8 @@ public final class DOMQueryEvaluator { } private static DOMQueryResult evalSingle(final NormalizedNode data, final DOMQuery query) { - return matches(data, query) ? DOMQueryResult.of() - : DOMQueryResult.of(List.of(new SimpleImmutableEntry<>(query.getRoot(), data))); + return matches(data, query) ? EagerDOMQueryResult.of() + : EagerDOMQueryResult.of(new SimpleImmutableEntry<>(query.getRoot(), data)); } private static boolean matches(final NormalizedNode data, final DOMQuery query) { diff --git a/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/query/EagerDOMQueryResult.java b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/query/EagerDOMQueryResult.java new file mode 100644 index 0000000000..33d6a47c98 --- /dev/null +++ b/dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/query/EagerDOMQueryResult.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.mdsal.dom.spi.query; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableList; +import java.util.List; +import java.util.Map.Entry; +import java.util.Spliterator; +import java.util.stream.Stream; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.opendaylight.mdsal.dom.api.query.DOMQueryResult; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +@Beta +@NonNullByDefault +public final class EagerDOMQueryResult implements DOMQueryResult { + private static final EagerDOMQueryResult EMPTY_INSTANCE = new EagerDOMQueryResult(ImmutableList.of()); + + private final ImmutableList>> items; + + private EagerDOMQueryResult(final List>> items) { + this.items = ImmutableList.copyOf(items); + } + + public static EagerDOMQueryResult of() { + return EMPTY_INSTANCE; + } + + public static EagerDOMQueryResult of(final Entry> item) { + return new EagerDOMQueryResult(ImmutableList.of(item)); + } + + public static EagerDOMQueryResult of( + final List>> items) { + return items.isEmpty() ? of() : new EagerDOMQueryResult(items); + } + + @Override + public Spliterator>> spliterator() { + return items.spliterator(); + } + + @Override + public Stream>> stream() { + return items.stream(); + } + + @Override + public Stream>> parallelStream() { + return items.parallelStream(); + } + + @Override + public List>> items() { + return items; + } +}