aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2023-05-31 23:18:11 +0800
committershedaniel <daniel@shedaniel.me>2023-05-31 23:18:11 +0800
commitc749bc8bcbd74404dd9476613838d329e68d10b9 (patch)
tree32529d94f09d9e63de307379844a81817f1291f1 /runtime/src/main
parentd9a1988ccf426c0e76a7377bab7c7ef85e2ef957 (diff)
parentcdfeb35c25de956c29035877ef4043a6e4b2e067 (diff)
downloadRoughlyEnoughItems-c749bc8bcbd74404dd9476613838d329e68d10b9.tar.gz
RoughlyEnoughItems-c749bc8bcbd74404dd9476613838d329e68d10b9.tar.bz2
RoughlyEnoughItems-c749bc8bcbd74404dd9476613838d329e68d10b9.zip
Merge branch '11.x-1.19.4' into 12.x-1.20
Diffstat (limited to 'runtime/src/main')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java13
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java63
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java143
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java28
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/AlternativeArgument.java9
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java258
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/ArgumentCache.java172
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/CompoundArgument.java16
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/collapsed/CollapsedEntriesCache.java85
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/util/ThreadCreator.java30
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java1
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java8
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/FilteredEntryList.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/PreFilteredEntryList.java55
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/collapsed/CollapsibleEntryRegistryImpl.java63
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/util/HashedEntryStackWrapper.java12
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java7
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/DefaultClientRuntimePlugin.java1
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/SearchFilterPrepareWatcher.java19
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/SearchFilterWatcher.java85
-rwxr-xr-xruntime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json2
26 files changed, 714 insertions, 376 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java
index c0b633117..88496cef3 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java
@@ -134,10 +134,11 @@ public class ClientHelperImpl implements ClientHelper {
@Override
public void appendModIdToTooltips(Tooltip components, String modId) {
final String modName = ClientHelper.getInstance().getModFromModId(modId);
+ int i = 0;
Iterator<Tooltip.Entry> iterator = components.entries().iterator();
while (iterator.hasNext()) {
Tooltip.Entry entry = iterator.next();
- if (entry.isText() && FormattingUtils.stripFormatting(entry.getAsText().getString()).equalsIgnoreCase(modName)) {
+ if (entry.isText() && i++ != 0 && FormattingUtils.stripFormatting(entry.getAsText().getString()).equalsIgnoreCase(modName)) {
iterator.remove();
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
index a332dd3b0..640c113ec 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
@@ -73,7 +73,7 @@ public class SearchFilteringRule implements FilteringRule<Unit> {
if (show) processList(context.getHiddenStacks(), completableFutures);
else processList(context.getShownStacks(), completableFutures);
try {
- CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(10, TimeUnit.SECONDS);
+ CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(90, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
index 06a733be5..3d9a308ba 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
@@ -449,7 +449,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen {
}
ExportRecipeIdentifierToast.addToast(I18n.get("msg.rei.exported_recipe"), I18n.get("msg.rei.exported_recipe.desc"));
}
- minecraft.setScreen(DefaultDisplayViewingScreen.this);
+ minecraft.setScreen(null);
}, Component.translatable("text.rei.ask_to_export", tab.categoryName),
Component.translatable("text.rei.ask_to_export.subtitle", categoryMap.getOrDefault(tab.category, Collections.emptyList()).size())));
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java
index a1a1eda3c..f8b2413c2 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java
@@ -30,6 +30,7 @@ import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.ClientHelper;
import me.shedaniel.rei.api.client.REIRuntime;
+import me.shedaniel.rei.api.client.config.ConfigObject;
import me.shedaniel.rei.api.client.gui.Renderer;
import me.shedaniel.rei.api.client.gui.drag.DraggableStack;
import me.shedaniel.rei.api.client.gui.drag.DraggableStackProviderWidget;
@@ -131,10 +132,14 @@ public class TabWidget extends WidgetWithBounds implements DraggableStackProvide
}
private void drawTooltip() {
- if (this.minecraft.options.advancedItemTooltips)
- Tooltip.create(categoryName, Component.literal(category.getIdentifier().toString()).withStyle(ChatFormatting.DARK_GRAY), ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
- else
- Tooltip.create(categoryName, ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
+ Tooltip tooltip = Tooltip.create(categoryName);
+ if (this.minecraft.options.advancedItemTooltips) {
+ tooltip.add(Component.literal(category.getIdentifier().toString()).withStyle(ChatFormatting.DARK_GRAY));
+ }
+ if (ConfigObject.getInstance().shouldAppendModNames()) {
+ tooltip.add(ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier()));
+ }
+ tooltip.queue();
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java
index e877943c6..c23bf2b64 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java
@@ -24,6 +24,7 @@
package me.shedaniel.rei.impl.client.gui.widget.entrylist;
import com.google.common.base.Stopwatch;
+import com.google.common.collect.Iterators;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import me.shedaniel.rei.api.client.config.ConfigManager;
@@ -35,10 +36,14 @@ import me.shedaniel.rei.api.client.view.Views;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.util.EntryStacks;
import me.shedaniel.rei.impl.client.search.AsyncSearchManager;
+import me.shedaniel.rei.impl.client.search.collapsed.CollapsedEntriesCache;
import me.shedaniel.rei.impl.common.InternalLogger;
+import me.shedaniel.rei.impl.common.entry.type.EntryRegistryImpl;
import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsedStack;
import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsibleEntryRegistryImpl;
+import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
import net.minecraft.client.Minecraft;
+import net.minecraft.resources.ResourceLocation;
import org.apache.logging.log4j.Level;
import org.jetbrains.annotations.Nullable;
@@ -47,12 +52,12 @@ import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
public class EntryListSearchManager {
- private static final Comparator<? super EntryStack<?>> ENTRY_NAME_COMPARER = Comparator.comparing(stack -> stack.asFormatStrippedText().getString());
- // private static final Comparator<? super EntryStack<?>> ENTRY_GROUP_COMPARER = VersionAdapter.INSTANCE.getEntryGroupComparator();
+ private static final Comparator<? super HashedEntryStackWrapper> ENTRY_NAME_COMPARER = Comparator.comparing(stack -> stack.unwrap().asFormatStrippedText().getString());
+ // private static final Comparator<? super HashedEntryStackWrapper> ENTRY_GROUP_COMPARER = VersionAdapter.INSTANCE.getEntryGroupComparator();
public static final EntryListSearchManager INSTANCE = new EntryListSearchManager();
- private AsyncSearchManager searchManager = new AsyncSearchManager(EntryRegistry.getInstance()::getPreFilteredList, () -> {
+ private final AsyncSearchManager searchManager = new AsyncSearchManager(((EntryRegistryImpl) EntryRegistry.getInstance())::getPreFilteredComplexList, () -> {
boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled();
LongSet workingItems = checkCraftable ? new LongOpenHashSet() : null;
if (checkCraftable) {
@@ -60,8 +65,8 @@ public class EntryListSearchManager {
workingItems.add(EntryStacks.hashExact(stack));
}
}
- return checkCraftable ? stack -> workingItems.contains(EntryStacks.hashExact(stack)) : stack -> true;
- }, EntryStack::normalize);
+ return checkCraftable ? stack -> workingItems.contains(stack.hashExact()) : stack -> true;
+ }, HashedEntryStackWrapper::normalize);
public void update(String searchTerm, boolean ignoreLastSearch, Consumer<List</*EntryStack<?> | CollapsedStack*/ Object>> update) {
Stopwatch stopwatch = Stopwatch.createStarted();
@@ -70,21 +75,21 @@ public class EntryListSearchManager {
if (searchManager.isDirty()) {
searchManager.getAsync((list, filter) -> {
if (!filter.getFilter().equals(searchTerm)) return;
- if (searchManager.filter() == null || searchManager.filter() != filter) return;
+ if (searchManager.filter == null || searchManager.filter != filter) return;
InternalLogger.getInstance().log(ConfigObject.getInstance().doDebugSearchTimeRequired() ? Level.INFO : Level.TRACE, "Search \"%s\" Used [%s]: %s", filter.getFilter(), Thread.currentThread().toString(), stopwatch.toString());
- List</*EntryStack<?> | CollapsedStack*/ Object> finalList = collapse(copyAndOrder(list), () -> searchManager.filter() != null && searchManager.filter() == filter);
+ List</*EntryStack<?> | CollapsedStack*/ Object> finalList = collapse(copyAndOrder(list), () -> searchManager.filter != null && searchManager.filter == filter);
InternalLogger.getInstance().log(ConfigObject.getInstance().doDebugSearchTimeRequired() ? Level.INFO : Level.TRACE, "Search \"%s\" Used and Applied [%s]: %s", filter.getFilter(), Thread.currentThread().toString(), stopwatch.stop().toString());
Minecraft.getInstance().submit(() -> {
- if (searchManager.filter() == null || searchManager.filter() != filter) return;
+ if (searchManager.filter == null || searchManager.filter != filter) return;
update.accept(finalList);
});
});
}
}
- private List<EntryStack<?>> copyAndOrder(List<EntryStack<?>> list) {
+ private List<HashedEntryStackWrapper> copyAndOrder(List<HashedEntryStackWrapper> list) {
list = new ArrayList<>(list);
EntryPanelOrdering ordering = ConfigObject.getInstance().getItemListOrdering();
if (ordering == EntryPanelOrdering.NAME)
@@ -98,7 +103,7 @@ public class EntryListSearchManager {
return list;
}
- private List</*EntryStack<?> | CollapsedStack*/ Object> collapse(List<EntryStack<?>> stacks, BooleanSupplier isValid) {
+ private List</*EntryStack<?> | CollapsedStack*/ Object> collapse(List<HashedEntryStackWrapper> stacks, BooleanSupplier isValid) {
CollapsibleEntryRegistryImpl collapsibleRegistry = (CollapsibleEntryRegistryImpl) CollapsibleEntryRegistry.getInstance();
Map<CollapsibleEntryRegistryImpl.Entry, @Nullable CollapsedStack> entries = new HashMap<>();
@@ -106,20 +111,46 @@ public class EntryListSearchManager {
entries.put(entry, null);
}
+ if (entries.isEmpty()) return (List<Object>) (List<?>) new AbstractList<EntryStack<?>>() {
+
+ @Override
+ public int size() {
+ return stacks.size();
+ }
+
+ @Override
+ public EntryStack<?> get(int i) {
+ return stacks.get(i).unwrap();
+ }
+
+ @Override
+ public Iterator<EntryStack<?>> iterator() {
+ return Iterators.transform(stacks.iterator(), HashedEntryStackWrapper::unwrap);
+ }
+ };
if (!isValid.getAsBoolean()) return List.of();
- List</*EntryStack<?> | CollapsedStack*/ Object> list = new ArrayList<>();
+ List</*EntryStack<?> | CollapsedStack*/ Object> list = new ArrayList<>(stacks.size() + 10);
int i = 0;
- for (EntryStack<?> stack : stacks) {
- long hashExact = EntryStacks.hashExact(stack);
+ for (HashedEntryStackWrapper wrapper : stacks) {
+ long hashExact = wrapper.hashExact();
+ EntryStack<?> stack = wrapper.unwrap();
boolean matchedAny = false;
+ Set<ResourceLocation> locations = CollapsedEntriesCache.getInstance().getEntries(hashExact);
for (Map.Entry<CollapsibleEntryRegistryImpl.Entry, @Nullable CollapsedStack> mapEntry : entries.entrySet()) {
CollapsibleEntryRegistryImpl.Entry entry = mapEntry.getKey();
+ boolean matches;
+
+ if (!entry.canCache()) {
+ matches = entry.getMatcher().matches(stack, hashExact);
+ } else {
+ matches = locations != null && locations.contains(entry.getId());
+ }
- if (entry.getMatcher().matches(stack, hashExact)) {
+ if (matches) {
CollapsedStack collapsed = mapEntry.getValue();
if (collapsed == null) {
@@ -146,6 +177,10 @@ public class EntryListSearchManager {
return list;
}
+ public AsyncSearchManager getSearchManager() {
+ return searchManager;
+ }
+
public boolean matches(EntryStack<?> stack) {
return searchManager.matches(stack);
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java
index 9391660c6..e039ad7e9 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java
@@ -54,9 +54,9 @@ public class OverlaySearchFieldSyntaxHighlighter implements Consumer<String> {
}
@Override
- public void addPart(Argument<?, ?> argument, boolean usingGrammar, Collection<IntRange> grammarRanges, int index) {
+ public void addPart(Argument.Builder<?, ?> argument, boolean usingGrammar, Collection<IntRange> grammarRanges, int index) {
if (usingGrammar) {
- int argIndex = ArgumentTypesRegistry.ARGUMENT_TYPE_LIST.indexOf(argument.getArgument()) * 2 + 1;
+ int argIndex = ArgumentTypesRegistry.ARGUMENT_TYPE_LIST.indexOf(argument.getType()) * 2 + 1;
for (int i = argument.start(); i < argument.end(); i++) {
highlighted[i] = (byte) argIndex;
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
index 8e5d76d97..85053fb73 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
@@ -63,9 +63,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
@Environment(EnvType.CLIENT)
public class ScreenRegistryImpl implements ScreenRegistry {
private Multimap<Class<? extends Screen>, ClickArea<?>> clickAreas = HashMultimap.create();
- private List<DraggableComponentProvider<Screen, Object>> draggableProviders = new ArrayList<>();
- private List<DraggableComponentVisitor<Screen>> draggableVisitors = new ArrayList<>();
- private List<FocusedStackProvider> focusedStackProviders = new ArrayList<>();
+ private List<DraggableComponentProvider<Screen, Object>> draggableProviders = new CopyOnWriteArrayList<>();
+ private List<DraggableComponentVisitor<Screen>> draggableVisitors = new CopyOnWriteArrayList<>();
+ private List<FocusedStackProvider> focusedStackProviders = new CopyOnWriteArrayList<>();
private List<OverlayDecider> deciders = new CopyOnWriteArrayList<>();
private Map<Class<?>, List<OverlayDecider>> cache = new HashMap<>();
private ExclusionZones exclusionZones = new ExclusionZonesImpl();
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
index 9d418453c..c1ab15fba 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
@@ -30,48 +30,50 @@ import me.shedaniel.rei.api.client.search.SearchFilter;
import me.shedaniel.rei.api.client.search.SearchProvider;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.util.CollectionUtils;
-import me.shedaniel.rei.impl.client.search.argument.Argument;
-import me.shedaniel.rei.impl.client.search.argument.type.ArgumentType;
import me.shedaniel.rei.impl.client.util.ThreadCreator;
-import org.jetbrains.annotations.Nullable;
+import me.shedaniel.rei.impl.common.InternalLogger;
+import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
+import net.minecraft.Util;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
public class AsyncSearchManager {
- private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-AsyncSearchManager").asService();
- private final Supplier<List<EntryStack<?>>> stacksProvider;
- private final Supplier<Predicate<EntryStack<?>>> additionalPredicateSupplier;
- private final UnaryOperator<EntryStack<?>> transformer;
- private ExecutorTuple executor;
- private SearchFilter filter;
- private Map.Entry<List<EntryStack<?>>, SearchFilter> last;
+ private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-AsyncSearchManager").asService(Math.min(3, Runtime.getRuntime().availableProcessors()));
+ private final Supplier<List<HashedEntryStackWrapper>> stacksProvider;
+ private final Supplier<Predicate<HashedEntryStackWrapper>> additionalPredicateSupplier;
+ private final UnaryOperator<HashedEntryStackWrapper> transformer;
+ private volatile Map.Entry<List<HashedEntryStackWrapper>, SearchFilter> last;
+ public volatile ExecutorTuple executor;
+ public volatile SearchFilter filter;
- public AsyncSearchManager(Supplier<List<EntryStack<?>>> stacksProvider, Supplier<Predicate<EntryStack<?>>> additionalPredicateSupplier, UnaryOperator<EntryStack<?>> transformer) {
+ public AsyncSearchManager(Supplier<List<HashedEntryStackWrapper>> stacksProvider, Supplier<Predicate<HashedEntryStackWrapper>> additionalPredicateSupplier, UnaryOperator<HashedEntryStackWrapper> transformer) {
this.stacksProvider = stacksProvider;
this.additionalPredicateSupplier = additionalPredicateSupplier;
this.transformer = transformer;
}
public void markDirty() {
- synchronized (AsyncSearchManager.this) {
- this.last = null;
- }
+ this.last = null;
}
- @Nullable
- public SearchFilter filter() {
- return this.filter;
+ public record ExecutorTuple(SearchFilter filter,
+ CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> future,
+ Steps steps) {
}
- private record ExecutorTuple(SearchFilter filter, CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> future) {
+ public static class Steps {
+ public long startTime = 0;
+ public AtomicInteger partitionsDone = new AtomicInteger(0);
+ public int totalPartitions = 0;
}
public void updateFilter(String filter) {
@@ -85,17 +87,16 @@ public class AsyncSearchManager {
}
public boolean isDirty() {
- synchronized (AsyncSearchManager.this) {
- return this.last == null || this.last.getValue() != this.filter;
- }
+ return this.last == null || this.last.getValue() != this.filter;
}
- public Future<?> getAsync(BiConsumer<List<EntryStack<?>>, SearchFilter> consumer) {
+ public Future<?> getAsync(BiConsumer<List<HashedEntryStackWrapper>, SearchFilter> consumer) {
if (this.executor == null || this.executor.filter() != filter || isDirty()) {
if (this.executor != null) {
this.executor.future().cancel(Platform.isFabric());
}
- this.executor = new ExecutorTuple(filter, get(EXECUTOR_SERVICE));
+ Steps steps = new Steps();
+ this.executor = new ExecutorTuple(filter, get(EXECUTOR_SERVICE, steps), steps);
}
SearchFilter savedFilter = filter;
return (this.executor = new ExecutorTuple(this.executor.filter(), this.executor.future().thenApplyAsync(result -> {
@@ -104,12 +105,12 @@ public class AsyncSearchManager {
}
return result;
- }, EXECUTOR_SERVICE))).future();
+ }, EXECUTOR_SERVICE), executor.steps)).future();
}
- public List<EntryStack<?>> getNow() {
+ public List<HashedEntryStackWrapper> getNow() {
try {
- return get(Runnable::run).get().getKey();
+ return get(Runnable::run, new Steps()).get().getKey();
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InterruptedException | CancellationException e) {
@@ -117,18 +118,14 @@ public class AsyncSearchManager {
}
}
- public CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> get(Executor executor) {
+ public CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> get(Executor executor, Steps steps) {
if (isDirty()) {
- Map.Entry<List<EntryStack<?>>, SearchFilter> last;
- synchronized (AsyncSearchManager.this) {
- last = this.last;
- }
+ Map.Entry<List<HashedEntryStackWrapper>, SearchFilter> last;
+ last = this.last;
return get(this.filter, this.additionalPredicateSupplier.get(), this.transformer,
- this.stacksProvider.get(), last, this, executor)
+ this.stacksProvider.get(), last, this, executor, steps)
.thenApply(entry -> {
- synchronized (AsyncSearchManager.this) {
- this.last = entry;
- }
+ this.last = entry;
return entry;
});
}
@@ -136,59 +133,46 @@ public class AsyncSearchManager {
return CompletableFuture.completedFuture(last);
}
- public static CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> get(SearchFilter filter, Predicate<EntryStack<?>> additionalPredicate,
- UnaryOperator<EntryStack<?>> transformer, List<EntryStack<?>> stacks, Map.Entry<List<EntryStack<?>>, SearchFilter> last,
- AsyncSearchManager manager, Executor executor) {
+ public static CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> get(SearchFilter filter, Predicate<HashedEntryStackWrapper> additionalPredicate,
+ UnaryOperator<HashedEntryStackWrapper> transformer, List<HashedEntryStackWrapper> stacks, Map.Entry<List<HashedEntryStackWrapper>, SearchFilter> last,
+ AsyncSearchManager manager, Executor executor, Steps steps) {
int searchPartitionSize = ConfigObject.getInstance().getAsyncSearchPartitionSize();
boolean shouldAsync = ConfigObject.getInstance().shouldAsyncSearch() && stacks.size() > searchPartitionSize * 4;
+ InternalLogger.getInstance().debug("Starting Search: \"" + filter.getFilter() + "\" with " + stacks.size() + " stacks, shouldAsync: " + shouldAsync + " on " + Thread.currentThread().getName());
if (!stacks.isEmpty()) {
- CompletableFuture<Void> preparationFuture = CompletableFuture.completedFuture(null);
-
- if (last == null || last.getValue() != filter) {
- Runnable prepare = () -> {
- if (manager.filter == filter) {
- List<ArgumentType<?, ?>> argumentTypes = ((SearchProviderImpl.SearchFilterImpl) filter).getArgumentTypes();
- Argument.prepareFilter(stacks, argumentTypes, () -> manager.filter() != null && manager.filter() == filter, executor);
- } else {
- throw new CancellationException();
- }
- };
- if (shouldAsync) {
- preparationFuture = CompletableFuture.runAsync(prepare, executor);
- } else {
- prepare.run();
- preparationFuture = CompletableFuture.completedFuture(null);
- }
- }
-
if (shouldAsync) {
- List<CompletableFuture<List<EntryStack<?>>>> futures = Lists.newArrayList();
- for (Iterable<EntryStack<?>> partitionStacks : CollectionUtils.partition(stacks, Math.max(searchPartitionSize, stacks.size() * 3 / Runtime.getRuntime().availableProcessors()))) {
+ List<CompletableFuture<List<HashedEntryStackWrapper>>> futures = Lists.newArrayList();
+ int partitions = 0;
+ for (Iterable<HashedEntryStackWrapper> partitionStacks : CollectionUtils.partition(stacks, searchPartitionSize * 4)) {
+ final int finalPartitions = partitions;
futures.add(CompletableFuture.supplyAsync(() -> {
- List<EntryStack<?>> filtered = Lists.newArrayList();
- for (EntryStack<?> stack : partitionStacks) {
- if (stack != null && filter.test(stack) && additionalPredicate.test(stack)) {
+ List<HashedEntryStackWrapper> filtered = Lists.newArrayList();
+ if (manager.filter != filter) throw new CancellationException();
+ for (HashedEntryStackWrapper stack : partitionStacks) {
+ if (stack != null && test(filter, stack.unwrap(), stack.hashExact()) && additionalPredicate.test(stack)) {
filtered.add(transformer.apply(stack));
}
if (manager.filter != filter) throw new CancellationException();
}
+ steps.partitionsDone.incrementAndGet();
return filtered;
}, executor));
+ partitions++;
}
- return preparationFuture.thenCompose($ -> CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
- .orTimeout(30, TimeUnit.SECONDS))
+ steps.startTime = Util.getEpochMillis();
+ steps.totalPartitions = partitions;
+ InternalLogger.getInstance().debug("Async Search: " + partitions + " partitions for \"" + filter.getFilter() + "\"");
+ return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
+