From fe233d82ea45c87fb5a7f73a70950db4c15ace4a Mon Sep 17 00:00:00 2001 From: asofold Date: Tue, 25 Apr 2017 10:18:41 +0200 Subject: [PATCH] Reorder the remainders of the previous draft. Keep an item array. Store an extra array of items internally and allow fast fetching (for fastest processing, where necessary). The sortedItemNodes array is kept for future purpose. --- .../registry/store/RegisteredItemStore.java | 73 ++++++++++++++----- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/store/RegisteredItemStore.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/store/RegisteredItemStore.java index 56fe79f0..7a654455 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/store/RegisteredItemStore.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/components/registry/store/RegisteredItemStore.java @@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.components.registry.store; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -19,11 +20,11 @@ import fr.neatmonster.nocheatplus.components.registry.order.RegistrationOrder.Ab import fr.neatmonster.nocheatplus.components.registry.order.SetupOrder; /** - * Keep sorted lists of registered (generic) items by type (support + * Keep sorted arrays of registered (generic) items by type (support * RegistrationOrder, IRegisterWithOrder, RegisterWithOrder, possibly * other/deprecated). This is an internal registry object, not meant for direct * external manipulation. Registering the same instance for several class types - * is possible. All registered items should differ by equals (!). + * is possible. All registered items must differ by equals (!). * * @author asofold * @@ -90,31 +91,53 @@ public class RegisteredItemStore { * itemNodes, for faster removal and contains check. Sorting by * internalId may use a Comparator. */ + /* + * TODO: Consider only having sortedItems, doing without + * sortedItemNodes. Contra: future registry features, then stored + * meta-data. + */ /** I bit heavy on the tip of the blade, java. */ private final SortItemNode typedSort = new SortItemNode(); - // TODO: always fetch an array and store as sorted. + /** Internal bookkeeping: all item nodes in order of registration. */ private final List> itemNodes = new LinkedList>(); - private List> sortedItemNodes = null; + /** All elements of itemNodes in sorted order, or null - lazy init, keep consistent. */ + private ItemNode[] sortedItemNodes = null; + /** All elements of itemNodes in sorted order, or null - lazy init, keep consistent. */ + private T[] sortedItems = null; /** - * For lazy sorting. + * Force sort, only should be called, if sortedItemNodes is null. */ + @SuppressWarnings("unchecked") void sort() { // TODO: Might create the typed sort on the fly, instead of storing it ... - typedSort.sort(itemNodes); - // TODO: extra sorted list (better: array once available), preserves order of registration. + sortedItemNodes = typedSort.getSortedArray(itemNodes); + sortedItems = (T[]) new Object[sortedItemNodes.length]; + for (int i = 0; i < sortedItemNodes.length; i++) { + sortedItems[i] = sortedItemNodes[i].item; + } + } + + /** + * Invalidate sorted outputs. + */ + void invalidateSorted() { sortedItemNodes = null; + sortedItems = null; + } + + /** + * Must not be altered. + * @return + */ + T[] getSortedItemsReferenceArray() { + return sortedItems; } List getSortedItemsCopyList() { - if (sortedItemNodes == null) { - sort(); - } - final List out = new LinkedList(); - for (final ItemNode node : sortedItemNodes) { - out.add(node.item); - } + final LinkedList out = new LinkedList(); + Collections.addAll(out, sortedItems); return out; } @@ -126,7 +149,7 @@ public class RegisteredItemStore { */ void register(final RegistrationOrder order, final T item, final int internalCount) { itemNodes.add(new ItemNode(order, item, internalCount)); - sortedItemNodes = null; + invalidateSorted(); } /** @@ -140,7 +163,7 @@ public class RegisteredItemStore { while (it.hasNext()) { // TODO: equals or == if (it.next().item.equals(item)) { - sortedItemNodes = null; + invalidateSorted(); it.remove(); return true; } @@ -480,7 +503,7 @@ public class RegisteredItemStore { } /** - * Get a new list with all registered items (ordered). + * Get a new (linked) list with all registered items (ordered). * * @param type * The type items are supposed to be registered for. @@ -494,6 +517,22 @@ public class RegisteredItemStore { return itemList == null ? new LinkedList() : itemList.getSortedItemsCopyList(); } + /** + * Get the reference of an internally stored array with all items that have + * been registered for the given type in sorted order. This would sort the + * items first, if the array is not set. It's imperative not to alter the + * array, because that would lead to an inconsistent internal state of the + * array. + * + * @param type + * @return + */ + @SuppressWarnings("unchecked") + public T[] getSortedItemsReferenceArray(Class type) { + final ItemList itemList = (ItemList) itemListMap.get(type); + return itemList == null ? null : itemList.getSortedItemsReferenceArray(); + } + /** * Remove everything. */