From 424806c5f46307051a22f57d069768de082217ce Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Sat, 22 Feb 2025 21:27:58 +0100 Subject: [PATCH] chore/feat: add stream operations to PlotQuery, avoid larger lookups --- .../util/query/AreaLimitedPlotProvider.java | 6 +++ .../core/util/query/ExpiredPlotProvider.java | 6 +++ .../core/util/query/FixedPlotProvider.java | 6 +++ .../core/util/query/GlobalPlotProvider.java | 6 +++ .../core/util/query/NullProvider.java | 6 +++ .../core/util/query/PlotProvider.java | 34 ++++++++++++++++- .../core/util/query/PlotQuery.java | 38 +++++++++++-------- .../core/util/query/SearchPlotProvider.java | 6 +++ 8 files changed, 92 insertions(+), 16 deletions(-) diff --git a/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java index 185bd58cf..5f4e99107 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/AreaLimitedPlotProvider.java @@ -24,6 +24,7 @@ import com.plotsquared.core.plot.PlotArea; import java.util.Collection; import java.util.LinkedList; import java.util.List; +import java.util.stream.Stream; class AreaLimitedPlotProvider implements PlotProvider { @@ -42,4 +43,9 @@ class AreaLimitedPlotProvider implements PlotProvider { return plots; } + @Override + public Stream streamPlots() { + return streamPlotsInPlotAreas(this.areas.toArray(PlotArea[]::new)); + } + } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java index 1fac18f2c..f43e7b58b 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/ExpiredPlotProvider.java @@ -22,6 +22,7 @@ import com.plotsquared.core.PlotSquared; import com.plotsquared.core.plot.Plot; import java.util.Collection; +import java.util.stream.Stream; class ExpiredPlotProvider implements PlotProvider { @@ -30,4 +31,9 @@ class ExpiredPlotProvider implements PlotProvider { return PlotSquared.platform().expireManager().getPendingExpired(); } + @Override + public Stream streamPlots() { + return getPlots().stream(); + } + } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/FixedPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/FixedPlotProvider.java index a8f43a024..dce320997 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/FixedPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/FixedPlotProvider.java @@ -23,6 +23,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import java.util.Collection; import java.util.Collections; +import java.util.stream.Stream; class FixedPlotProvider implements PlotProvider { @@ -37,4 +38,9 @@ class FixedPlotProvider implements PlotProvider { return Collections.singleton(plot); } + @Override + public Stream streamPlots() { + return Stream.of(plot); + } + } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java index e02994e63..4553498b5 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/GlobalPlotProvider.java @@ -26,6 +26,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.stream.Stream; class GlobalPlotProvider implements PlotProvider { @@ -44,4 +45,9 @@ class GlobalPlotProvider implements PlotProvider { return plots; } + @Override + public Stream streamPlots() { + return streamPlotsInPlotAreas(this.plotAreaManager.getAllPlotAreas()); + } + } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/NullProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/NullProvider.java index 17f0c752d..5120442f5 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/NullProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/NullProvider.java @@ -22,6 +22,7 @@ import com.plotsquared.core.plot.Plot; import java.util.Collection; import java.util.Collections; +import java.util.stream.Stream; class NullProvider implements PlotProvider { @@ -30,4 +31,9 @@ class NullProvider implements PlotProvider { return Collections.emptyList(); } + @Override + public Stream streamPlots() { + return Stream.empty(); + } + } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java index 05c6d54ba..110ed2d27 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java @@ -19,12 +19,44 @@ package com.plotsquared.core.util.query; import com.plotsquared.core.plot.Plot; +import com.plotsquared.core.plot.PlotArea; import java.util.Collection; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; -@FunctionalInterface interface PlotProvider { Collection getPlots(); + Stream streamPlots(); + + default Stream streamPlotsInPlotAreas(PlotArea[] areas) { + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new Iterator<>() { + private int areaIndex = -1; + private Iterator currentAreaPlots; + @Override + public boolean hasNext() { + if (currentAreaPlots == null) { + return areas.length > 0; + } + if (!currentAreaPlots.hasNext()) { + return ++areaIndex < areas.length - 1; + } + return true; + } + + @Override + public Plot next() { + if (currentAreaPlots == null) { + currentAreaPlots = areas[++areaIndex].getPlots().iterator(); + } + return currentAreaPlots.next(); + } + }, Spliterator.IMMUTABLE), false); + } + } diff --git a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java index 7a3533d35..6d4d6e3a6 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java @@ -229,6 +229,7 @@ public final class PlotQuery implements Iterable { public @NonNull PlotQuery hasOwner() { return this.addFilter(new HasOwnerFilter()); } + /** * Query for plots with a specific alias * @@ -307,7 +308,7 @@ public final class PlotQuery implements Iterable { * @return Matching plots */ public @NonNull Stream asStream() { - return this.asList().stream(); + return this.asList().stream(); // TODO: use stream functionality from PlotProvider? } /** @@ -427,22 +428,29 @@ public final class PlotQuery implements Iterable { * @return {@code true} if any provided plot matches the filters. */ public boolean anyMatch() { - if (this.filters.isEmpty()) { - return !this.plotProvider.getPlots().isEmpty(); - } else { - final Collection plots = this.plotProvider.getPlots(); - outer: - for (final Plot plot : plots) { - // a plot must pass all filters to match the criteria - for (final PlotFilter filter : this.filters) { - if (!filter.accepts(plot)) { - continue outer; - } + return hasMinimumMatches(1); + } + + /** + * Get whether this query matches at least {@code minimum} plots. + *
+ * Should be prioritized over {@link #count()}, if possible. + * This method only queries as many plots and areas as required without applying sorting. (short-circuiting on the stream) + * + * @param minimum the minimum amount of matches plots expected (inclusive) + * @return {@code true} if this query's result contains at least {@code minimum} plots (after optional filters). + * + * @since TODO + */ + public boolean hasMinimumMatches(int minimum) { + return this.plotProvider.streamPlots().filter(plot -> { + for (final PlotFilter filter : filters) { + if (!filter.accepts(plot)) { + return false; } - return true; // a plot passed all filters, so we have a match } - return false; - } + return true; + }).limit(minimum).count() == minimum; } @NonNull diff --git a/Core/src/main/java/com/plotsquared/core/util/query/SearchPlotProvider.java b/Core/src/main/java/com/plotsquared/core/util/query/SearchPlotProvider.java index df8f485b6..76d2195f6 100644 --- a/Core/src/main/java/com/plotsquared/core/util/query/SearchPlotProvider.java +++ b/Core/src/main/java/com/plotsquared/core/util/query/SearchPlotProvider.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; class SearchPlotProvider implements PlotProvider { @@ -115,4 +116,9 @@ class SearchPlotProvider implements PlotProvider { return getPlotsBySearch(this.searchTerm); } + @Override + public Stream streamPlots() { + return getPlots().stream(); // TODO: look into potentially optimizations here? + } + }