From cc87cae145a8ab6b64de5a04c65d3cb5d7c42f33 Mon Sep 17 00:00:00 2001 From: Speiger Date: Mon, 5 Dec 2022 00:00:05 +0100 Subject: [PATCH] Implemented Lists can now be Disabled Each List implementation can be now turned off. Or all Lists can be turned off. ListIterator can't be turned of since it is a IndexBasedIterator and not a List and a few implementation use them. --- Changelog.md | 2 + ModulSettings.json | 65 +++++- .../builder/PrimitiveCollectionsBuilder.java | 1 - .../src/builder/modules/ListModule.java | 32 ++- .../templates/collections/Iterable.template | 19 +- .../templates/lists/CopyOnWriteList.template | 4 +- .../collections/templates/lists/List.template | 4 + .../customHash/OpenCustomHashMap.template | 26 ++- .../maps/impl/hash/OpenHashMap.template | 26 ++- .../templates/sets/OpenCustomHashSet.template | 26 ++- .../templates/sets/OpenHashSet.template | 26 ++- .../templates/utils/Arrays.template | 34 ++- .../templates/utils/AsyncBuilder.template | 15 +- .../templates/utils/Collections.template | 203 ++++++++++++++++++ .../templates/utils/IArray.template | 2 + .../templates/utils/Iterables.template | 31 ++- .../templates/utils/Iterators.template | 67 +++--- 17 files changed, 466 insertions(+), 117 deletions(-) diff --git a/Changelog.md b/Changelog.md index 9725396..8e0630e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,8 @@ - Added: ISizeProvider into most Iterable implementations (Distinct/Filter/FlatMap/ArrayFlatMap don't support it, for obvious reasons) - Added: ToArray function into Iterable which uses ISizeProvider to reduce overhead of duplicating arrays. - Fixed: putIfAbsent now replaces defaultValues +- Fixed: OpenHashSet/Map and their Custom Variants no longer rely on List implementations. +- Fixed: ObjectCopyOnWriteList.of did create a ObjectArrayList instead of the CopyOnWrite variant. ### Version 0.7.0 - Added: Over 11 Million Unit Tests to this library to ensure quality. diff --git a/ModulSettings.json b/ModulSettings.json index 0fc6dbb..ebc5a6a 100644 --- a/ModulSettings.json +++ b/ModulSettings.json @@ -3,7 +3,7 @@ "Base": true, "Collection": true, "Function": true, - "List": true, + "List": false, "Map": true, "Pair": true, "PriorityQueue": true, @@ -101,7 +101,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true @@ -230,7 +235,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true @@ -359,7 +369,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true @@ -488,7 +503,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true @@ -617,7 +637,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true @@ -746,7 +771,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true @@ -875,7 +905,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true @@ -1004,7 +1039,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true @@ -1133,7 +1173,12 @@ "enabled": true }, "List": { - "enabled": true + "enabled": true, + "Lists": true, + "ImmutableList": true, + "CopyOnWriteList": true, + "ArrayList": true, + "LinkedList": true }, "Set": { "enabled": true diff --git a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java index ddb7a07..04a7dba 100644 --- a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java +++ b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java @@ -241,7 +241,6 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor boolean load = flags.contains("load"); boolean save = flags.contains("save"); int flag = (load ? LOAD : 0) | (save ? SAVE : 0); -// new PrimitiveCollectionsBuilder(silent).test(); new PrimitiveCollectionsBuilder(silent).setFlags(flag).process(force); if(tests) { createTests(silent, flag).process(force || forceTests); diff --git a/src/builder/java/speiger/src/builder/modules/ListModule.java b/src/builder/java/speiger/src/builder/modules/ListModule.java index b1e50cd..2fb2b10 100644 --- a/src/builder/java/speiger/src/builder/modules/ListModule.java +++ b/src/builder/java/speiger/src/builder/modules/ListModule.java @@ -1,5 +1,9 @@ package speiger.src.builder.modules; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import speiger.src.builder.ClassType; @SuppressWarnings("javadoc") @@ -11,18 +15,32 @@ public class ListModule extends BaseModule protected void loadVariables() {} @Override protected void loadFlags() { - + if(isModuleEnabled()) addKeyFlag("LIST_MODULE"); + if(isModuleEnabled("Lists")) addKeyFlag("LISTS_FEATURE"); + if(isModuleEnabled("ArrayList")) addKeyFlag("ARRAY_LIST_FEATURE"); + if(isModuleEnabled("LinkedList")) addKeyFlag("LINKED_LIST_FEATURE"); + if(isModuleEnabled("ImmutableList")) addKeyFlag("IMMUTABLE_LIST_FEATURE"); + if(isModuleEnabled("CopyOnWriteList")) addKeyFlag("COPY_ON_WRITE_LIST_FEATURE"); } @Override protected void loadBlockades() { - if(keyType.isObject()) { - addBlockedFiles("ListFillBufferTester"); - } - if(keyType == ClassType.BOOLEAN) { - addBlockedFiles("ListFillBufferTester", "ListReplaceAllTester"); - } + if(!isModuleEnabled("Lists")) addBlockedFiles("Lists"); + if(!isModuleEnabled("ArrayList")) addBlockedFiles("ArrayList"); + if(!isModuleEnabled("LinkedList")) addBlockedFiles("LinkedList"); + if(!isModuleEnabled("ImmutableList")) addBlockedFiles("ImmutableList"); + if(!isModuleEnabled("CopyOnWriteList")) addBlockedFiles("CopyOnWriteList"); + if(!isModuleEnabled()) addBlockedFiles("List", "AbstractList"); + + if(keyType.isObject()) addBlockedFiles("ListFillBufferTester"); + if(keyType == ClassType.BOOLEAN) addBlockedFiles("ListFillBufferTester", "ListReplaceAllTester"); + } + + @Override + public Set getModuleKeys(ClassType keyType, ClassType valueType) + { + return new HashSet<>(Arrays.asList("Lists", "ArrayList", "LinkedList", "ImmutableList", "CopyOnWriteList")); } @Override diff --git a/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template b/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template index 213b4a9..afb9194 100644 --- a/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template +++ b/src/builder/resources/speiger/assets/collections/templates/collections/Iterable.template @@ -17,12 +17,19 @@ import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; +#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE import speiger.src.collections.PACKAGE.lists.LIST; +#if ARRAY_LIST_FEATURE import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; +#else +import speiger.src.collections.PACKAGE.lists.LINKED_LIST; +#endif +#endif #if !TYPE_BOOLEAN import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.LINKED_HASH_SET; #endif +import speiger.src.collections.PACKAGE.utils.ARRAYS; #if ASYNC_MODULE import speiger.src.collections.PACKAGE.utils.ASYNC_BUILDER; #endif @@ -206,14 +213,20 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable return collection; } +#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE /** * A Helper function that reduces the usage of streams and allows to collect all elements as a ArrayList * @return a new ArrayList of all elements */ default LIST KEY_GENERIC_TYPE pourAsList() { - return pour(new ARRAY_LISTBRACES()); +#if ARRAY_LIST_FEATURE + return pour(new ARRAY_LISTBRACES()); +#else + return pour(new LINKED_LISTBRACES()); +#endif } +#endif #if !TYPE_BOOLEAN /** * A Helper function that reduces the usage of streams and allows to collect all elements as a LinkedHashSet @@ -241,7 +254,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable return array; } } - return ITERATORS.pour(iterator()).TO_ARRAY(action); + return ARRAYS.pour(iterator(), action); } #else /** @@ -258,7 +271,7 @@ public interface ITERABLE KEY_GENERIC_TYPE extends Iterable return array; } } - return ITERATORS.pour(iterator()).TO_ARRAY(); + return ARRAYS.pour(iterator()); } #endif diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/CopyOnWriteList.template b/src/builder/resources/speiger/assets/collections/templates/lists/CopyOnWriteList.template index 806223f..0e49659 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/CopyOnWriteList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/CopyOnWriteList.template @@ -148,8 +148,8 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER * @Type(T) * @return a typed List */ - public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE of(Class c) { - ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); + public static GENERIC_KEY_BRACES COPY_ON_WRITE_LIST KEY_GENERIC_TYPE of(Class c) { + COPY_ON_WRITE_LIST KEY_GENERIC_TYPE list = new COPY_ON_WRITE_LISTBRACES(); list.data = (KEY_TYPE[])ObjectArrays.newArray(c, 0); return list; } diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/List.template b/src/builder/resources/speiger/assets/collections/templates/lists/List.template index 5c0a2c4..6488ca2 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/List.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/List.template @@ -20,7 +20,9 @@ import speiger.src.collections.PACKAGE.collections.SPLIT_ITERATOR; import speiger.src.collections.PACKAGE.functions.COMPARATOR; #endif import speiger.src.collections.PACKAGE.utils.ARRAYS; +#if LIST_FEATURE import speiger.src.collections.PACKAGE.utils.LISTS; +#endif import speiger.src.collections.PACKAGE.utils.SPLIT_ITERATORS; #if TYPE_BYTE || TYPE_SHORT || TYPE_CHAR || TYPE_FLOAT import speiger.src.collections.utils.SanityChecks; @@ -379,6 +381,7 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List @Override public LIST KEY_GENERIC_TYPE subList(int from, int to); +#if LISTS_FEATURE /** * Creates a Wrapped List that is Synchronized * @return a new List that is synchronized @@ -401,6 +404,7 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List */ public default LIST KEY_GENERIC_TYPE unmodifiable() { return LISTS.unmodifiable(this); } +#endif /** * A function to ensure the elements are within the requested size. * If smaller then the stored elements they get removed as needed. diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/impl/customHash/OpenCustomHashMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/impl/customHash/OpenCustomHashMap.template index 1d67e8b..8f4c4b6 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/impl/customHash/OpenCustomHashMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/impl/customHash/OpenCustomHashMap.template @@ -22,8 +22,6 @@ import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; #if !TYPE_OBJECT && !VALUE_BOOLEAN import speiger.src.collections.PACKAGE.functions.function.PREDICATE; #endif -import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; -import speiger.src.collections.PACKAGE.lists.LIST; import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.utils.maps.MAPS; @@ -1420,7 +1418,8 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL int lastReturned = -1; int nextIndex = Integer.MIN_VALUE; boolean returnNull = containsNull; - LIST KEY_GENERIC_TYPE wrapped = null; + KEY_TYPE[] wrapped = null; + int wrappedIndex = 0; public boolean hasNext() { if(nextIndex == Integer.MIN_VALUE) { @@ -1432,7 +1431,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL { while(true) { if(--pos < 0) { - if(wrapped == null || wrapped.size() <= -pos - 1) break; + if(wrapped == null || wrappedIndex <= -pos - 1) break; nextIndex = -pos - 1; break; } @@ -1451,7 +1450,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL returnedPos = pos; if(nextIndex < 0){ lastReturned = Integer.MAX_VALUE; - int value = findIndex(wrapped.GET_KEY(nextIndex)); + int value = findIndex(wrapped[nextIndex]); if(value < 0) throw new IllegalStateException("Entry ["+nextIndex+"] was removed during Iteration"); nextIndex = Integer.MIN_VALUE; return value; @@ -1470,7 +1469,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL } else if(returnedPos >= 0) shiftKeys(returnedPos); else { - CUSTOM_HASH_MAP.this.remove(wrapped.GET_KEY(-returnedPos - 1)); + CUSTOM_HASH_MAP.this.remove(wrapped[-returnedPos - 1]); lastReturned = -1; return; } @@ -1493,13 +1492,20 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break; startPos = ++startPos & mask; } - if(startPos < last) { - if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2); - wrapped.add(keys[startPos]); - } + if(startPos < last) addWrapper(keys[startPos]); keys[last] = current; values[last] = values[startPos]; } } + + private void addWrapper(KEY_TYPE value) { + if(wrapped == null) wrapped = NEW_KEY_ARRAY(2); + else if(wrappedIndex >= wrapped.length) { + KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2); + System.arraycopy(wrapped, 0, newArray, 0, wrapped.length); + wrapped = newArray; + } + wrapped[wrappedIndex++] = value; + } } } \ No newline at end of file diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/impl/hash/OpenHashMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/impl/hash/OpenHashMap.template index ce26713..24e30d1 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/impl/hash/OpenHashMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/impl/hash/OpenHashMap.template @@ -22,8 +22,6 @@ import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR; #if !TYPE_OBJECT && !VALUE_BOOLEAN import speiger.src.collections.PACKAGE.functions.function.PREDICATE; #endif -import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; -import speiger.src.collections.PACKAGE.lists.LIST; import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.PACKAGE.maps.interfaces.MAP; import speiger.src.collections.PACKAGE.utils.maps.MAPS; @@ -1376,7 +1374,8 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE int lastReturned = -1; int nextIndex = Integer.MIN_VALUE; boolean returnNull = containsNull; - LIST KEY_GENERIC_TYPE wrapped = null; + KEY_TYPE[] wrapped = null; + int wrappedIndex = 0; public boolean hasNext() { if(nextIndex == Integer.MIN_VALUE) { @@ -1388,7 +1387,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE { while(true) { if(--pos < 0) { - if(wrapped == null || wrapped.size() <= -pos - 1) break; + if(wrapped == null || wrappedIndex <= -pos - 1) break; nextIndex = -pos - 1; break; } @@ -1407,7 +1406,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE returnedPos = pos; if(nextIndex < 0){ lastReturned = Integer.MAX_VALUE; - int value = findIndex(wrapped.GET_KEY(nextIndex)); + int value = findIndex(wrapped[nextIndex]); if(value < 0) throw new IllegalStateException("Entry ["+nextIndex+"] was removed during Iteration"); nextIndex = Integer.MIN_VALUE; return value; @@ -1426,7 +1425,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE } else if(returnedPos >= 0) shiftKeys(returnedPos); else { - HASH_MAP.this.remove(wrapped.GET_KEY(-returnedPos - 1)); + HASH_MAP.this.remove(wrapped[-returnedPos - 1]); lastReturned = -1; return; } @@ -1449,13 +1448,20 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break; startPos = ++startPos & mask; } - if(startPos < last) { - if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2); - wrapped.add(keys[startPos]); - } + if(startPos < last) addWrapper(keys[startPos]); keys[last] = current; values[last] = values[startPos]; } } + + private void addWrapper(KEY_TYPE value) { + if(wrapped == null) wrapped = NEW_KEY_ARRAY(2); + else if(wrappedIndex >= wrapped.length) { + KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2); + System.arraycopy(wrapped, 0, newArray, 0, wrapped.length); + wrapped = newArray; + } + wrapped[wrappedIndex++] = value; + } } } \ No newline at end of file diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/OpenCustomHashSet.template b/src/builder/resources/speiger/assets/collections/templates/sets/OpenCustomHashSet.template index b1e7a9d..c9ddeb4 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/OpenCustomHashSet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/OpenCustomHashSet.template @@ -13,8 +13,6 @@ import java.util.function.BiFunction; import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.ITERATOR; -import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; -import speiger.src.collections.PACKAGE.lists.LIST; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.functions.CONSUMER; @@ -630,7 +628,8 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T int lastReturned = -1; int nextIndex = Integer.MIN_VALUE; boolean returnNull = containsNull; - LIST KEY_GENERIC_TYPE wrapped = null; + KEY_TYPE[] wrapped = null; + int wrappedIndex = 0; @Override public boolean hasNext() { @@ -642,7 +641,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T else { while(true) { if(--pos < 0) { - if(wrapped == null || wrapped.size() <= -pos - 1) break; + if(wrapped == null || wrappedIndex <= -pos - 1) break; nextIndex = -pos - 1; break; } @@ -662,7 +661,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T returnedPos = pos; if(nextIndex < 0){ lastReturned = Integer.MAX_VALUE; - KEY_TYPE value = wrapped.GET_KEY(nextIndex); + KEY_TYPE value = wrapped[nextIndex]; nextIndex = Integer.MIN_VALUE; return value; } @@ -680,7 +679,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T } else if(returnedPos >= 0) shiftKeys(returnedPos); else { - CUSTOM_HASH_SET.this.remove(wrapped.GET_KEY(-returnedPos - 1)); + CUSTOM_HASH_SET.this.remove(wrapped[-returnedPos - 1]); lastReturned = -1; return; } @@ -702,12 +701,19 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break; startPos = ++startPos & mask; } - if(startPos < last) { - if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2); - wrapped.add(keys[startPos]); - } + if(startPos < last) addWrapper(keys[startPos]); keys[last] = current; } } + + private void addWrapper(KEY_TYPE value) { + if(wrapped == null) wrapped = NEW_KEY_ARRAY(2); + else if(wrappedIndex >= wrapped.length) { + KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2); + System.arraycopy(wrapped, 0, newArray, 0, wrapped.length); + wrapped = newArray; + } + wrapped[wrappedIndex++] = value; + } } } \ No newline at end of file diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/OpenHashSet.template b/src/builder/resources/speiger/assets/collections/templates/sets/OpenHashSet.template index 5cac2a9..b5646b0 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/OpenHashSet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/OpenHashSet.template @@ -13,8 +13,6 @@ import java.util.function.BiFunction; import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.ITERATOR; -import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; -import speiger.src.collections.PACKAGE.lists.LIST; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.PACKAGE.functions.CONSUMER; @@ -597,7 +595,8 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp int lastReturned = -1; int nextIndex = Integer.MIN_VALUE; boolean returnNull = containsNull; - LIST KEY_GENERIC_TYPE wrapped = null; + KEY_TYPE[] wrapped = null; + int wrappedIndex = 0; @Override public boolean hasNext() { @@ -610,7 +609,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp { while(true) { if(--pos < 0) { - if(wrapped == null || wrapped.size() <= -pos - 1) break; + if(wrapped == null || wrappedIndex <= -pos - 1) break; nextIndex = -pos - 1; break; } @@ -630,7 +629,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp returnedPos = pos; if(nextIndex < 0){ lastReturned = Integer.MAX_VALUE; - KEY_TYPE value = wrapped.GET_KEY(nextIndex); + KEY_TYPE value = wrapped[nextIndex]; nextIndex = Integer.MIN_VALUE; return value; } @@ -648,7 +647,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp } else if(returnedPos >= 0) shiftKeys(returnedPos); else { - HASH_SET.this.remove(wrapped.GET_KEY(-returnedPos - 1)); + HASH_SET.this.remove(wrapped[-returnedPos - 1]); lastReturned = -1; return; } @@ -670,12 +669,19 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp if(last <= startPos ? (last >= slot || slot > startPos) : (last >= slot && slot > startPos)) break; startPos = ++startPos & mask; } - if(startPos < last) { - if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2); - wrapped.add(keys[startPos]); - } + if(startPos < last) addWrapper(keys[startPos]); keys[last] = current; } } + + private void addWrapper(KEY_TYPE value) { + if(wrapped == null) wrapped = NEW_KEY_ARRAY(2); + else if(wrappedIndex >= wrapped.length) { + KEY_TYPE[] newArray = NEW_KEY_ARRAY(wrapped.length * 2); + System.arraycopy(wrapped, 0, newArray, 0, wrapped.length); + wrapped = newArray; + } + wrapped[wrappedIndex++] = value; + } } } \ No newline at end of file diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template b/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template index 44937fb..68065f4 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Arrays.template @@ -9,10 +9,11 @@ import speiger.src.collections.PACKAGE.functions.COMPARATOR; #else import java.util.Comparator; +import speiger.src.collections.ints.functions.function.Int2ObjectFunction; #endif import speiger.src.collections.PACKAGE.collections.ITERATOR; -import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; import speiger.src.collections.PACKAGE.utils.ITERATORS; +import speiger.src.collections.PACKAGE.utils.COLLECTIONS; import speiger.src.collections.utils.SanityChecks; /** @@ -132,10 +133,39 @@ public class ARRAYS * @return array with all requested elements of the iterator */ public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max) { - ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); + COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE list = COLLECTIONS.wrapper(); ITERATORS.pour(iter, list, max); return list.TO_ARRAY(NEW_KEY_ARRAY(list.size())); } + +#if TYPE_OBJECT + /** + * A Helper function that pours all elements of a iterator into a Array + * @param iter the elements that should be gathered. + * @ArrayType(T) + * @param action that is creating the Array to be poured into + * @return array with all elements of the iterator + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter, Int2ObjectFunction action) { + return pour(iter, Integer.MAX_VALUE, action); + } + + /** + * A Helper function that pours all elements of a iterator into a Array + * @param iter the elements that should be gathered. + * @param max how many elements should be added + * @param action that is creating the Array to be poured into + * @ArrayType(T) + * @return array with all requested elements of the iterator + */ + public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max, Int2ObjectFunction action) { + COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE list = COLLECTIONS.wrapper(); + ITERATORS.pour(iter, list, max); + return list.TO_ARRAY(action.apply(list.size())); + } + +#endif + /** * Method to validate if the current value is the lowest value in the heap * @param data the current heap. diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template b/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template index 129637b..e2d8c21 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template @@ -27,9 +27,12 @@ import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; #endif import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; -import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; #if OBJECT_ASYNC_MODULE -import speiger.src.collections.PACKAGE.lists.LIST; +#if ARRAY_LIST_FEATURE +import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; +#else if LINKED_LIST_FEATURE +import speiger.src.collections.PACKAGE.lists.LINKED_LIST; +#endif #if !TYPE_BOOLEAN import speiger.src.collections.PACKAGE.sets.SET; import speiger.src.collections.PACKAGE.sets.LINKED_HASH_SET; @@ -119,6 +122,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE return new ASYNC_BUILDERBRACES(ITERABLES.wrap(iterable)); } +#if ARRAY_LIST_FEATURE /** * Helper function that automatically wraps a array into a AsyncBuilder since it forces this collections Iterable. * @param values that should be wrapped @@ -129,6 +133,7 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE return new ASYNC_BUILDERBRACES(ARRAY_LIST.wrap(values)); } +#endif #if OBJECT_ASYNC_MODULE /** * Maps the elements to something else @@ -268,14 +273,20 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE #endif #if OBJECT_ASYNC_MODULE +#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE /** * Pours all elements into a List that can be later * @return a new Builder with the pour function applied */ public ObjectAsyncBuilder pourAsList() { +#if ARRAY_LIST_FEATURE return pour(new ARRAY_LISTBRACES()); +#else + return pour(new LINKED_LISTBRACES()); +#endif } +#endif #if !TYPE_BOOLEAN /** * Pours all elements into a Set that can be later diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Collections.template b/src/builder/resources/speiger/assets/collections/templates/utils/Collections.template index d922289..58136b1 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Collections.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Collections.template @@ -1,7 +1,10 @@ package speiger.src.collections.PACKAGE.utils; +import java.util.Arrays; import java.util.Collection; +import java.util.Objects; #if TYPE_OBJECT +import java.util.Comparator; import java.util.function.BiFunction; #endif import java.util.function.Predicate; @@ -13,6 +16,9 @@ import java.util.function.Consumer; import speiger.src.collections.PACKAGE.collections.ABSTRACT_COLLECTION; import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.ITERATOR; +#if !TYPE_OBJECT +import speiger.src.collections.PACKAGE.functions.COMPARATOR; +#endif import speiger.src.collections.objects.utils.ObjectArrays; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.functions.CONSUMER; @@ -21,6 +27,9 @@ import speiger.src.collections.PACKAGE.utils.ARRAYS; import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; +import speiger.src.collections.utils.ITrimmable; +import speiger.src.collections.utils.SanityChecks; + /** * A Helper class for Collections */ @@ -75,6 +84,200 @@ public class COLLECTIONS return c instanceof SynchronizedCollection ? c : new SynchronizedCollectionBRACES(c, mutex); } + protected static GENERIC_KEY_BRACES CollectionWrapper KEY_GENERIC_TYPE wrapper() { + return new CollectionWrapperBRACES(); + } + + protected static GENERIC_KEY_BRACES CollectionWrapper KEY_GENERIC_TYPE wrapper(int size) { + return new CollectionWrapperBRACES(size); + } + + protected static class CollectionWrapper KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION KEY_GENERIC_TYPE implements ITrimmable { + KEY_TYPE[] elements; + int size = 0; + + public CollectionWrapper() { + this(10); + } + + public CollectionWrapper(int size) { + if(size < 0) throw new IllegalStateException("Size has to be 0 or greater"); + elements = NEW_KEY_ARRAY(size); + } + + @Override + public boolean add(KEY_TYPE o) { + if(size >= elements.length) elements = Arrays.copyOf(elements, (int)Math.min((long)elements.length + (elements.length >> 1), SanityChecks.MAX_ARRAY_SIZE)); + elements[size++] = o; + return true; + } + + public KEY_TYPE GET_KEY(int index) { + if(index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + return elements[index]; + } + +#if TYPE_OBJECT + @Override + public boolean remove(Object e) { + for(int i = 0;i= size) throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + size--; + if(index != size) System.arraycopy(elements, index+1, elements, index, size - index); + } + + @Override + public ITERATOR KEY_GENERIC_TYPE iterator() { + return new ITERATOR KEY_GENERIC_TYPE() { + int index = 0; + int lastReturned = -1; + + @Override + public boolean hasNext() { + return index < size; + } + + @Override + public KEY_TYPE NEXT() { + int i = index++; + return elements[(lastReturned = i)]; + } + + @Override + public void remove() { + if(lastReturned == -1) throw new IllegalStateException(); + removeIndex(lastReturned); + index = lastReturned; + lastReturned = -1; + } + }; + } + + @Override + public int size() { + return size; + } + + @Override + public void clear() { +#if TYPE_OBJECT + for(int i = 0;i c) { + if(c != null) ARRAYS.stableSort(elements, size, c); + else ARRAYS.stableSort(elements, size); + } + + public void unstableSort(Comparator c) { + if(c != null) ARRAYS.unstableSort(elements, size, c); + else ARRAYS.unstableSort(elements, size); + } + +#else + public void sort(COMPARATOR c) { + if(c != null) ARRAYS.stableSort(elements, size, c); + else ARRAYS.stableSort(elements, size); + } + + public void unstableSort(COMPARATOR c) { + if(c != null) ARRAYS.unstableSort(elements, size, c); + else ARRAYS.unstableSort(elements, size); + } + +#endif + @Override + public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(int i = 0;i void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { + Objects.requireNonNull(action); + for(int i = 0;i size() || size() == elements.length) return false; + int value = Math.max(size, size()); + elements = value == 0 ? EMPTY_KEY_ARRAY : Arrays.copyOf(elements, value); + return true; + } + + @Override + public void clearAndTrim(int size) { + if(elements.length <= size) { + clear(); + return; + } + elements = size == 0 ? EMPTY_KEY_ARRAY : NEW_KEY_ARRAY(size); + this.size = size; + } + + @Override + @Primitive + public Object[] toArray() { + Object[] obj = new Object[size]; + for(int i = 0;i E[] toArray(E[] a) { + if(a == null) a = (E[])new Object[size]; + else if(a.length < size) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size); + #if TYPE_OBJECT + System.arraycopy(elements, 0, a, 0, size); + #else + for(int i = 0;i size) a[size] = null; + return a; + } + +#if !TYPE_OBJECT + @Override + public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) { + if(a.length < size) a = new KEY_TYPE[size]; + System.arraycopy(elements, 0, a, 0, size); + if (a.length > size) a[size] = EMPTY_KEY_VALUE; + return a; + } +#endif + } + /** * Synchronized Collection Wrapper for the synchronizedCollection function * @Type(T) diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/IArray.template b/src/builder/resources/speiger/assets/collections/templates/utils/IArray.template index ff040f0..3193973 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/IArray.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/IArray.template @@ -7,7 +7,9 @@ import speiger.src.collections.utils.IArray; /** * Type-Specific Helper class to get the underlying array of array implementations. +#if ARRAY_LIST_FEATURE * @see speiger.src.collections.PACKAGE.lists.ARRAY_LIST +#endif * @Type(T) */ public interface IARRAY KEY_GENERIC_TYPE extends IArray diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template b/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template index de74496..95a553f 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Iterables.template @@ -10,6 +10,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import speiger.src.collections.PACKAGE.collections.ITERABLE; +import speiger.src.collections.PACKAGE.collections.COLLECTION; #if !TYPE_OBJECT import speiger.src.collections.objects.collections.ObjectIterable; import speiger.src.collections.objects.collections.ObjectIterator; @@ -17,8 +18,6 @@ import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.COMPARATOR; #endif import speiger.src.collections.PACKAGE.collections.ITERATOR; -import speiger.src.collections.PACKAGE.lists.LIST; -import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.PREDICATE; #if !TYPE_BOOLEAN @@ -380,19 +379,19 @@ public class ITERABLES @Override public void forEach(CONSUMER action) { Objects.requireNonNull(action); - LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); - iterable.forEach(action.andThen(list::add)); + COLLECTION KEY_GENERIC_TYPE repeater = COLLECTIONS.wrapper(); + iterable.forEach(action.andThen(repeater::add)); for(int i = 0;i action) { Objects.requireNonNull(action); - LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); - iterable.forEach(T -> {action.accept(T); list.add(T);}); + COLLECTION KEY_GENERIC_TYPE repeater = COLLECTIONS.wrapper(); + iterable.forEach(T -> {action.accept(T); repeater.add(T);}); for(int i = 0;i action) { Objects.requireNonNull(action); - LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); - iterable.forEach(list::add); - list.unstableSort(sorter); - list.forEach(action); + COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE wrapper = COLLECTIONS.wrapper(); + iterable.forEach(wrapper::add); + wrapper.unstableSort(sorter); + wrapper.forEach(action); } #endif } diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template b/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template index e9c0f3a..dad3089 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Iterators.template @@ -16,8 +16,13 @@ import speiger.src.collections.PACKAGE.functions.COMPARATOR; #endif import speiger.src.collections.PACKAGE.functions.function.TO_OBJECT_FUNCTION; import speiger.src.collections.PACKAGE.functions.function.PREDICATE; +#if LIST_MODULE +#if ARRAY_LIST_FEATURE import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; -import speiger.src.collections.PACKAGE.lists.LIST; +#else if LINKED_LIST_FEATURE +import speiger.src.collections.PACKAGE.lists.LINKED_LIST; +#endif +#endif import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR; import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; import speiger.src.collections.PACKAGE.collections.COLLECTION; @@ -468,6 +473,8 @@ public class ITERATORS } #endif +#if LIST_MODULE +#if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE /** * A Helper function to pours all elements of a Iterator into a List * @param iter the elements that should be poured into list. @@ -486,12 +493,20 @@ public class ITERATORS * @return A list of all requested elements of the Iterator */ public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE pour(ITERATOR KEY_GENERIC_TYPE iter, int max) { +#if ARRAY_LIST_FEATURE ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); +#else + LINKED_LIST KEY_GENERIC_TYPE list = new LINKED_LISTBRACES(); +#endif pour(iter, list, max); +#if ARRAY_LIST_FEATURE list.trim(); +#endif return list; } +#endif +#endif /** * A Helper function to pours all elements of a Iterator into a Collection * @param iter the elements that should be poured into list. @@ -624,7 +639,7 @@ public class ITERATORS @Override public void remove() { it.remove(); } } - + private static class ReverseListIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE { LIST_ITERATOR KEY_GENERIC_TYPE it; @@ -747,45 +762,25 @@ public class ITERATORS return iterator.NEXT(); } } - + private static class EmptyIterator KEY_GENERIC_TYPE implements LIST_ITERATOR KEY_GENERIC_TYPE { @Override - public boolean hasNext() { - return false; - } - + public boolean hasNext() { return false; } @Override - public KEY_TYPE NEXT() { - throw new NoSuchElementException(); - } - + public KEY_TYPE NEXT() { throw new NoSuchElementException(); } @Override - public boolean hasPrevious() { - return false; - } - + public boolean hasPrevious() { return false; } @Override - public KEY_TYPE PREVIOUS() { - throw new NoSuchElementException(); - } - + public KEY_TYPE PREVIOUS() { throw new NoSuchElementException(); } @Override - public int nextIndex() { - return 0; - } - + public int nextIndex() { return 0; } @Override - public int previousIndex() { - return -1; - } - + public int previousIndex() { return -1; } @Override public void remove() { throw new UnsupportedOperationException(); } - @Override public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); } - @Override public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); } } @@ -925,7 +920,7 @@ public class ITERATORS final int repeats; int index = 0; ITERATOR KEY_GENERIC_TYPE iter; - LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); + COLLECTION KEY_GENERIC_TYPE repeater = COLLECTIONS.wrapper(); public RepeatingIterator(ITERATOR KEY_GENERIC_TYPE iter, int repeat) { this.iter = iter; @@ -937,7 +932,7 @@ public class ITERATORS if(iter.hasNext()) return true; if(index < repeats) { index++; - iter = list.iterator(); + iter = repeater.iterator(); return iter.hasNext(); } return false; @@ -947,7 +942,7 @@ public class ITERATORS public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); KEY_TYPE value = iter.NEXT(); - if(index == 0) list.add(value); + if(index == 0) repeater.add(value); return value; } } @@ -956,7 +951,7 @@ public class ITERATORS { ITERATOR KEY_GENERIC_TYPE iterator; COMPARATOR KEY_GENERIC_TYPE sorter; - LIST KEY_GENERIC_TYPE sortedElements = null; + COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE sortedElements = null; int index = 0; public SortedIterator(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE sorter) { @@ -968,7 +963,11 @@ public class ITERATORS public boolean hasNext() { if(sortedElements == null) { boolean hasNext = iterator.hasNext(); - sortedElements = hasNext ? pour(iterator) : LISTS.empty(); + if(hasNext) { + sortedElements = COLLECTIONS.wrapper(); + pour(iterator, sortedElements); + } + else sortedElements = COLLECTIONS.wrapper(); if(hasNext) sortedElements.unstableSort(sorter); } return index < sortedElements.size();