diff --git a/Changelog.md b/Changelog.md index 4a00c94..4074254 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,7 +6,11 @@ - Added: ToArray function into Iterable which uses ISizeProvider to reduce overhead of duplicating arrays. - Added: Functions that have the same type, Int2IntFunction as example, have now a identity function. - Added: Functions of a BooleanValue have now alwaysTrue/False function. -- Added: ForEachIndexed for Lists only for now. (Might get added to others too if necessary) +- Added: ForEachIndexed for all Iterable implementations +- Added: RandomGenerator support (Java17), though requires self compilation +- Added: Optimizations for HashUtils next power of function. +- Added: toArray() now returns a cached empty array if the collection is empty. +- Added: toArray function for AsyncBuilder - 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. diff --git a/build.gradle b/build.gradle index f5801cb..82fb672 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,7 @@ configurations { dependencies { builderImplementation 'com.google.code.gson:gson:2.10' - builderImplementation 'de.speiger:Simple-Code-Generator:1.2.1' + builderImplementation 'de.speiger:Simple-Code-Generator:1.2.2' testImplementation 'junit:junit:4.12' testImplementation 'com.google.guava:guava-testlib:31.0.1-jre' diff --git a/src/builder/java/speiger/src/builder/ModulePackage.java b/src/builder/java/speiger/src/builder/ModulePackage.java index 84933cd..a08c540 100644 --- a/src/builder/java/speiger/src/builder/ModulePackage.java +++ b/src/builder/java/speiger/src/builder/ModulePackage.java @@ -32,6 +32,7 @@ public class ModulePackage List mappers = new ArrayList<>(); Set flags = new LinkedHashSet<>(); Set globalFlags; + Map flaggedValues = new HashMap<>(); BiConsumer requirements = VOID; public ModulePackage(Set globalFlags, ClassType keyType, ClassType valueType) { @@ -74,6 +75,10 @@ public class ModulePackage globalFlags.add(flag); } + public void addValue(String key, int value) { + flaggedValues.put(key, value); + } + public void addRequirement(String fileName, RequiredType type) { requirements.accept(fileName, type); } @@ -107,6 +112,7 @@ public class ModulePackage process.addFlags(flags); process.addFlags(globalFlags); process.addMappers(mappers); + process.addValues(flaggedValues); result.accept(process); } diff --git a/src/builder/java/speiger/src/builder/modules/BaseModule.java b/src/builder/java/speiger/src/builder/modules/BaseModule.java index a3ffc0d..d13f72f 100644 --- a/src/builder/java/speiger/src/builder/modules/BaseModule.java +++ b/src/builder/java/speiger/src/builder/modules/BaseModule.java @@ -83,6 +83,10 @@ public abstract class BaseModule entry.addFlag(name); } + protected void addValue(String name, int value) { + entry.addValue(name, value); + } + protected void addKeyFlag(String name) { entry.addFlag(name); entry.addGlobalFlag(keyType.getCapType()+"_"+name); diff --git a/src/builder/java/speiger/src/builder/modules/JavaModule.java b/src/builder/java/speiger/src/builder/modules/JavaModule.java index 9b6e1ee..61b7811 100644 --- a/src/builder/java/speiger/src/builder/modules/JavaModule.java +++ b/src/builder/java/speiger/src/builder/modules/JavaModule.java @@ -22,6 +22,7 @@ public class JavaModule extends BaseModule { addFlag("TYPE_"+keyType.getCapType()); addFlag("VALUE_"+valueType.getCapType()); + addValue("JAVA_VERSION", getVersion()); if(keyType == valueType) addFlag("SAME_TYPE"); if(keyType.hasFunction(valueType)) addFlag("JDK_FUNCTION"); if(!keyType.needsCustomJDKType()) addFlag("JDK_TYPE"); @@ -30,6 +31,13 @@ public class JavaModule extends BaseModule if(!valueType.needsCustomJDKType()) addFlag("JDK_VALUE"); } + private int getVersion() { + String version = System.getProperty("java.version"); + if(version.startsWith("1.")) return Integer.parseInt(version.substring(2, 3)); + int dot = version.indexOf("."); + return Integer.parseInt(dot != -1 ? version.substring(0, dot) : version); + } + @Override protected void loadRemappers() {} @Override @@ -52,6 +60,8 @@ public class JavaModule extends BaseModule @Override protected void loadClasses() { + if(getVersion() >= 17) addSimpleMapper("RANDOM", "RandomGenerator"); + else addSimpleMapper("RANDOM", "Random"); addSimpleMapper("JAVA_PREDICATE", keyType.isPrimitiveBlocking() ? "" : keyType.getCustomJDKType().getFileType()+"Predicate"); addSimpleMapper("JAVA_CONSUMER", keyType.isPrimitiveBlocking() ? "" : "java.util.function."+keyType.getCustomJDKType().getFileType()+"Consumer"); addSimpleMapper("JAVA_SUPPLIER", keyType.isPrimitiveBlocking() ? "" : "java.util.function."+keyType.getCustomJDKType().getFileType()+"Supplier"); diff --git a/src/builder/resources/speiger/assets/collections/templates/collections/AbstractCollection.template b/src/builder/resources/speiger/assets/collections/templates/collections/AbstractCollection.template index 2a96ba7..fedde02 100644 --- a/src/builder/resources/speiger/assets/collections/templates/collections/AbstractCollection.template +++ b/src/builder/resources/speiger/assets/collections/templates/collections/AbstractCollection.template @@ -11,6 +11,7 @@ import java.util.function.Consumer; import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.utils.ITERATORS; #endif +import speiger.src.collections.PACKAGE.utils.ARRAYS; /** * Abstract Type Specific Collection that reduces boxing/unboxing @@ -245,6 +246,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle */ @Override public KEY_TYPE[] TO_ARRAY() { + if(isEmpty()) return ARRAYS.EMPTY_ARRAY; return TO_ARRAY(new KEY_TYPE[size()]); } diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template b/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template index 58b21d8..59e982b 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template @@ -42,11 +42,10 @@ import speiger.src.collections.PACKAGE.functions.function.PREDICATE; #endif import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.utils.ARRAYS; +import speiger.src.collections.objects.utils.ObjectArrays; import speiger.src.collections.PACKAGE.utils.ITERATORS; #if TYPE_OBJECT import speiger.src.collections.utils.Stack; -#else -import speiger.src.collections.objects.utils.ObjectArrays; #endif #if PRIMITIVES && SPLIT_ITERATOR_FEATURE && STREAM_FEATURE import java.util.stream.JAVA_STREAM; @@ -1043,6 +1042,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE @Override @Primitive public Object[] toArray() { + if(size == 0) return ObjectArrays.EMPTY_ARRAY; Object[] obj = new Object[size]; for(int i = 0;i=17 +import java.util.random.RANDOM; +#else +import java.util.RANDOM; +#endif import java.util.concurrent.RecursiveAction; #if !TYPE_OBJECT @@ -292,7 +296,7 @@ public class ARRAYS * @ArrayType(T) * @return the provided sorted array */ - public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, Random random) { + public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, RANDOM random) { for(int i = array.length-1; i>=0;i--) { int p = random.nextInt(i + 1); KEY_TYPE t = array[i]; @@ -310,7 +314,7 @@ public class ARRAYS * @ArrayType(T) * @return the provided sorted array */ - public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length, Random random) { + public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length, RANDOM random) { return shuffle(array, 0, length, random); } @@ -323,7 +327,7 @@ public class ARRAYS * @ArrayType(T) * @return the provided sorted array */ - public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length, Random random) { + public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length, RANDOM random) { for(int i = length-1; i>=0;i--) { int p = offset + random.nextInt(i + 1); KEY_TYPE t = array[offset+i]; 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 3538fb0..e198502 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/AsyncBuilder.template @@ -12,6 +12,7 @@ import java.util.function.Consumer; import speiger.src.collections.PACKAGE.functions.CONSUMER; import speiger.src.collections.PACKAGE.functions.COMPARATOR; #else +import java.util.function.IntFunction; import java.util.function.BiFunction; import java.util.Comparator; @@ -69,6 +70,7 @@ import speiger.src.collections.objects.utils.ObjectAsyncBuilder.BaseObjectTask; import speiger.src.collections.ints.utils.IntAsyncBuilder; import speiger.src.collections.ints.utils.IntAsyncBuilder.BaseIntTask; #endif +import speiger.src.collections.utils.ISizeProvider; import speiger.src.collections.utils.SanityChecks; /** @@ -292,6 +294,26 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE #endif #if OBJECT_ASYNC_MODULE +#if TYPE_OBJECT + /** + * Pours all elements of the Iterable down into a Array. + * @param action creates the final array that should be copied into. + * @return a new Builder with the ToArray function applied + */ + public ObjectAsyncBuilder TO_ARRAY(IntFunction action) { + return new ObjectAsyncBuilder<>(new ArrayTaskBRACES(iterable, action)); + } + +#else + /** + * Pours all elements of the Iterable down into a Array. + * @return a new Builder with the ToArray function applied + */ + public ObjectAsyncBuilder TO_ARRAY() { + return new ObjectAsyncBuilder<>(new ArrayTaskBRACES(iterable)); + } + +#endif #if ARRAY_LIST_FEATURE || LINKED_LIST_FEATURE /** * Pours all elements into a List that can be later @@ -729,6 +751,51 @@ public class ASYNC_BUILDER KEY_GENERIC_TYPE } } + private static class ArrayTask KEY_GENERIC_TYPE extends BaseObjectTask + { + ITERATOR KEY_GENERIC_TYPE iter; + COLLECTIONS.CollectionWrapper KEY_GENERIC_TYPE wrapper; +#if TYPE_OBJECT + IntFunction builder; + + public ArrayTask(ITERABLE KEY_GENERIC_TYPE iterable, IntFunction builder) { + this.builder = builder; +#else + + public ArrayTask(ITERABLE KEY_GENERIC_TYPE iterable) { +#endif + iter = iterable.iterator(); + ISizeProvider prov = ISizeProvider.of(iterable); + int size = prov == null ? -1 : prov.size(); + wrapper = size < 0 ? COLLECTIONS.wrapper() : COLLECTIONS.wrapper(size); + } + + @Override + protected boolean execute() throws Exception { + while(shouldRun() && iter.hasNext()) { + wrapper.add(iter.NEXT()); + } + if(!iter.hasNext()) { +#if TYPE_OBJECT + setResult(wrapper.TO_ARRAY(builder)); +#else + setResult(wrapper.TO_ARRAY()); +#endif + wrapper = null; + } + return false; + } + + @Override + protected void onCompletion() { + super.onCompletion(); + iter = null; +#if TYPE_OBJECT + builder = null; +#endif + } + } + private static class ForEachTask extends BaseObjectTask { ITERATOR KEY_GENERIC_TYPE iter; diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template index 19f2d53..70d59c1 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template @@ -5,7 +5,11 @@ import java.util.List; #if IARRAY_FEATURE import java.util.Objects; #endif -import java.util.Random; +#if JAVA_VERSION>=17 +import java.util.random.RANDOM; +#else +import java.util.RANDOM; +#endif import java.util.RandomAccess; #if IARRAY_FEATURE || TYPE_OBJECT import java.util.function.Consumer; @@ -157,7 +161,7 @@ public class LISTS * @Type(T) * @return the input list */ - public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE shuffle(LIST KEY_GENERIC_TYPE list, Random random) { + public static GENERIC_KEY_BRACES LIST KEY_GENERIC_TYPE shuffle(LIST KEY_GENERIC_TYPE list, RANDOM random) { int size = list.size(); #if IARRAY_FEATURE if(list instanceof IARRAY) { diff --git a/src/main/java/speiger/src/collections/utils/HashUtil.java b/src/main/java/speiger/src/collections/utils/HashUtil.java index 9e814f8..c2dd143 100644 --- a/src/main/java/speiger/src/collections/utils/HashUtil.java +++ b/src/main/java/speiger/src/collections/utils/HashUtil.java @@ -51,15 +51,7 @@ public class HashUtil * @return the input number rounded up to the next power of two */ public static int nextPowerOfTwo(int x) { - if(x != 0) { - x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - } - return x + 1; + return 1 << (32 - Integer.numberOfLeadingZeros(x - 1)); } /** @@ -69,16 +61,7 @@ public class HashUtil * @return the input number rounded up to the next power of two */ public static long nextPowerOfTwo(long x) { - if(x != 0) { - x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - x |= x >> 32; - } - return x + 1L; + return 1L << (64 - Long.numberOfLeadingZeros(x - 1)); } /**