From c0fef15e64b97beb122fa03cfe627c2efde192a8 Mon Sep 17 00:00:00 2001 From: Speiger Date: Thu, 24 Jun 2021 13:17:48 +0200 Subject: [PATCH] More Fixes - Fixed: containsKey & containsValue in HashMaps were deprecated for Object Variants. - Fixed: HashMap wasn't deleting Keys & Values references when removing a Object - Fixed: AVLTreeSet didn't balance properly. - Changed: EnumMap no longer tries to access SharedSecrets since its gone in java11 --- Changelog.md | 8 +++++- build.gradle | 2 +- .../speiger/src/builder/GlobalVariables.java | 9 ++++++- .../customHash/OpenCustomHashMap.template | 26 ++++++++++++++++--- .../maps/impl/hash/OpenHashMap.template | 26 ++++++++++++++++--- .../templates/maps/impl/misc/EnumMap.template | 7 ----- .../maps/impl/tree/AVLTreeMap.template | 4 +-- 7 files changed, 64 insertions(+), 18 deletions(-) diff --git a/Changelog.md b/Changelog.md index 5f1dc91..892b43a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,13 @@ # Changelog of versions -## Version 0.3.0 (Breaking 0.2.0) +### Version 0.3.1 +- Fixed: containsKey & containsValue in HashMaps were deprecated for Object Variants. +- Fixed: HashMap wasn't deleting Keys & Values references when removing a Object +- Fixed: AVLTreeSet didn't balance properly. +- Changed: EnumMap no longer tries to access SharedSecrets since its gone in java11 + +### Version 0.3.0 (Breaking 0.2.0) - Added: Stack.isEmpty was missing - Changed: remove/removeLast/enqueue/enqueueFirst no longer use Type Suffixes - Removed: Suffixes for unmodifiable & synchronize functions. diff --git a/build.gradle b/build.gradle index 0965150..df65373 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ repositories { } archivesBaseName = 'Primitive Collections' -version = '0.3.0'; +version = '0.3.1-SNAPSHOT'; sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' diff --git a/src/builder/java/speiger/src/builder/GlobalVariables.java b/src/builder/java/speiger/src/builder/GlobalVariables.java index f89e2ec..a42c994 100644 --- a/src/builder/java/speiger/src/builder/GlobalVariables.java +++ b/src/builder/java/speiger/src/builder/GlobalVariables.java @@ -78,6 +78,8 @@ public class GlobalVariables addAnnontion("@PrimitiveOverride", "@Override"); addSimpleMapper("@PrimitiveDoc", ""); addAnnontion("@Primitive", "@Deprecated"); + addValueAnnontion("@ValuePrimitiveOverride", "@Override"); + addValueAnnontion("@ValuePrimitive", "@Deprecated"); return this; } @@ -254,7 +256,6 @@ public class GlobalVariables { flags.add("TYPE_"+type.getCapType()); flags.add("VALUE_"+valueType.getCapType()); -// flags.add("UNSAVE_ENUM"); //if we want to use shared constants... Not compile save if(type == valueType) flags.add("SAME_TYPE"); if(type.hasFunction(valueType)) flags.add("JDK_FUNCTION"); if(!type.needsCustomJDKType()) flags.add("JDK_TYPE"); @@ -335,6 +336,12 @@ public class GlobalVariables else operators.add(new SimpleMapper(type.name()+"["+pattern+"]", pattern, value)); } + private void addValueAnnontion(String pattern, String value) + { + if(valueType == ClassType.OBJECT) operators.add(new LineMapper(valueType.name()+"["+pattern+"]", pattern)); + else operators.add(new SimpleMapper(valueType.name()+"["+pattern+"]", pattern, value)); + } + private void addComment(String pattern, String value) { if(type == ClassType.OBJECT) operators.add(new InjectMapper(type.name()+"["+pattern+"]", pattern, value).removeBraces()); 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 d178323..fc9f90f 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 @@ -36,6 +36,7 @@ import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.ObjectSet; import speiger.src.collections.utils.HashUtil; +import speiger.src.collections.utils.ITrimmable; /** * A Type Specific HashMap that allows for custom HashControl. @@ -43,7 +44,7 @@ import speiger.src.collections.utils.HashUtil; * @Type(T) * @ValueType(V) */ -public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE +public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements ITrimmable { /** The Backing keys array */ protected transient KEY_TYPE[] keys; @@ -262,7 +263,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL #endif @Override - @Deprecated + @Primitive public boolean containsKey(Object key) { #if !TYPE_OBJECT return key instanceof CLASS_TYPE && findIndex(CLASS_TO_KEY(key)) >= 0; @@ -282,7 +283,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL #endif @Override - @Deprecated + @ValuePrimitive public boolean containsValue(Object value) { if((value == null && VALUE_EQUALS(values[nullIndex], getDefaultReturnValue())) || EQUALS_VALUE_TYPE(values[nullIndex], value)) return true; for(int i = nullIndex-1;i >= 0;i--) @@ -520,6 +521,23 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL Arrays.fill(values, EMPTY_VALUE); } + @Override + public boolean trim(int size) { + int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); + if(request >= size || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false; + try { + rehash(request); + } + catch(OutOfMemoryError noMemory) { return false; } + return true; + } + + @Override + public void clearAndTrim(int size) { + clear(); + trim(size); + } + #if !TYPE_OBJECT protected int findIndex(KEY_TYPE key) { if(strategy.equals(key, EMPTY_KEY_VALUE)) return containsNull ? nullIndex : -(nullIndex + 1); @@ -549,6 +567,8 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL protected VALUE_TYPE removeIndex(int pos) { VALUE_TYPE value = values[pos]; + keys[pos] = EMPTY_KEY_VALUE; + values[pos] = EMPTY_VALUE; size--; onNodeRemoved(pos); shiftKeys(pos); 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 36d5df1..832f687 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 @@ -35,6 +35,7 @@ import speiger.src.collections.objects.collections.ObjectIterator; import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.ObjectSet; import speiger.src.collections.utils.HashUtil; +import speiger.src.collections.utils.ITrimmable; /** * A Type Specific Custom implementation of the HashMap @@ -43,7 +44,7 @@ import speiger.src.collections.utils.HashUtil; * @Type(T) * @ValueType(V) */ -public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE +public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements ITrimmable { /** The Backing keys array */ protected transient KEY_TYPE[] keys; @@ -237,7 +238,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE #endif @Override - @Deprecated + @Primitive public boolean containsKey(Object key) { return findIndex(key) >= 0; } @@ -253,7 +254,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE #endif @Override - @Deprecated + @ValuePrimitive public boolean containsValue(Object value) { if((value == null && VALUE_EQUALS(values[nullIndex], getDefaultReturnValue())) || EQUALS_VALUE_TYPE(values[nullIndex], value)) return true; for(int i = nullIndex-1;i >= 0;i--) @@ -481,6 +482,23 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE Arrays.fill(values, EMPTY_VALUE); } + @Override + public boolean trim(int size) { + int request = Math.max(minCapacity, HashUtil.nextPowerOfTwo((int)Math.ceil(size / loadFactor))); + if(request >= size || this.size > Math.min((int)Math.ceil(request * loadFactor), request - 1)) return false; + try { + rehash(request); + } + catch(OutOfMemoryError noMemory) { return false; } + return true; + } + + @Override + public void clearAndTrim(int size) { + clear(); + trim(size); + } + #if !TYPE_OBJECT protected int findIndex(KEY_TYPE key) { if(KEY_EQUALS_NULL(key)) return containsNull ? nullIndex : -(nullIndex + 1); @@ -509,6 +527,8 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE protected VALUE_TYPE removeIndex(int pos) { VALUE_TYPE value = values[pos]; + keys[pos] = EMPTY_KEY_VALUE; + values[pos] = EMPTY_VALUE; size--; onNodeRemoved(pos); shiftKeys(pos); diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/impl/misc/EnumMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/impl/misc/EnumMap.template index 5090dbb..b1aa0b4 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/impl/misc/EnumMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/impl/misc/EnumMap.template @@ -16,9 +16,6 @@ import speiger.src.collections.objects.maps.abstracts.ABSTRACT_MAP; import speiger.src.collections.objects.maps.interfaces.MAP; import speiger.src.collections.objects.sets.AbstractObjectSet; import speiger.src.collections.objects.sets.ObjectSet; -#if UNSAVE_ENUM -import sun.misc.SharedSecrets; -#endif /** * A Type Specific EnumMap implementation that allows for Primitive Values. @@ -215,11 +212,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE protected boolean isSet(int index) { return (present[index >> 6] & (1L << index)) != 0; } private static > K[] getKeyUniverse(Class keyType) { -#if UNSAVE_ENUM - return SharedSecrets.getJavaLangAccess().getEnumConstantsShared(keyType); -#else return keyType.getEnumConstants(); -#endif } class EntrySet extends AbstractObjectSet { diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/impl/tree/AVLTreeMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/impl/tree/AVLTreeMap.template index ca70fa4..7d6e443 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/impl/tree/AVLTreeMap.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/impl/tree/AVLTreeMap.template @@ -1931,9 +1931,9 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_ #endif int getHeight() { return state; } - void updateHeight() { state = (1 + Math.max(left == null ? 0 : left.getHeight(), right == null ? 0 : right.getHeight())); } + void updateHeight() { state = (1 + Math.max(left == null ? -1 : left.getHeight(), right == null ? -1 : right.getHeight())); } - int getBalance() { return (left == null ? 0 : left.getHeight()) - (right == null ? 0 : right.getBalance()); } + int getBalance() { return (left == null ? -1 : left.getHeight()) - (right == null ? -1 : right.getBalance()); } boolean needsSuccessor() { return left != null && right != null; }