diff options
| author | shedaniel <daniel@shedaniel.me> | 2023-05-29 14:13:31 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-05-29 14:13:31 +0800 |
| commit | c2d352636f871631b1f4d4622b6c28daffef5541 (patch) | |
| tree | da7ddce0947e3e2c7879ee6cf8be364f49d16edf | |
| parent | 8e0aafdf9e16688117bd57e14824d664eb816fa0 (diff) | |
| parent | 5996c704a0e9312aa02d4d835a59f5efc3ac8b43 (diff) | |
| download | RoughlyEnoughItems-c2d352636f871631b1f4d4622b6c28daffef5541.tar.gz RoughlyEnoughItems-c2d352636f871631b1f4d4622b6c28daffef5541.tar.bz2 RoughlyEnoughItems-c2d352636f871631b1f4d4622b6c28daffef5541.zip | |
Merge remote-tracking branch 'shedaniel/9.x-1.19' into 10.x-1.19.3
# Conflicts:
# runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java
25 files changed, 590 insertions, 363 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java b/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java index f94266447..7fb37e351 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java @@ -26,6 +26,7 @@ package me.shedaniel.rei.api.client.search; import me.shedaniel.rei.api.common.entry.EntryStack; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import org.jetbrains.annotations.ApiStatus; import java.util.Collection; import java.util.function.Predicate; @@ -80,4 +81,9 @@ public interface SearchFilter extends Predicate<EntryStack<?>> { */ default void prepareFilter(Collection<EntryStack<?>> stacks) { } + + @ApiStatus.Experimental + default boolean test(EntryStack<?> stack, long hashExact) { + return this.test(stack); + } } diff --git a/build.gradle b/build.gradle index 045aacc37..18a3a4456 100755 --- a/build.gradle +++ b/build.gradle @@ -141,7 +141,7 @@ task releaseOnCf { } def time = df.format(new Date()) def changes = new StringBuilder() - changes << "## REI v$project.version for $project.supported_version\nUpdated at **$time**.\n" + changes << "## REI v$project.version for $project.supported_version\nUpdated at **$time**.\n[Click here for changelog](https://www.github.com/shedaniel/RoughlyEnoughItems/commits/$branch)" def proc = "git log --max-count=200 --pretty=format:%s".execute() proc.in.eachLine { line -> def processedLine = line.toString() diff --git a/forge/build.gradle b/forge/build.gradle index 25dd8cc0a..aab987e70 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -76,9 +76,9 @@ dependencies { // modRuntime("curse.maven:immersive-engineering-231951:3721708") // modRuntime("curse.maven:autoreglib-250363:3326041") // modRuntime("curse.maven:ars-nouveau-401955:3814106") - // modRuntime("curse.maven:patchouli-306770:3809917") + // modRuntime("curse.maven:patchouli-306770:3843443") // modRuntime("curse.maven:curios-309927:3748873") - // modRuntime("software.bernie.geckolib:geckolib-1.18-forge:3.0.22") + // modRuntime("software.bernie.geckolib:geckolib-forge-1.18:3.0.57") // modRuntime("curse.maven:little-logistics-570050:3818773") // modRuntime("curse.maven:refined-storage-243076:3623324") // modRuntime("appeng:appliedenergistics2:10.0.1") 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 7c4567f55..83b6e2434 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 @@ -454,7 +454,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 44d972c16..2fbcd2be7 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 @@ -31,6 +31,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..11672222d 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) { 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..5c7836576 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,10 +30,8 @@ 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.util.HashedEntryStackWrapper; import java.util.AbstractMap; import java.util.ArrayList; @@ -46,32 +44,26 @@ 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 ExecutorTuple executor; + private volatile Map.Entry<List<HashedEntryStackWrapper>, SearchFilter> last; + 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; - } - } - - @Nullable - public SearchFilter filter() { - return this.filter; + this.last = null; } - private record ExecutorTuple(SearchFilter filter, CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> future) { + private record ExecutorTuple(SearchFilter filter, + CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> future) { } public void updateFilter(String filter) { @@ -85,12 +77,10 @@ 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()); @@ -107,7 +97,7 @@ public class AsyncSearchManager { }, EXECUTOR_SERVICE))).future(); } - public List<EntryStack<?>> getNow() { + public List<HashedEntryStackWrapper> getNow() { try { return get(Runnable::run).get().getKey(); } catch (ExecutionException e) { @@ -117,18 +107,14 @@ public class AsyncSearchManager { } } - public CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> get(Executor executor) { + public CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> get(Executor executor) { 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) .thenApply(entry -> { - synchronized (AsyncSearchManager.this) { - this.last = entry; - } + this.last = entry; return entry; }); } @@ -136,39 +122,20 @@ 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, + 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) { int searchPartitionSize = ConfigObject.getInstance().getAsyncSearchPartitionSize(); boolean shouldAsync = ConfigObject.getInstance().shouldAsyncSearch() && stacks.size() > searchPartitionSize * 4; 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(); + for (Iterable<HashedEntryStackWrapper> partitionStacks : CollectionUtils.partition(stacks, Math.max(searchPartitionSize, stacks.size() * 3 / Runtime.getRuntime().availableProcessors()))) { 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(); + for (HashedEntryStackWrapper stack : partitionStacks) { + if (stack != null && filter.test(stack.unwrap(), stack.hashExact()) && additionalPredicate.test(stack)) { filtered.add(transformer.apply(stack)); } if (manager.filter != filter) throw new CancellationException(); @@ -176,19 +143,16 @@ public class AsyncSearchManager { return filtered; }, executor)); } - return preparationFuture.thenCompose($ -> CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) - .orTimeout(30, TimeUnit.SECONDS)) + return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) + .orTimeout(90, TimeUnit.SECONDS) .thenApplyAsync($ -> { - List<EntryStack<?>> list = new ArrayList<>(); + List<HashedEntryStackWrapper> list = new ArrayList<>(); - if (manager.filter == filter) { - |
