New Features and Bugfixes.

- Fixed: ObjectArrayList.of was causing crashes because of a Poor
implementation.
- Added: Unsorted HashMaps/Sets now throw Concurrent exceptions if they
were modified during a rehash.
- Added: Array/Collection version of enqueue and enqueueFirst to
PriorityQueues.
- Added: fillBuffer function into PrimitiveLists which allow to optimize
JavaNio buffers if needed.
This commit is contained in:
Speiger 2021-10-11 19:05:54 +02:00
parent a38e7b069a
commit ffc34a131f
16 changed files with 212 additions and 10 deletions

View File

@ -1,5 +1,11 @@
# Changelog of versions
### Version 0.4.4
- Fixed: ObjectArrayList.of was causing crashes because of a Poor implementation.
- Added: Unsorted HashMaps/Sets now throw Concurrent exceptions if they were modified during a rehash.
- Added: Array/Collection version of enqueue and enqueueFirst to PriorityQueues.
- Added: fillBuffer function into PrimitiveLists which allow to optimize JavaNio buffers if needed.
### Version 0.4.3
- Added: Wrapper now support the Optimized Lambda replacer functions to improve performance.
- Added: FIFO Queue has now a minimum capacity and that is now checked more consistently.

View File

@ -72,13 +72,14 @@ repositories {
}
}
dependencies {
compile 'de.speiger:Primitive-Collections:0.4.3'
compile 'de.speiger:Primitive-Collections:0.4.4'
}
```
Direct:
| Version | Jar | Sources | Java Doc |
|--------- |------------------------------------------------------------------------------------------------------------------------------ |-------------------------------------------------------------------------------------------------------------------------------------- |-------------------------------------------------------------------------------------------------------------------------------------- |
| 0.4.4 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.4/Primitive-Collections-0.4.4.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.4/Primitive-Collections-0.4.4-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.4/Primitive-Collections-0.4.4-javadoc.jar) |
| 0.4.3 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.3/Primitive-Collections-0.4.3.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.3/Primitive-Collections-0.4.3-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.3/Primitive-Collections-0.4.3-javadoc.jar) |
| 0.4.2 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.2/Primitive-Collections-0.4.2.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.2/Primitive-Collections-0.4.2-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.2/Primitive-Collections-0.4.2-javadoc.jar) |
| 0.4.1 | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.1/Primitive-Collections-0.4.1.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.1/Primitive-Collections-0.4.1-sources.jar) | [Download](https://maven.speiger.com/repository/main/de/speiger/Primitive-Collections/0.4.1/Primitive-Collections-0.4.1-javadoc.jar) |

View File

@ -18,7 +18,7 @@ repositories {
}
archivesBaseName = 'Primitive Collections'
version = '0.4.3';
version = '0.4.4';
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'

View File

@ -153,6 +153,7 @@ public class GlobalVariables
addSimpleMapper("JAVA_UNARY_OPERATOR", type.isObject() ? "BinaryOperator" : type == ClassType.BOOLEAN ? "" : type.getCustomJDKType().getFileType()+"UnaryOperator");
addSimpleMapper("JAVA_SPLIT_ITERATOR", type.isPrimitiveBlocking() ? "Spliterator" : "Of"+type.getCustomJDKType().getFileType());
addSimpleMapper("JAVA_STREAM", type.isPrimitiveBlocking() ? "" : type.getCustomJDKType().getFileType()+"Stream");
addSimpleMapper("JAVA_BUFFER", type.getFileType()+"Buffer");
//Final Classes
addClassMapper("ARRAY_LIST", "ArrayList");

View File

@ -15,6 +15,7 @@ import java.util.function.UnaryOperator;
#if PRIMITIVES
import java.util.function.JAVA_PREDICATE;
import java.util.function.JAVA_UNARY_OPERATOR;
import java.nio.JAVA_BUFFER;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
@ -181,7 +182,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
*/
public static GENERIC_KEY_BRACES ARRAY_LIST KEY_GENERIC_TYPE of(Class<KEY_TYPE> c) {
ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES();
list.data = (KEY_TYPE[])ObjectArrays.newArray(c.getClass().getComponentType(), 0);
list.data = (KEY_TYPE[])ObjectArrays.newArray(c, 0);
return list;
}
@ -388,9 +389,15 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
size -= length;
return a;
}
#endif
#if PRIMITIVES
@Override
public void fillBuffer(JAVA_BUFFER buffer) {
buffer.put(data, 0, size);
}
#endif
/**
* A function to find if the Element is present in this list.
* @param o the element that is searched for

View File

@ -2,6 +2,8 @@ package speiger.src.collections.PACKAGE.lists;
#if TYPE_OBJECT
import java.util.Comparator;
#else if PRIMITIVES
import java.nio.JAVA_BUFFER;
#endif
import java.util.Collection;
import java.util.Iterator;
@ -637,6 +639,14 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
return d;
}
#endif
#if PRIMITIVES
@Override
public void fillBuffer(JAVA_BUFFER buffer) {
for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next)
buffer.put(entry.value);
}
#endif
@Override
@Primitive

View File

@ -1,5 +1,8 @@
package speiger.src.collections.PACKAGE.lists;
#if PRIMITIVES
import java.nio.JAVA_BUFFER;
#endif
import java.util.List;
#if !TYPE_OBJECT && !TYPE_BOOLEAN
import java.util.Objects;
@ -255,6 +258,14 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List
*/
public KEY_TYPE[] extractElements(int from, int to);
#if PRIMITIVES
/**
* Helper function that allows to fastFill a buffer reducing the duplication requirement
* @param buffer where the data should be stored in.
*/
public default void fillBuffer(JAVA_BUFFER buffer) { buffer.put(TO_ARRAY()); }
#endif
/** {@inheritDoc}
* <p>This default implementation delegates to the corresponding type-specific function.
* @deprecated Please use the corresponding type-specific function instead.

View File

@ -1,6 +1,7 @@
package speiger.src.collections.PACKAGE.maps.impl.customHash;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
@ -667,7 +668,10 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
VALUE_TYPE[] newValues = NEW_VALUE_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(strategy.equals(keys[--i], EMPTY_KEY_VALUE));
while(true) {
if(--i < 0) throw new ConcurrentModificationException("Map was modified during rehash");
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) break;
}
if(!strategy.equals(newKeys[pos = HashUtil.mix(strategy.hashCode(keys[i])) & newMask], EMPTY_KEY_VALUE))
while(!strategy.equals(newKeys[pos = (++pos & newMask)], EMPTY_KEY_VALUE));
newKeys[pos] = keys[i];

View File

@ -1,6 +1,7 @@
package speiger.src.collections.PACKAGE.maps.impl.hash;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
@ -627,7 +628,10 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
VALUE_TYPE[] newValues = NEW_VALUE_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(KEY_EQUALS_NULL(keys[--i]));
while(true) {
if(--i < 0) throw new ConcurrentModificationException("Map was modified during rehash");
if(KEY_EQUALS_NOT_NULL(keys[i])) break;
}
if(KEY_EQUALS_NOT_NULL(newKeys[pos = HashUtil.mix(KEY_TO_HASH(keys[i])) & newMask]))
while(KEY_EQUALS_NOT_NULL(newKeys[pos = (++pos & newMask)]));
newKeys[pos] = keys[i];

View File

@ -1,5 +1,12 @@
package speiger.src.collections.PACKAGE.queues;
#if TYPE_OBJECT
import java.util.Collection;
import java.util.Iterator;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
/**
* A Type Speciifc PriorityDeque or Dequeue interface to allow implementations like FIFO queues.
* @Type(T)
@ -11,6 +18,56 @@ public interface PRIORITY_DEQUEUE KEY_GENERIC_TYPE extends PRIORITY_QUEUE KEY_GE
* @param e the element that should be inserted into the first place
*/
public void enqueueFirst(KEY_TYPE e);
/**
* Method to mass insert a elements into the first Index of the PriorityDequeue.
* @param e the elements that should be inserted
*/
public default void enqueueAllFirst(KEY_TYPE... e) {
enqueueAllFirst(e, 0, e.length);
}
/**
* Method to mass insert a elements into the first Index of the PriorityDequeue.
* @param e the elements that should be inserted
* @param length the amount of elements that should be inserted
*/
public default void enqueueAllFirst(KEY_TYPE[] e, int length) {
enqueueAllFirst(e, 0, length);
}
/**
* Method to mass insert a elements into the first Index of the PriorityDequeue.
* @param e the elements that should be inserted
* @param offset the offset where in the array should be started
* @param length the amount of elements that should be inserted
*/
public default void enqueueAllFirst(KEY_TYPE[] e, int offset, int length) {
for(int i = 0;i<length;i++)
enqueueFirst(e[i+offset]);
}
/**
* Method to mass insert elements into first Index of the PriorityDequeue.
* @param c the elements that should be inserted from the Collection
*/
public default void enqueueAllFirst(COLLECTION KEY_GENERIC_TYPE c) {
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();)
enqueueFirst(iter.NEXT());
}
#if TYPE_OBJECT
/**
* Method to mass insert elements into first Index of the PriorityDequeue.
* This method exists to add support for Java Collections to make it more useable
* @param c the elements that should be inserted from the Collection
*/
public default void enqueueAllFirst(Collection<? extends CLASS_TYPE> c) {
for(Iterator<? extends CLASS_TYPE> iter = c.iterator();iter.hasNext();)
enqueueFirst(iter.next());
}
#endif
/**
* A Method to remove a element from the last place instead of the first
* @return the last element inserted

View File

@ -2,11 +2,14 @@ package speiger.src.collections.PACKAGE.queues;
#if TYPE_OBJECT
import java.util.Comparator;
import speiger.src.collections.objects.collections.ObjectIterator;
import java.util.Collection;
import java.util.Iterator;
#else
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERABLE;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
/**
* A Simple PriorityQueue (or Queue) interface that provides with the nessesary functions to interact with it, without cluttering with the Collection interface.
@ -33,6 +36,57 @@ public interface PRIORITY_QUEUE KEY_GENERIC_TYPE extends ITERABLE KEY_GENERIC_TY
* @param e the element that should be inserted
*/
public void enqueue(KEY_TYPE e);
/**
* Method to mass insert elements into the PriorityQueue
* @param e the elements that should be inserted
*/
public default void enqueueAll(KEY_TYPE... e) {
enqueueAll(e, 0, e.length);
}
/**
* Method to mass insert elements into the PriorityQueue
* @param e the elements that should be inserted
* @param length the amount of elements that should be inserted
*/
public default void enqueueAll(KEY_TYPE[] e, int length) {
enqueueAll(e, 0, length);
}
/**
* Method to mass insert elements into the PriorityQueue
* @param e the elements that should be inserted
* @param offset the offset where in the array should be started
* @param length the amount of elements that should be inserted
*/
public default void enqueueAll(KEY_TYPE[] e, int offset, int length) {
for(int i = 0;i<length;i++)
enqueue(e[i+offset]);
}
/**
* Method to mass insert elements into the PriorityQueue
* @param c the elements that should be inserted from the Collection
*/
public default void enqueueAll(COLLECTION KEY_GENERIC_TYPE c) {
for(ITERATOR KEY_GENERIC_TYPE iter = c.iterator();iter.hasNext();)
enqueue(iter.NEXT());
}
#if TYPE_OBJECT
/**
* Method to mass insert elements into the PriorityQueue
* This method exists to add support for Java Collections to make it more useable
* @param c the elements that should be inserted from the Collection
*/
public default void enqueueAll(Collection<? extends CLASS_TYPE> c) {
for(Iterator<? extends CLASS_TYPE> iter = c.iterator();iter.hasNext();)
enqueue(iter.next());
}
#endif
/**
* Method to extract a element from the PriorityQueue
* @return a element from the Queue

View File

@ -2,6 +2,7 @@ package speiger.src.collections.PACKAGE.sets;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
@ -429,7 +430,10 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(strategy.equals(keys[--i], EMPTY_KEY_VALUE));
while(true) {
if(--i < 0) throw new ConcurrentModificationException("Set was modified during rehash");
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) break;
}
if(!strategy.equals(newKeys[pos = HashUtil.mix(KEY_TO_HASH(keys[i])) & newMask], EMPTY_KEY_VALUE))
while(!strategy.equals(newKeys[pos = (++pos & newMask)], EMPTY_KEY_VALUE));
newKeys[pos] = keys[i];

View File

@ -2,6 +2,7 @@ package speiger.src.collections.PACKAGE.sets;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
@ -461,7 +462,10 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
int newMask = newSize - 1;
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
while(KEY_EQUALS_NULL(keys[--i]));
while(true) {
if(--i < 0) throw new ConcurrentModificationException("Set was modified during rehash");
if(KEY_EQUALS_NOT_NULL(keys[i])) break;
}
if(KEY_EQUALS_NOT_NULL(newKeys[pos = HashUtil.mix(KEY_TO_HASH(keys[i])) & newMask]))
while(KEY_EQUALS_NOT_NULL(newKeys[pos = (++pos & newMask)]));
newKeys[pos] = keys[i];

View File

@ -5,6 +5,9 @@ import java.util.Objects;
import java.util.Random;
import java.util.RandomAccess;
import java.util.function.Consumer;
#if PRIMITIVES
import java.nio.JAVA_BUFFER;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
@ -204,7 +207,11 @@ public class LISTS
a[offset] = element;
return a;
}
#if PRIMITIVES
@Override
public void fillBuffer(JAVA_BUFFER buffer) { buffer.put(element); }
#endif
@Override
public void removeElements(int from, int to) { throw new UnsupportedOperationException(); }
#if TYPE_OBJECT
@ -357,6 +364,9 @@ public class LISTS
@Override
public <K> K[] extractElements(int from, int to, Class<K> clz) { synchronized(mutex) { return l.extractElements(from, to, clz); } }
#endif
#if PRIMITIVES
public void fillBuffer(JAVA_BUFFER buffer) { synchronized(mutex) { l.fillBuffer(buffer); } }
#endif
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {
@ -469,6 +479,10 @@ public class LISTS
@Override
public <K> K[] extractElements(int from, int to, Class<K> clz) { throw new UnsupportedOperationException(); }
#endif
#if PRIMITIVES
public void fillBuffer(JAVA_BUFFER buffer) { l.fillBuffer(buffer); }
#endif
@Override
public LIST_ITERATOR KEY_GENERIC_TYPE listIterator() {

View File

@ -1,11 +1,13 @@
package speiger.src.collections.PACKAGE.utils;
#if TYPE_OBJECT
import java.util.Collection;
import java.util.Comparator;
import java.util.function.Consumer;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
@ -92,6 +94,14 @@ public class PRIORITY_QUEUES
public void clear() { synchronized(mutex) { queue.clear(); } }
@Override
public void enqueue(KEY_TYPE e) { synchronized(mutex) { queue.enqueue(e); } }
@Override
public void enqueueAll(KEY_TYPE[] e, int offset, int length) { synchronized(mutex) { queue.enqueueAll(e, offset, length); } }
@Override
public void enqueueAll(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { queue.enqueueAll(c); } }
#if TYPE_OBJECT
@Override
public void enqueueAll(Collection<? extends CLASS_TYPE> c) { synchronized(mutex) { queue.enqueueAll(c); } }
#endif
@Override
public KEY_TYPE dequeue() { synchronized(mutex) { return queue.dequeue(); } }
@Override
@ -143,6 +153,14 @@ public class PRIORITY_QUEUES
@Override
public void enqueueFirst(KEY_TYPE e) { synchronized(mutex) { dequeue.enqueueFirst(e); } }
@Override
public void enqueueAllFirst(KEY_TYPE[] e, int offset, int length) { synchronized(mutex) { dequeue.enqueueAllFirst(e, offset, length); } }
@Override
public void enqueueAllFirst(COLLECTION KEY_GENERIC_TYPE c) { synchronized(mutex) { dequeue.enqueueAllFirst(c); } }
#if TYPE_OBJECT
@Override
public void enqueueAllFirst(Collection<? extends CLASS_TYPE> c) { synchronized(mutex) { dequeue.enqueueAllFirst(c); } }
#endif
@Override
public KEY_TYPE dequeueLast() { synchronized(mutex) { return dequeue.dequeueLast(); } }
@Override

View File

@ -22,6 +22,13 @@ public class ObjectArrayListTest
testCastable(ObjectArrayList.wrap("Test", "Testing", "Testing stuff"), true);
}
@Test
public void testEmptyCreation()
{
ObjectArrayList<String> test = ObjectArrayList.of(String.class);
Assert.assertTrue(test.isCastable());
}
public <T> void testCastable(IObjectArray<T> castable, boolean result)
{
Assert.assertTrue(castable.isCastable() == result);