Primitive-Collections/src/builder/resources/speiger/assets/collections/templates/queues/HeapPriorityQueue.template

335 lines
9.2 KiB
Plaintext

package speiger.src.collections.PACKAGE.queues;
import java.util.Arrays;
import java.util.NoSuchElementException;
#if TYPE_OBJECT
import java.util.Comparator;
import java.util.function.Consumer;
#endif
import java.util.Objects;
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
import speiger.src.collections.PACKAGE.functions.CONSUMER;
#endif
import speiger.src.collections.PACKAGE.functions.consumer.BI_OBJECT_CONSUMER;
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
import speiger.src.collections.PACKAGE.utils.ARRAYS;
/**
* A Simple Heap base Priority Queue implementation
* It is a ArrayBased Alternative to TreeSets that has less object allocations
* @Type(T)
*/
public class HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE implements PRIORITY_QUEUE KEY_GENERIC_TYPE
{
/** The Backing Array */
protected transient KEY_TYPE[] array = EMPTY_KEY_ARRAY;
/** The Amount of elements stored within the array */
protected int size;
/** The Sorter of the Array */
protected COMPARATOR KEY_SUPER_GENERIC_TYPE comparator;
/**
* Default Constructor
*/
public HEAP_PRIORITY_QUEUE() {
this(0, null);
}
/**
* Constructor using custom sorter
* @param comp Comparator to sort the Array. Can be null
*/
public HEAP_PRIORITY_QUEUE(COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this(0, comp);
}
/**
* Constructor with a Min Capacity
* @param size the initial capacity of the backing array
* @throws IllegalStateException if the initial size is smaller 0
*/
public HEAP_PRIORITY_QUEUE(int size) {
this(size, null);
}
/**
* Constructor with a Min Capacity and custom Sorter
* @param size the initial capacity of the backing array
* @param comp Comparator to sort the Array. Can be null
* @throws IllegalStateException if the initial size is smaller 0
*/
public HEAP_PRIORITY_QUEUE(int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
if(size > 0) array = NEW_KEY_ARRAY(size);
this.size = size;
comparator = comp;
}
/**
* Constructor using a initial array
* @param array the Array that should be used
*/
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array) {
this(array, array.length);
}
/**
* Constructor using a initial array
* @param array the Array that should be used
* @param size the amount of elements found within the array
* @throws NegativeArraySizeException if size is smaller then 0
*/
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size) {
this.array = Arrays.copyOf(array, size);
this.size = size;
ARRAYS.heapify(array, size, null);
}
/**
* Constructor using a initial array and a custom sorter
* @param array the Array that should be used
* @param comp Comparator to sort the Array. Can be null
*/
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this(array, array.length, comp);
}
/**
* Constructor using a initial array and a custom sorter
* @param array the Array that should be used
* @param size the amount of elements found within the array
* @param comp Comparator to sort the Array. Can be null
* @throws NegativeArraySizeException if size is smaller then 0
*/
public HEAP_PRIORITY_QUEUE(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
this.array = Arrays.copyOf(array, size);
this.size = size;
comparator = comp;
ARRAYS.heapify(array, size, comp);
}
/**
* Constructor using a Collection
* @param c the Collection that should be used
*/
public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c) {
array = CAST_KEY_ARRAY c.TO_ARRAY();
size = c.size();
ARRAYS.heapify(array, size, null);
}
/**
* Constructor using a Collection and a custom sorter
* @param c the Collection that should be used
* @param comp Comparator to sort the Array. Can be null
*/
public HEAP_PRIORITY_QUEUE(COLLECTION KEY_GENERIC_TYPE c, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
array = CAST_KEY_ARRAY c.TO_ARRAY();
size = c.size();
comparator = comp;
ARRAYS.heapify(array, size, comp);
}
/**
* Wrapping method to help serialization
* @param array the array that should be used
* @Type(T)
* @return a HeapPriorityQueue containing the original input array
*/
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array) {
return wrap(array, array.length);
}
/**
* Wrapping method to help serialization
* @param array the array that should be used
* @param size the amount of elements within the array
* @Type(T)
* @return a HeapPriorityQueue containing the original input array
*/
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size) {
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES();
queue.array = array;
queue.size = size;
ARRAYS.heapify(array, size, null);
return queue;
}
/**
* Wrapping method to help serialization, using a custom sorter
* @param array the array that should be used
* @param comp Comparator to sort the Array. Can be null
* @Type(T)
* @return a HeapPriorityQueue containing the original input array
*/
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
return wrap(array, array.length, comp);
}
/**
* Wrapping method to help serialization, using a custom sorter
* @param array the array that should be used
* @param size the amount of elements within the array
* @param comp Comparator to sort the Array. Can be null
* @Type(T)
* @return a HeapPriorityQueue containing the original input array
*/
public static GENERIC_KEY_BRACES HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE wrap(KEY_TYPE[] array, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) {
HEAP_PRIORITY_QUEUE KEY_GENERIC_TYPE queue = new HEAP_PRIORITY_QUEUEBRACES(comp);
queue.array = array;
queue.size = size;
ARRAYS.heapify(array, size, comp);
return queue;
}
@Override
public int size() {
return size;
}
@Override
public void clear() {
#if TYPE_OBJECT
Arrays.fill(array, null);
#endif
size = 0;
}
@Override
public ITERATOR KEY_GENERIC_TYPE iterator() {
return new Iter();
}
@Override
public void enqueue(KEY_TYPE e) {
if(size == array.length) array = Arrays.copyOf(array, size + 1);
array[size++] = e;
ARRAYS.shiftUp(array, size-1, comparator);
}
@Override
public KEY_TYPE dequeue() {
if(size <= 0) throw new NoSuchElementException();
KEY_TYPE value = array[0];
array[0] = array[--size];
#if TYPE_OBJECT
array[size] = null;
#endif
if(size != 0) ARRAYS.shiftDown(array, size, 0, comparator);
return value;
}
@Override
public KEY_TYPE peek(int index) {
if(index < 0 || index >= size) throw new NoSuchElementException();
return array[index];
}
@Override
public boolean removeFirst(KEY_TYPE e) {
for(int i = 0;i<size;i++)
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false;
}
@Override
public boolean removeLast(KEY_TYPE e) {
for(int i = size-1;i>=0;i--)
if(KEY_EQUALS(e, array[i])) return removeIndex(i);
return false;
}
@Override
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(dequeue());
}
@Override
public <E> void forEach(E input, BI_OBJECT_CONSUMER KEY_VALUE_SPECIAL_GENERIC_TYPE action) {
Objects.requireNonNull(action);
for(int i = 0,m=size;i<m;i++) action.accept(dequeue(), input);
}
@Override
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) return true;
}
return false;
}
@Override
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) return false;
}
return true;
}
@Override
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(!filter.TEST_VALUE(array[i])) return false;
}
return true;
}
@Override
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
Objects.requireNonNull(filter);
for(int i = 0;i<size;i++) {
if(filter.TEST_VALUE(array[i])) {
KEY_TYPE data = array[i];
removeIndex(i);
return data;
}
}
return EMPTY_VALUE;
}
protected boolean removeIndex(int index) {
array[index] = array[--size];
#if TYPE_OBJECT
array[size] = null;
#endif
if(size != index) ARRAYS.shiftDown(array, size, index, comparator);
return true;
}
@Override
public void onChanged() {
if(size <= 0) return;
ARRAYS.shiftDown(array, size, 0, comparator);
}
@Override
public COMPARATOR KEY_SUPER_GENERIC_TYPE comparator() {
return comparator;
}
@Override
public KEY_GENERIC_SPECIAL_TYPE KEY_SPECIAL_TYPE[] TO_ARRAY(KEY_SPECIAL_TYPE[] input) {
if(input == null || input.length < size()) input = NEW_SPECIAL_KEY_ARRAY(size());
System.arraycopy(array, 0, input, 0, size());
return input;
}
private class Iter implements ITERATOR KEY_GENERIC_TYPE {
@Override
public boolean hasNext() {
return !isEmpty();
}
@Override
public KEY_TYPE NEXT() {
return dequeue();
}
}
}