diff options
| author | shedaniel <daniel@shedaniel.me> | 2023-05-30 04:28:31 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-05-30 04:28:31 +0800 |
| commit | 981d975f0e1ddff61bfedd0d45ecbe0803372d8e (patch) | |
| tree | 3eb69445b8ccaf76054b5d2e21358e585d005bb4 /runtime/src/main/java/me/shedaniel/rei/impl/client | |
| parent | d0f07b4adfbd6a8e7424b821cda0143eba401ae9 (diff) | |
| parent | af164bc5db24d46f129ddfca6388e748267f6cce (diff) | |
| download | RoughlyEnoughItems-981d975f0e1ddff61bfedd0d45ecbe0803372d8e.tar.gz RoughlyEnoughItems-981d975f0e1ddff61bfedd0d45ecbe0803372d8e.tar.bz2 RoughlyEnoughItems-981d975f0e1ddff61bfedd0d45ecbe0803372d8e.zip | |
Merge remote-tracking branch 'shedaniel/9.x-1.19' into 10.x-1.19.3
Diffstat (limited to 'runtime/src/main/java/me/shedaniel/rei/impl/client')
6 files changed, 55 insertions, 32 deletions
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 11672222d..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 @@ -177,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/search/AsyncSearchManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java index 5c7836576..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 @@ -31,13 +31,16 @@ 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.util.ThreadCreator; +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; @@ -48,8 +51,8 @@ public class AsyncSearchManager { 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 ExecutorTuple executor; public volatile SearchFilter filter; public AsyncSearchManager(Supplier<List<HashedEntryStackWrapper>> stacksProvider, Supplier<Predicate<HashedEntryStackWrapper>> additionalPredicateSupplier, UnaryOperator<HashedEntryStackWrapper> transformer) { @@ -62,8 +65,15 @@ public class AsyncSearchManager { this.last = null; } - private record ExecutorTuple(SearchFilter filter, - CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> future) { + public record ExecutorTuple(SearchFilter filter, + CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> future, + Steps steps) { + } + + public static class Steps { + public long startTime = 0; + public AtomicInteger partitionsDone = new AtomicInteger(0); + public int totalPartitions = 0; } public void updateFilter(String filter) { @@ -85,7 +95,8 @@ public class AsyncSearchManager { 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 -> { @@ -94,12 +105,12 @@ public class AsyncSearchManager { } return result; - }, EXECUTOR_SERVICE))).future(); + }, EXECUTOR_SERVICE), executor.steps)).future(); } 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) { @@ -107,12 +118,12 @@ public class AsyncSearchManager { } } - public CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> get(Executor executor) { + public CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> get(Executor executor, Steps steps) { if (isDirty()) { 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 -> { this.last = entry; return entry; @@ -124,25 +135,34 @@ public class AsyncSearchManager { 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) { + 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()) { if (shouldAsync) { List<CompletableFuture<List<HashedEntryStackWrapper>>> futures = Lists.newArrayList(); - for (Iterable<HashedEntryStackWrapper> partitionStacks : CollectionUtils.partition(stacks, Math.max(searchPartitionSize, stacks.size() * 3 / Runtime.getRuntime().availableProcessors()))) { + int partitions = 0; + for (Iterable<HashedEntryStackWrapper> partitionStacks : CollectionUtils.partition(stacks, searchPartitionSize * 4)) { + final int finalPartitions = partitions; futures.add(CompletableFuture.supplyAsync(() -> { List<HashedEntryStackWrapper> filtered = Lists.newArrayList(); + if (manager.filter != filter) throw new CancellationException(); for (HashedEntryStackWrapper stack : partitionStacks) { - if (stack != null && filter.test(stack.unwrap(), stack.hashExact()) && additionalPredicate.test(stack)) { + 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++; } + 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])) .orTimeout(90, TimeUnit.SECONDS) .thenApplyAsync($ -> { @@ -163,7 +183,7 @@ public class AsyncSearchManager { List<HashedEntryStackWrapper> list = new ArrayList<>(); for (HashedEntryStackWrapper stack : stacks) { - if (filter.test(stack.unwrap(), stack.hashExact()) && additionalPredicate.test(stack)) { + if (test(filter, stack.unwrap(), stack.hashExact()) && additionalPredicate.test(stack)) { list.add(transformer.apply(stack)); } if (manager.filter != filter) throw new CancellationException(); @@ -176,6 +196,15 @@ public class AsyncSearchManager { return CompletableFuture.completedFuture(new AbstractMap.SimpleImmutableEntry<>(Lists.newArrayList(), filter)); } + private static boolean test(SearchFilter filter, EntryStack<?> stack, long hashExact) { + try { + return filter.test(stack, hashExact); + } catch (Throwable throwable) { + InternalLogger.getInstance().debug("Error while testing filter", throwable); + return false; + } + } + public boolean matches(EntryStack<?> stack) { return filter.test(stack); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java index c19d3f0c1..6b1205d63 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java @@ -34,11 +34,8 @@ import me.shedaniel.rei.impl.client.search.argument.AlternativeArgument; import me.shedaniel.rei.impl.client.search.argument.Argument; import me.shedaniel.rei.impl.client.search.argument.CompoundArgument; import me.shedaniel.rei.impl.client.search.argument.type.ArgumentType; -import me.shedaniel.rei.impl.client.util.CrashReportUtils; import me.shedaniel.rei.impl.common.InternalLogger; import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper; -import net.minecraft.CrashReport; -import net.minecraft.CrashReportCategory; import java.util.Collection; import java.util.List; @@ -72,7 +69,7 @@ public class SearchProviderImpl implements SearchProvider { .map(Argument::getArgument) .distinct() .collect(Collectors.toList())); - InternalLogger.getInstance().debug("Created search filter with %s using %s", filter, inputMethod.getName().getString()); + InternalLogger.getInstance().debug("Created search filter with \"%s\" using %s", filter, inputMethod.getName().getString()); } @Override @@ -80,14 +77,7 @@ public class SearchProviderImpl implements SearchProvider { try { return Argument.matches(stack, hashExact, arguments.get(), inputMethod); } catch (Throwable throwable) { - CrashReport report = CrashReportUtils.essential(throwable, "Testing entry with search filter"); - CrashReportCategory category = report.addCategory("Search entry details"); - try { - stack.fillCrashReport(report, category); - } catch (Throwable throwable1) { - category.setDetailError("Filling Report", throwable1); - } - throw CrashReportUtils.throwReport(report); + throw new RuntimeException("Failed to test search filter: \"" + filter + "\" with stack [" + stack.getType().getIdentifier() + "@" + stack.getIdentifier() + "!" + stack.getValue() + "]", throwable); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java index 7b8dc7d18..bd5034aa3 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java @@ -55,7 +55,7 @@ import java.util.regex.Pattern; @ApiStatus.Internal @Environment(EnvType.CLIENT) public class Argument<T, R> { - private static final Object NO_CACHE = new Object(); + public static final Object NO_CACHE = new Object(); private static final AtomicReference<String> LAST_LANGUAGE = new AtomicReference<>(); public static ArgumentCache cache = new ArgumentCache(); private final ArgumentType<T, R> argumentType; @@ -81,13 +81,13 @@ public class Argument<T, R> { Collection<HashedEntryStackWrapper> stacks = new AbstractCollection<>() { @Override public Iterator<HashedEntryStackWrapper> iterator() { - return Iterators.transform(((EntryRegistryImpl) EntryRegistry.getInstance()).getPreFilteredComplexList().iterator(), + return Iterators.transform(((EntryRegistryImpl) EntryRegistry.getInstance()).getComplexList().iterator(), HashedEntryStackWrapper::normalize); } @Override public int size() { - return EntryRegistry.getInstance().getPreFilteredList().size(); + return ((EntryRegistryImpl) EntryRegistry.getInstance()).getComplexList().size(); } }; if (cache) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/ArgumentCache.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/ArgumentCache.java index d0a443d3c..033331360 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/ArgumentCache.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/ArgumentCache.java @@ -134,10 +134,10 @@ public class ArgumentCache { Long2ObjectMap<Object> out = new Long2ObjectArrayMap<>(stacks.size() + 1); for (HashedEntryStackWrapper stack : stacks) { if (cacheMap.get(stack.hashExact()) == null) { - Object data = argumentType.cacheData(stack.unwrap()); - - if (data != null) { - out.put(stack.hashExact(), data); + try { + Object data = argumentType.cacheData(stack.unwrap()); + out.put(stack.hashExact(), data == null ? Argument.NO_CACHE : data); + } catch (Throwable ignored) { } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/util/ThreadCreator.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/util/ThreadCreator.java index d49b7c2cd..d373cee44 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/util/ThreadCreator.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/util/ThreadCreator.java @@ -54,7 +54,7 @@ public final class ThreadCreator { public ExecutorService asService(int poolSize) { return new ForkJoinPool(poolSize, pool -> { ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool); - worker.setName(group().getName() + "-" + worker.getPoolIndex()); + worker.setName(group().getName() + "-" + threadId().getAndIncrement()); worker.setContextClassLoader(getClass().getClassLoader()); return worker; }, ($, exception) -> { |
