Skip to content

Commit 78f7864

Browse files
committed
chore/feat: add comparator for plots, implement PlotQuery#asStream
1 parent 6c29fd5 commit 78f7864

File tree

7 files changed

+189
-65
lines changed

7 files changed

+189
-65
lines changed

Core/src/main/java/com/plotsquared/core/PlotSquared.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -713,8 +713,6 @@ private void sortPlotsByHash(final @NonNull Plot @NonNull [] input) {
713713
case CREATION_DATE_TIMESTAMP -> toReturn.addAll(sortPlotsByTimestamp(map.get(area)));
714714
case DISTANCE_FROM_ORIGIN -> toReturn.addAll(sortPlotsByHash(map.get(area)));
715715
case LAST_MODIFIED -> toReturn.addAll(sortPlotsByModified(map.get(area)));
716-
default -> {
717-
}
718716
}
719717
}
720718
return toReturn;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.plotsquared.core.util.comparator;
2+
3+
import com.plotsquared.core.plot.Plot;
4+
import org.jetbrains.annotations.ApiStatus;
5+
6+
import java.util.Comparator;
7+
8+
/**
9+
* Sort plots by {@link Plot#temp} (being the auto increment id in database) in natural order for {@code temp > 0}.
10+
* For {@code temp < 1} sort by {@link Plot#hashCode()}
11+
*/
12+
@ApiStatus.Internal
13+
public class PlotByCreationDateComparator implements Comparator<Plot> {
14+
15+
@ApiStatus.Internal
16+
public static final Comparator<Plot> INSTANCE = new PlotByCreationDateComparator();
17+
18+
private PlotByCreationDateComparator() {
19+
}
20+
21+
@Override
22+
@SuppressWarnings("deprecation") // Plot#temp
23+
public int compare(final Plot first, final Plot second) {
24+
if (first.temp > 0 && second.temp > 0) {
25+
return Integer.compare(first.temp, second.temp);
26+
}
27+
// second is implicitly `< 1` (due to previous condition)
28+
if (first.temp > 0) {
29+
return 1;
30+
}
31+
// sort dangling plots (temp < 1) by their hashcode
32+
return Integer.compare(first.hashCode(), second.hashCode());
33+
}
34+
35+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.plotsquared.core.util.comparator;
2+
3+
import com.plotsquared.core.plot.Plot;
4+
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
5+
import com.plotsquared.core.util.MathMan;
6+
7+
import java.util.Comparator;
8+
9+
/**
10+
* Sort plots by their {@link DoneFlag} in reverse numeric natural order. (more recent "finished plots" first)
11+
* <br>
12+
* Non-finished plots last, unsorted.
13+
*/
14+
public class PlotByDoneComparator implements Comparator<Plot> {
15+
16+
public static final PlotByDoneComparator INSTANCE = new PlotByDoneComparator();
17+
18+
private PlotByDoneComparator() {
19+
}
20+
21+
@Override
22+
public int compare(final Plot first, final Plot second) {
23+
String firstDone = first.getFlag(DoneFlag.class);
24+
String lastDone = second.getFlag(DoneFlag.class);
25+
if (MathMan.isInteger(firstDone)) {
26+
if (MathMan.isInteger(lastDone)) {
27+
return Integer.parseInt(lastDone) - Integer.parseInt(firstDone);
28+
}
29+
return -1; // only "first" is finished, so sort "second" after "first"
30+
}
31+
return 0; // neither is finished
32+
}
33+
34+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.plotsquared.core.util.comparator;
2+
3+
import com.plotsquared.core.plot.Plot;
4+
import com.plotsquared.core.plot.Rating;
5+
6+
import java.util.Comparator;
7+
import java.util.Map;
8+
import java.util.UUID;
9+
10+
public class PlotByRatingComparator implements Comparator<Plot> {
11+
12+
public static final PlotByRatingComparator INSTANCE = new PlotByRatingComparator();
13+
14+
PlotByRatingComparator() {
15+
}
16+
17+
@Override
18+
public int compare(final Plot p1, final Plot p2) {
19+
double v1 = 0;
20+
int p1s = p1.getSettings().getRatings().size();
21+
int p2s = p2.getRatings().size();
22+
if (!p1.getSettings().getRatings().isEmpty()) {
23+
v1 = p1.getRatings().values().stream().mapToDouble(Rating::getAverageRating)
24+
.map(av -> av * av).sum();
25+
v1 /= p1s;
26+
v1 += p1s;
27+
}
28+
double v2 = 0;
29+
if (!p2.getSettings().getRatings().isEmpty()) {
30+
for (Map.Entry<UUID, Rating> entry : p2.getRatings().entrySet()) {
31+
double av = entry.getValue().getAverageRating();
32+
v2 += av * av;
33+
}
34+
v2 /= p2s;
35+
v2 += p2s;
36+
}
37+
if (v2 == v1 && v2 != 0) {
38+
return p2s - p1s;
39+
}
40+
return (int) Math.signum(v2 - v1);
41+
}
42+
43+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.plotsquared.core.util.comparator;
2+
3+
import com.plotsquared.core.plot.Plot;
4+
import com.plotsquared.core.plot.PlotArea;
5+
6+
import javax.annotation.Nullable;
7+
import java.util.Comparator;
8+
9+
public class PlotInPrioritizedAreaComparator implements Comparator<Plot> {
10+
11+
private final PlotArea priorityArea;
12+
13+
public PlotInPrioritizedAreaComparator(@Nullable final PlotArea area) {
14+
this.priorityArea = area;
15+
}
16+
17+
@Override
18+
public int compare(final Plot first, final Plot second) {
19+
if (this.priorityArea == null) {
20+
return 0; // no defined priority? don't sort
21+
}
22+
if (this.priorityArea.equals(first.getArea())) {
23+
return -1;
24+
}
25+
if (this.priorityArea.equals(second.getArea())) {
26+
return 1;
27+
}
28+
return 0; // same area, don't sort
29+
}
30+
31+
}

Core/src/main/java/com/plotsquared/core/util/query/PlotProvider.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ public boolean hasNext() {
5454

5555
@Override
5656
public Plot next() {
57-
if (currentAreaPlots == null) {
58-
currentAreaPlots = areas[++areaIndex].getPlots().iterator();
59-
}
6057
return currentAreaPlots.next();
6158
}
6259
}, Spliterator.IMMUTABLE), false);

Core/src/main/java/com/plotsquared/core/util/query/PlotQuery.java

Lines changed: 46 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
import com.plotsquared.core.player.PlotPlayer;
2424
import com.plotsquared.core.plot.Plot;
2525
import com.plotsquared.core.plot.PlotArea;
26-
import com.plotsquared.core.plot.Rating;
27-
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
2826
import com.plotsquared.core.plot.world.PlotAreaManager;
29-
import com.plotsquared.core.util.MathMan;
27+
import com.plotsquared.core.util.comparator.PlotByDoneComparator;
28+
import com.plotsquared.core.util.comparator.PlotByRatingComparator;
29+
import com.plotsquared.core.util.comparator.PlotByCreationDateComparator;
30+
import com.plotsquared.core.util.comparator.PlotInPrioritizedAreaComparator;
3031
import org.checkerframework.checker.nullness.qual.NonNull;
3132

3233
import java.util.ArrayList;
@@ -37,7 +38,6 @@
3738
import java.util.Iterator;
3839
import java.util.LinkedList;
3940
import java.util.List;
40-
import java.util.Map;
4141
import java.util.Set;
4242
import java.util.UUID;
4343
import java.util.function.Predicate;
@@ -308,7 +308,15 @@ public static PlotQuery newQuery() {
308308
* @return Matching plots
309309
*/
310310
public @NonNull Stream<Plot> asStream() {
311-
return this.asList().stream(); // TODO: use stream functionality from PlotProvider?
311+
Stream<Plot> stream = this.plotProvider.streamPlots().filter(testPlotAgainstFilters());
312+
if (this.sortingStrategy == SortingStrategy.NO_SORTING) {
313+
return stream;
314+
}
315+
stream = stream.sorted(getConfiguredComparator());
316+
if (this.priorityArea != null) {
317+
stream = stream.sorted(new PlotInPrioritizedAreaComparator(this.priorityArea));
318+
}
319+
return stream;
312320
}
313321

314322
/**
@@ -335,49 +343,10 @@ public static PlotQuery newQuery() {
335343
}
336344
if (this.sortingStrategy == SortingStrategy.NO_SORTING) {
337345
return result;
338-
} else if (this.sortingStrategy == SortingStrategy.SORT_BY_TEMP) {
339-
return PlotSquared.get().sortPlotsByTemp(result);
340-
} else if (this.sortingStrategy == SortingStrategy.SORT_BY_DONE) {
341-
result.sort((a, b) -> {
342-
String va = a.getFlag(DoneFlag.class);
343-
String vb = b.getFlag(DoneFlag.class);
344-
if (MathMan.isInteger(va)) {
345-
if (MathMan.isInteger(vb)) {
346-
return Integer.parseInt(vb) - Integer.parseInt(va);
347-
}
348-
return -1;
349-
}
350-
return 1;
351-
});
352-
} else if (this.sortingStrategy == SortingStrategy.SORT_BY_RATING) {
353-
result.sort((p1, p2) -> {
354-
double v1 = 0;
355-
int p1s = p1.getSettings().getRatings().size();
356-
int p2s = p2.getRatings().size();
357-
if (!p1.getSettings().getRatings().isEmpty()) {
358-
v1 = p1.getRatings().values().stream().mapToDouble(Rating::getAverageRating)
359-
.map(av -> av * av).sum();
360-
v1 /= p1s;
361-
v1 += p1s;
362-
}
363-
double v2 = 0;
364-
if (!p2.getSettings().getRatings().isEmpty()) {
365-
for (Map.Entry<UUID, Rating> entry : p2.getRatings().entrySet()) {
366-
double av = entry.getValue().getAverageRating();
367-
v2 += av * av;
368-
}
369-
v2 /= p2s;
370-
v2 += p2s;
371-
}
372-
if (v2 == v1 && v2 != 0) {
373-
return p2s - p1s;
374-
}
375-
return (int) Math.signum(v2 - v1);
376-
});
377-
} else if (this.sortingStrategy == SortingStrategy.SORT_BY_CREATION) {
378-
return PlotSquared.get().sortPlots(result, PlotSquared.SortType.CREATION_DATE, this.priorityArea);
379-
} else if (this.sortingStrategy == SortingStrategy.COMPARATOR) {
380-
result.sort(this.plotComparator);
346+
}
347+
result.sort(getConfiguredComparator());
348+
if (this.priorityArea != null) {
349+
result.sort(new PlotInPrioritizedAreaComparator(this.priorityArea));
381350
}
382351
return result;
383352
}
@@ -443,14 +412,13 @@ public boolean anyMatch() {
443412
* @since TODO
444413
*/
445414
public boolean hasMinimumMatches(int minimum) {
446-
return this.plotProvider.streamPlots().filter(plot -> {
447-
for (final PlotFilter filter : filters) {
448-
if (!filter.accepts(plot)) {
449-
return false;
450-
}
451-
}
452-
return true;
453-
}).limit(minimum).count() == minimum;
415+
return this.plotProvider.streamPlots().filter(testPlotAgainstFilters()).limit(minimum).count() == minimum;
416+
}
417+
418+
@NonNull
419+
@Override
420+
public Iterator<Plot> iterator() {
421+
return this.asCollection().iterator();
454422
}
455423

456424
@NonNull
@@ -459,10 +427,28 @@ private PlotQuery addFilter(final @NonNull PlotFilter filter) {
459427
return this;
460428
}
461429

462-
@NonNull
463-
@Override
464-
public Iterator<Plot> iterator() {
465-
return this.asCollection().iterator();
430+
private Comparator<Plot> getConfiguredComparator() {
431+
return switch (sortingStrategy) {
432+
case NO_SORTING -> (p1, p2) -> 0;
433+
case SORT_BY_TEMP, SORT_BY_CREATION -> PlotByCreationDateComparator.INSTANCE;
434+
case SORT_BY_DONE -> PlotByDoneComparator.INSTANCE;
435+
case SORT_BY_RATING -> PlotByRatingComparator.INSTANCE;
436+
case COMPARATOR -> plotComparator;
437+
};
438+
}
439+
440+
private Predicate<Plot> testPlotAgainstFilters() {
441+
if (this.filters.isEmpty()) {
442+
return plot -> true;
443+
}
444+
return plot -> {
445+
for (final PlotFilter filter : filters) {
446+
if (!filter.accepts(plot)) {
447+
return false;
448+
}
449+
}
450+
return true;
451+
};
466452
}
467453

468454
}

0 commit comments

Comments
 (0)