From 67f20e0233abc67f7743554deb486049e8a88e1c Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 20 Nov 2021 18:24:52 +0800 Subject: Fix duplicate items with CC Tweaked --- .../impl/common/entry/type/EntryRegistryImpl.java | 96 ++++++++++++++++------ 1 file changed, 69 insertions(+), 27 deletions(-) (limited to 'runtime/src/main/java') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java index 346cbb8ea..136429680 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java @@ -26,6 +26,8 @@ package me.shedaniel.rei.impl.common.entry.type; import com.google.common.base.MoreObjects; import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import it.unimi.dsi.fastutil.longs.LongSet; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigObject; @@ -69,6 +71,7 @@ public class EntryRegistryImpl implements EntryRegistry { public List refilterListener = Lists.newCopyOnWriteArrayList(); private List> preFilteredList = Lists.newCopyOnWriteArrayList(); private List> entries = Lists.newCopyOnWriteArrayList(); + private LongSet entriesHash = new LongOpenHashSet(); @Nullable private List reloadingRegistry; private boolean reloading; @@ -87,6 +90,7 @@ public class EntryRegistryImpl implements EntryRegistry { public void startReload() { refilterListener.clear(); entries = Lists.newCopyOnWriteArrayList(); + entriesHash = new LongOpenHashSet(); reloadingRegistry = Lists.newArrayListWithCapacity(Registry.ITEM.keySet().size() + 100); preFilteredList = Lists.newCopyOnWriteArrayList(); reloading = true; @@ -186,16 +190,19 @@ public class EntryRegistryImpl implements EntryRegistry { public void addEntryAfter(@Nullable EntryStack afterEntry, EntryStack stack) { if (reloading) { int index = afterEntry != null ? reloadingRegistry.lastIndexOf(new HashedEntryStackWrapper(afterEntry)) : -1; - if (index >= 0) { - reloadingRegistry.add(index, new HashedEntryStackWrapper(stack)); - } else reloadingRegistry.add(new HashedEntryStackWrapper(stack)); - } else { - preFilteredList.addAll(refilterNew(Collections.singletonList(stack))); - queueSearchUpdate(); + HashedEntryStackWrapper wrapper = new HashedEntryStackWrapper(stack); + if (this.entriesHash.add(wrapper.hashExact())) { + if (index >= 0) { + reloadingRegistry.add(index, wrapper); + } else reloadingRegistry.add(wrapper); + } + } else if (this.entriesHash.add(EntryStacks.hashExact(stack))) { if (afterEntry != null) { int index = entries.lastIndexOf(afterEntry); entries.add(index, stack); } else entries.add(stack); + preFilteredList.addAll(refilterNew(Collections.singletonList(stack))); + queueSearchUpdate(); } } @@ -203,16 +210,18 @@ public class EntryRegistryImpl implements EntryRegistry { public void addEntriesAfter(@Nullable EntryStack afterEntry, Collection> stacks) { if (reloading) { int index = afterEntry != null ? reloadingRegistry.lastIndexOf(new HashedEntryStackWrapper(afterEntry)) : -1; + List filtered = CollectionUtils.mapAndFilter(stacks, wrapper -> entriesHash.add(wrapper.hashExact()), HashedEntryStackWrapper::new); if (index >= 0) { - reloadingRegistry.addAll(index, CollectionUtils.mapParallel(stacks, HashedEntryStackWrapper::new)); - } else reloadingRegistry.addAll(CollectionUtils.mapParallel(stacks, HashedEntryStackWrapper::new)); + reloadingRegistry.addAll(index, filtered); + } else reloadingRegistry.addAll(filtered); } else { - preFilteredList.addAll(refilterNew((Collection>) stacks)); - queueSearchUpdate(); + List> filtered = CollectionUtils.filterToList((Collection>) stacks, stack -> entriesHash.add(EntryStacks.hashExact(stack))); if (afterEntry != null) { int index = entries.lastIndexOf(afterEntry); - entries.addAll(index, stacks); - } else entries.addAll(stacks); + entries.addAll(index, filtered); + } else entries.addAll(filtered); + preFilteredList.addAll(refilterNew(filtered)); + queueSearchUpdate(); } } @@ -255,49 +264,82 @@ public class EntryRegistryImpl implements EntryRegistry { @Override public boolean alreadyContain(EntryStack stack) { - if (reloading) { - return reloadingRegistry.parallelStream().anyMatch(s -> EntryStacks.equalsExact(s.unwrap(), stack)); - } - return entries.parallelStream().anyMatch(s -> EntryStacks.equalsExact(s, stack)); + return entriesHash.contains(EntryStacks.hashExact(stack)); } @Override public boolean removeEntry(EntryStack stack) { if (reloading) { - return reloadingRegistry.remove(new HashedEntryStackWrapper(stack)); + HashedEntryStackWrapper wrapper = new HashedEntryStackWrapper(stack); + reloadingRegistry.remove(wrapper); + return entriesHash.remove(wrapper.hashExact()); } else { preFilteredList.remove(stack); - return entries.remove(stack); + entries.remove(stack); + return entriesHash.remove(EntryStacks.hashExact(stack)); } } @Override public boolean removeEntryIf(Predicate> predicate) { if (reloading) { - return reloadingRegistry.removeIf(wrapper -> ((Predicate>) predicate).test(wrapper.unwrap())); + return reloadingRegistry.removeIf(wrapper -> { + if (((Predicate>) predicate).test(wrapper.unwrap())) { + entriesHash.remove(wrapper.hashExact()); + return true; + } + + return false; + }); } else { - preFilteredList.removeIf((Predicate>) predicate); - return entries.removeIf((Predicate>) predicate); + Predicate> entryStackPredicate = stack -> { + if (((Predicate>) predicate).test(stack)) { + entriesHash.remove(EntryStacks.hashExact(stack)); + return true; + } + + return false; + }; + preFilteredList.removeIf(entryStackPredicate); + return entries.removeIf(entryStackPredicate); } } @Override public boolean removeEntryExactHashIf(LongPredicate predicate) { + LongPredicate entryStackPredicate = hash -> { + if (predicate.test(hash)) { + entriesHash.remove(hash); + return true; + } + + return false; + }; + if (reloading) { - return reloadingRegistry.removeIf(wrapper -> predicate.test(wrapper.hashExact())); + return reloadingRegistry.removeIf(wrapper -> entryStackPredicate.test(wrapper.hashExact())); } else { - preFilteredList.removeIf(stack -> predicate.test(EntryStacks.hashExact(stack))); - return entries.removeIf(stack -> predicate.test(EntryStacks.hashExact(stack))); + preFilteredList.removeIf(stack -> entryStackPredicate.test(EntryStacks.hashExact(stack))); + return entries.removeIf(stack -> entryStackPredicate.test(EntryStacks.hashExact(stack))); } } @Override public boolean removeEntryFuzzyHashIf(LongPredicate predicate) { + Predicate> entryStackPredicate = stack -> { + if (predicate.test(EntryStacks.hashFuzzy(stack))) { + entriesHash.remove(EntryStacks.hashExact(stack)); + return true; + } + + return false; + }; + if (reloading) { - return reloadingRegistry.removeIf(wrapper -> predicate.test(EntryStacks.hashFuzzy(wrapper.unwrap()))); + return reloadingRegistry.removeIf(wrapper -> entryStackPredicate.test(wrapper.unwrap())); } else { - preFilteredList.removeIf(stack -> predicate.test(EntryStacks.hashFuzzy(stack))); - return entries.removeIf(stack -> predicate.test(EntryStacks.hashFuzzy(stack))); + preFilteredList.removeIf(entryStackPredicate); + return entries.removeIf(entryStackPredicate); } } } -- cgit