forked from Speiger/Primitive-Collections
Next big batch of features.
-Added: Tests for IntSortedSet, IntNavigableSet. -Added: Test Classes for: Open/Custom/Linked HashSet, TreeSets, ArraySet -Changed: MemFreeMergeSort got improved by a lot. -Fixed: Bugs that the tests uncovered. -Note: TreeSets still have issues. But every other collection type is fixed.
This commit is contained in:
parent
0123cb8937
commit
c0c719f2b6
|
@ -63,6 +63,7 @@ public class GlobalVariables
|
|||
addInjectMapper("CLASS_TO_KEY", "(("+type.getClassType()+")%s)."+type.getKeyType()+"Value()").removeBraces();
|
||||
addSimpleMapper("APPLY", "applyAs"+type.getCustomJDKType().getNonFileType());
|
||||
addInjectMapper("TO_HASH", type.isObject() ? "%s.hashCode()" : type.getClassType()+".hashCode(%s)").removeBraces();
|
||||
addInjectMapper("NEW_KEY_ARRAY", type.isObject() ? "(KEY_TYPE[])new Object[%s]" : "new KEY_TYPE[%s]").removeBraces();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,8 +75,8 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
|||
@Override
|
||||
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) {
|
||||
Objects.requireNonNull(c);
|
||||
for(KEY_TYPE e : this)
|
||||
if(!c.contains(e))
|
||||
for(KEY_TYPE e : c)
|
||||
if(!contains(e))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -92,8 +92,8 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
|||
@Primitive
|
||||
public boolean containsAny(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
for(KEY_TYPE e : this)
|
||||
if(c.contains(KEY_TO_OBJ(e)))
|
||||
for(Object e : c)
|
||||
if(contains(e))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -107,8 +107,8 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
|||
@Override
|
||||
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) {
|
||||
Objects.requireNonNull(c);
|
||||
for(KEY_TYPE e : this)
|
||||
if(c.contains(e))
|
||||
for(KEY_TYPE e : c)
|
||||
if(contains(e))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -168,6 +168,11 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
|||
@Override
|
||||
public boolean retainAll(COLLECTION KEY_GENERIC_TYPE c) {
|
||||
Objects.requireNonNull(c);
|
||||
if(c.isEmpty()) {
|
||||
boolean modified = !isEmpty();
|
||||
clear();
|
||||
return modified;
|
||||
}
|
||||
boolean modified = false;
|
||||
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
|
||||
if(!c.contains(iter.NEXT())) {
|
||||
|
|
|
@ -76,11 +76,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
|||
* Creates a new ArrayList with the specific requested size
|
||||
*/
|
||||
public ARRAY_LIST(int size) {
|
||||
#if TYPE_OBJECT
|
||||
data = (KEY_TYPE[])new Object[size];
|
||||
#else
|
||||
data = new KEY_TYPE[size];
|
||||
#endif
|
||||
data = NEW_KEY_ARRAY(size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -358,49 +354,6 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
|||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* A function to check if all elements requested are present in the other collection.
|
||||
* This function might delegate to a more appropiate function if nessesary
|
||||
* @param c the collection that should be checked
|
||||
* @return true if the collection contains all elements in this list
|
||||
* @throws NullPointerException if the collection is null
|
||||
* @deprecated if the collection is type-specific
|
||||
*/
|
||||
@Override
|
||||
@Primitive
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
for(int i = 0,m=size;i<m;i++) {
|
||||
#if !TYPE_OBJECT
|
||||
if(!c.contains(KEY_TO_OBJ(data[i]))) return false;
|
||||
#else
|
||||
if(!c.contains(data[i])) return false;
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to check if any element of this list is present in the collection.
|
||||
* This function might delegate to a more appropiate function if nessesary
|
||||
* @param c the collection that should be checked
|
||||
* @return true if the collection contains any elements in this list
|
||||
* @throws NullPointerException if the collection is null
|
||||
* @deprecated if the collection is type-specific
|
||||
*/
|
||||
@Override
|
||||
@Primitive
|
||||
public boolean containsAny(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
for(int i = 0,m=size;i<m;i++) {
|
||||
#if !TYPE_OBJECT
|
||||
if(c.contains(KEY_TO_OBJ(data[i]))) return true;
|
||||
#else
|
||||
if(c.contains(data[i])) return true;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to find if the Element is present in this list.
|
||||
|
@ -485,38 +438,7 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
|||
else ARRAYS.unstableSort((Comparable[])data, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* A Type-Specific implementation of containsAll. This implementation iterates over all elements and checks all elements are present in the other collection.
|
||||
* @param the collection that should be checked if it contains all elements.
|
||||
* @return true if all elements were found in the collection
|
||||
* @throws NullPointerException if the collection is null
|
||||
*/
|
||||
@Override
|
||||
public boolean containsAll(COLLECTION KEY_GENERIC_TYPE c) {
|
||||
Objects.requireNonNull(c);
|
||||
for(int i = 0,m=size;i<m;i++) {
|
||||
if(!c.contains(data[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation iterates over the elements of the collection and checks if they are stored in this collection.
|
||||
* @param c the elements that should be checked for
|
||||
* @return true if any element is in this collection
|
||||
* @throws NullPointerException if the collection is null
|
||||
*/
|
||||
@Override
|
||||
public boolean containsAny(COLLECTION KEY_GENERIC_TYPE c) {
|
||||
Objects.requireNonNull(c);
|
||||
for(int i = 0,m=size;i<m;i++) {
|
||||
if(c.contains(data[i])) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
#else
|
||||
/**
|
||||
* A Type Specific implementation of the Collection#contains function.
|
||||
* @param the element that is searched for.
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
package speiger.src.collections.PACKAGE.sets;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Collection;
|
||||
#if TYPE_OBJECT
|
||||
import java.util.Comparator;
|
||||
#endif
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
|
||||
#if !TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
||||
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
|
||||
#if !TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.utils.ITERATORS;
|
||||
#endif
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
|
||||
public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
|
||||
{
|
||||
|
@ -30,6 +38,36 @@ public class AVL_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
|
|||
public AVL_TREE_SET() {
|
||||
}
|
||||
|
||||
public AVL_TREE_SET(KEY_TYPE[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
public AVL_TREE_SET(KEY_TYPE[] array, int offset, int length) {
|
||||
SanityChecks.checkArrayCapacity(array.length, offset, length);
|
||||
for(int i = 0;i<length;i++) add(array[offset+i]);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public AVL_TREE_SET(Collection<? extends CLASS_TYPE> collection) {
|
||||
addAll(collection);
|
||||
}
|
||||
|
||||
public AVL_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection) {
|
||||
addAll(collection);
|
||||
}
|
||||
|
||||
public AVL_TREE_SET(Iterator<CLASS_TYPE> iterator) {
|
||||
#if !TYPE_OBJECT
|
||||
this(ITERATORS.wrap(iterator));
|
||||
#else
|
||||
while(iterator.hasNext()) add(iterator.next());
|
||||
#endif
|
||||
}
|
||||
|
||||
public AVL_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
|
||||
while(iterator.hasNext()) add(iterator.NEXT());
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; }
|
||||
|
|
|
@ -31,11 +31,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
}
|
||||
|
||||
public ARRAY_SET(int capacity) {
|
||||
#if TYPE_OBJECT
|
||||
data = (KEY_TYPE[])new Object[capacity];
|
||||
#else
|
||||
data = new KEY_TYPE[capacity];
|
||||
#endif
|
||||
data = NEW_KEY_ARRAY(capacity);
|
||||
}
|
||||
|
||||
public ARRAY_SET(KEY_TYPE[] array) {
|
||||
|
@ -43,7 +39,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
}
|
||||
|
||||
public ARRAY_SET(KEY_TYPE[] array, int length) {
|
||||
data = array;
|
||||
data = Arrays.copyOf(array, length);
|
||||
size = length;
|
||||
}
|
||||
|
||||
|
@ -94,7 +90,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
else if(index != 0) {
|
||||
o = data[index];
|
||||
System.arraycopy(data, 0, data, 1, index);
|
||||
data[index] = o;
|
||||
data[0] = o;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -110,7 +106,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
else if(index != size - 1) {
|
||||
o = data[index];
|
||||
System.arraycopy(data, index+1, data, index, size - index);
|
||||
data[size] = o;
|
||||
data[size-1] = o;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -121,7 +117,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
if(index > 0) {
|
||||
o = data[index];
|
||||
System.arraycopy(data, 0, data, 1, index);
|
||||
data[index] = o;
|
||||
data[0] = o;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -132,8 +128,8 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
int index = findIndex(o);
|
||||
if(index != -1 && index != size - 1) {
|
||||
o = data[index];
|
||||
System.arraycopy(data, index+1, data, index, size - index);
|
||||
data[size] = o;
|
||||
System.arraycopy(data, index+1, data, index, size - index - 1);
|
||||
data[size-1] = o;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -169,7 +165,11 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
public boolean remove(KEY_TYPE o) {
|
||||
int index = findIndex(o);
|
||||
if(index != -1) {
|
||||
System.arraycopy(data, index+1, data, index, size - index);
|
||||
size--;
|
||||
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
||||
#if TYPE_OBJECT
|
||||
data[size] = EMPTY_VALUE;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -180,8 +180,11 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
public boolean remove(Object o) {
|
||||
int index = findIndex(o);
|
||||
if(index != -1) {
|
||||
System.arraycopy(data, index+1, data, index, size - index);
|
||||
data[size-1] = EMPTY_VALUE;
|
||||
size--;
|
||||
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
||||
#if TYPE_OBJECT
|
||||
data[size] = EMPTY_VALUE;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -192,7 +195,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
public KEY_TYPE POLL_FIRST_KEY() {
|
||||
if(size == 0) throw new NoSuchElementException();
|
||||
KEY_TYPE result = data[0];
|
||||
System.arraycopy(data, 1, data, 0, size);
|
||||
System.arraycopy(data, 1, data, 0, size - 1);
|
||||
#if TYPE_OBJECT
|
||||
data[size-1] = EMPTY_VALUE;
|
||||
#endif
|
||||
|
@ -202,12 +205,13 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
@Override
|
||||
public KEY_TYPE POLL_LAST_KEY() {
|
||||
if(size == 0) throw new NoSuchElementException();
|
||||
size--;
|
||||
#if TYPE_OBJECT
|
||||
KEY_TYPE result = data[size-1];
|
||||
data[size-1] = EMPTY_VALUE;
|
||||
KEY_TYPE result = data[size];
|
||||
data[size] = EMPTY_VALUE;
|
||||
return result;
|
||||
#else
|
||||
return data[--size];
|
||||
return data[size];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -242,14 +246,14 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
int fromIndex = findIndex(fromElement);
|
||||
int toIndex = findIndex(toElement);
|
||||
if(fromIndex == -1 || toIndex == -1) throw new NoSuchElementException();
|
||||
return new SubSet(fromIndex, toIndex - fromIndex);
|
||||
return new SubSet(fromIndex, toIndex - fromIndex + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) {
|
||||
int toIndex = findIndex(toElement);
|
||||
if(toIndex == -1) throw new NoSuchElementException();
|
||||
return new SubSet(0, toIndex);
|
||||
return new SubSet(0, toIndex+1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -283,13 +287,15 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
this.length = length;
|
||||
}
|
||||
|
||||
int end() { return offset+length; }
|
||||
|
||||
@Override
|
||||
public boolean add(KEY_TYPE o) {
|
||||
int index = findIndex(o);
|
||||
if(index != -1) {
|
||||
if(index == -1) {
|
||||
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
|
||||
System.arraycopy(data, (offset+length), data, (offset+length)+1, size-(offset+length));
|
||||
data[offset+length] = o;
|
||||
if(end() != size) System.arraycopy(data, end(), data, end()+1, size-(offset+length));
|
||||
data[end()] = o;
|
||||
size++;
|
||||
length++;
|
||||
return true;
|
||||
|
@ -321,8 +327,8 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
int index = findIndex(o);
|
||||
if(index == -1) {
|
||||
if(data.length == size) data = Arrays.copyOf(data, size == 0 ? 2 : size * 2);
|
||||
System.arraycopy(data, (offset+length)+1, data, (offset+length), size-(offset+length));
|
||||
data[offset+length] = o;
|
||||
System.arraycopy(data, end()+1, data, end(), size-end());
|
||||
data[end()] = o;
|
||||
size++;
|
||||
length++;
|
||||
return true;
|
||||
|
@ -338,7 +344,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
@Override
|
||||
public boolean moveToFirst(KEY_TYPE o) {
|
||||
int index = findIndex(o);
|
||||
if(index != -1 && index != offset) {
|
||||
if(index > offset) {
|
||||
o = data[index];
|
||||
System.arraycopy(data, offset, data, offset+1, index-offset);
|
||||
data[offset] = o;
|
||||
|
@ -350,10 +356,10 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
@Override
|
||||
public boolean moveToLast(KEY_TYPE o) {
|
||||
int index = findIndex(o);
|
||||
if(index != -1 && index != (offset+length) - 1) {
|
||||
if(index != -1 && index < end()-1) {
|
||||
o = data[index];
|
||||
System.arraycopy(data, offset+1, data, offset, index-offset);
|
||||
data[offset+length] = o;
|
||||
System.arraycopy(data, index+1, data, index, end()-index-1);
|
||||
data[end()-1] = o;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -380,7 +386,7 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
@Override
|
||||
public KEY_TYPE LAST_KEY() {
|
||||
if(length == 0) throw new NoSuchElementException();
|
||||
return data[(offset + length) - 1];
|
||||
return data[end()-1];
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
|
@ -388,9 +394,9 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
public boolean remove(KEY_TYPE o) {
|
||||
int index = findIndex(o);
|
||||
if(index != -1) {
|
||||
System.arraycopy(data, index+1, data, index, size - index);
|
||||
size--;
|
||||
length--;
|
||||
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -401,10 +407,12 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
public boolean remove(Object o) {
|
||||
int index = findIndex(o);
|
||||
if(index != -1) {
|
||||
System.arraycopy(data, index+1, data, index, size - index);
|
||||
data[size-1] = EMPTY_VALUE;
|
||||
size--;
|
||||
length--;
|
||||
if(index != size) System.arraycopy(data, index+1, data, index, size - index);
|
||||
#if TYPE_OBJECT
|
||||
data[size] = EMPTY_VALUE;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -413,13 +421,13 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
@Override
|
||||
public KEY_TYPE POLL_FIRST_KEY() {
|
||||
if(length == 0) throw new NoSuchElementException();
|
||||
size--;
|
||||
length--;
|
||||
KEY_TYPE result = data[offset];
|
||||
System.arraycopy(data, offset+1, data, offset, size-offset);
|
||||
#if TYPE_OBJECT
|
||||
data[size-1] = EMPTY_VALUE;
|
||||
data[size] = EMPTY_VALUE;
|
||||
#endif
|
||||
size--;
|
||||
length--;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -427,12 +435,12 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
public KEY_TYPE POLL_LAST_KEY() {
|
||||
if(length == 0) throw new NoSuchElementException();
|
||||
KEY_TYPE result = data[offset+length];
|
||||
System.arraycopy(data, (offset+length)+1, data, (offset+length), size-(offset+length));
|
||||
#if TYPE_OBJECT
|
||||
data[size-1] = EMPTY_VALUE;
|
||||
#endif
|
||||
size--;
|
||||
length--;
|
||||
System.arraycopy(data, end()+1, data, end(), size-end());
|
||||
#if TYPE_OBJECT
|
||||
data[size] = EMPTY_VALUE;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -482,17 +490,99 @@ public class ARRAY_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE im
|
|||
|
||||
#if !TYPE_OBJECT
|
||||
protected int findIndex(KEY_TYPE o) {
|
||||
for(int i = size-1;i>=0;i--)
|
||||
for(int i = length-1;i>=0;i--)
|
||||
if(EQUALS(data[offset+i], o)) return i + offset;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
protected int findIndex(Object o) {
|
||||
for(int i = size-1;i>=0;i--)
|
||||
for(int i = length-1;i>=0;i--)
|
||||
if(EQUALS_KEY_TYPE(data[offset+i], o)) return i + offset;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
|
||||
int index;
|
||||
int lastReturned = -1;
|
||||
|
||||
public SetIterator(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return index < size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE NEXT() {
|
||||
lastReturned = index;
|
||||
return data[index++];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE PREVIOUS() {
|
||||
lastReturned = index;
|
||||
return data[index--];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return index-1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if(lastReturned == -1)
|
||||
throw new IllegalStateException();
|
||||
SubSet.this.remove(data[lastReturned]);
|
||||
if(lastReturned < index)
|
||||
index--;
|
||||
lastReturned = -1;
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
@Override
|
||||
public void set(Object e) { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public void add(Object e) { throw new UnsupportedOperationException(); }
|
||||
|
||||
#else
|
||||
@Override
|
||||
public void set(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
||||
|
||||
#endif
|
||||
@Override
|
||||
public int skip(int amount) {
|
||||
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
||||
int steps = Math.min(amount, (size() - 1) - index);
|
||||
index += steps;
|
||||
return steps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int back(int amount) {
|
||||
if(amount < 0) throw new IllegalStateException("Negative Numbers are not allowed");
|
||||
int steps = Math.min(amount, index);
|
||||
index -= steps;
|
||||
return steps;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE {
|
||||
|
|
|
@ -158,6 +158,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
|||
|
||||
@Override
|
||||
public boolean moveToFirst(KEY_TYPE o) {
|
||||
if(strategy.equals(FIRST_KEY(), o)) return false;
|
||||
if(strategy.equals(o, EMPTY_VALUE)) {
|
||||
if(containsNull) {
|
||||
moveToFirstIndex(nullIndex);
|
||||
|
@ -180,6 +181,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
|||
|
||||
@Override
|
||||
public boolean moveToLast(KEY_TYPE o) {
|
||||
if(strategy.equals(LAST_KEY(), o)) return false;
|
||||
if(strategy.equals(o, EMPTY_VALUE)) {
|
||||
if(containsNull) {
|
||||
moveToLastIndex(nullIndex);
|
||||
|
@ -290,14 +292,14 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
|||
}
|
||||
else {
|
||||
links[lastIndex] ^= ((links[lastIndex] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
|
||||
links[pos] = ((lastIndex & 0xFFFFFFFFL) << 32) | (-1 & 0xFFFFFFFFL);
|
||||
links[pos] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
|
||||
lastIndex = pos;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNodeRemoved(int pos) {
|
||||
if(size == 0) firstIndex = lastIndex = 0;
|
||||
if(size == 0) firstIndex = lastIndex = -1;
|
||||
else if(firstIndex == pos) {
|
||||
firstIndex = (int)links[pos];
|
||||
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
|
||||
|
@ -344,11 +346,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
|||
@Override
|
||||
protected void rehash(int newSize) {
|
||||
int newMask = newSize - 1;
|
||||
#if TYPE_OBJECT
|
||||
KEY_TYPE[] newKeys = (KEY_TYPE[])new Object[newSize + 1];
|
||||
#else
|
||||
KEY_TYPE[] newKeys = new KEY_TYPE[newSize + 1];
|
||||
#endif
|
||||
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
|
||||
long[] newLinks = new long[newSize + 1];
|
||||
int newPrev = -1;
|
||||
for(int j = size, i = firstIndex, pos = 0, prev = -1;j != 0;) {
|
||||
|
@ -471,7 +469,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
|||
ensureIndexKnown();
|
||||
if(current == previous) {
|
||||
index--;
|
||||
previous = (int)(links[current] >> 32);
|
||||
previous = (int)(links[current] >>> 32);
|
||||
}
|
||||
else next = (int)links[current];
|
||||
size--;
|
||||
|
@ -490,7 +488,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
|||
current = -1;
|
||||
KEY_TYPE current;
|
||||
while(true) {
|
||||
last = ((last = startPos) + 1) & mask;
|
||||
startPos = ((last = startPos) + 1) & mask;
|
||||
while(true){
|
||||
if(strategy.equals((current = keys[startPos]), EMPTY_VALUE)) {
|
||||
keys[last] = EMPTY_VALUE;
|
||||
|
@ -520,7 +518,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
|||
|
||||
@Override
|
||||
public KEY_TYPE NEXT() {
|
||||
if(!hasPrevious()) throw new NoSuchElementException();
|
||||
if(!hasNext()) throw new NoSuchElementException();
|
||||
current = next;
|
||||
next = (int)(links[current]);
|
||||
previous = current;
|
||||
|
|
|
@ -160,6 +160,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
|||
|
||||
@Override
|
||||
public boolean moveToFirst(KEY_TYPE o) {
|
||||
if(EQUALS(FIRST_KEY(), o)) return false;
|
||||
if(EQUALS_NULL(o)) {
|
||||
if(containsNull) {
|
||||
moveToFirstIndex(nullIndex);
|
||||
|
@ -182,6 +183,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
|||
|
||||
@Override
|
||||
public boolean moveToLast(KEY_TYPE o) {
|
||||
if(EQUALS(LAST_KEY(), o)) return false;
|
||||
if(EQUALS_NULL(o)) {
|
||||
if(containsNull) {
|
||||
moveToLastIndex(nullIndex);
|
||||
|
@ -292,14 +294,14 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
|||
}
|
||||
else {
|
||||
links[lastIndex] ^= ((links[lastIndex] ^ (pos & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
|
||||
links[pos] = ((lastIndex & 0xFFFFFFFFL) << 32) | (-1 & 0xFFFFFFFFL);
|
||||
links[pos] = ((lastIndex & 0xFFFFFFFFL) << 32) | 0xFFFFFFFFL;
|
||||
lastIndex = pos;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNodeRemoved(int pos) {
|
||||
if(size == 0) firstIndex = lastIndex = 0;
|
||||
if(size == 0) firstIndex = lastIndex = -1;
|
||||
else if(firstIndex == pos) {
|
||||
firstIndex = (int)links[pos];
|
||||
if(0 <= firstIndex) links[firstIndex] |= 0xFFFFFFFF00000000L;
|
||||
|
@ -346,11 +348,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
|||
@Override
|
||||
protected void rehash(int newSize) {
|
||||
int newMask = newSize - 1;
|
||||
#if TYPE_OBJECT
|
||||
KEY_TYPE[] newKeys = (KEY_TYPE[])new Object[newSize + 1];
|
||||
#else
|
||||
KEY_TYPE[] newKeys = new KEY_TYPE[newSize + 1];
|
||||
#endif
|
||||
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
|
||||
long[] newLinks = new long[newSize + 1];
|
||||
int newPrev = -1;
|
||||
for(int j = size, i = firstIndex, pos = 0, prev = -1;j != 0;) {
|
||||
|
@ -473,7 +471,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
|||
ensureIndexKnown();
|
||||
if(current == previous) {
|
||||
index--;
|
||||
previous = (int)(links[current] >> 32);
|
||||
previous = (int)(links[current] >>> 32);
|
||||
}
|
||||
else next = (int)links[current];
|
||||
size--;
|
||||
|
@ -492,7 +490,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
|||
current = -1;
|
||||
KEY_TYPE current;
|
||||
while(true) {
|
||||
last = ((last = startPos) + 1) & mask;
|
||||
startPos = ((last = startPos) + 1) & mask;
|
||||
while(true){
|
||||
if(EQUALS_NULL((current = keys[startPos]))) {
|
||||
keys[last] = EMPTY_VALUE;
|
||||
|
@ -522,7 +520,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
|||
|
||||
@Override
|
||||
public KEY_TYPE NEXT() {
|
||||
if(!hasPrevious()) throw new NoSuchElementException();
|
||||
if(!hasNext()) throw new NoSuchElementException();
|
||||
current = next;
|
||||
next = (int)(links[current]);
|
||||
previous = current;
|
||||
|
|
|
@ -46,11 +46,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
this.minCapacity = nullIndex = HashUtil.arraySize(minCapacity, loadFactor);
|
||||
mask = nullIndex - 1;
|
||||
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
|
||||
#if TYPE_OBJECT
|
||||
keys = (KEY_TYPE[])new Object[nullIndex + 1];
|
||||
#else
|
||||
keys = new KEY_TYPE[nullIndex + 1];
|
||||
#endif
|
||||
keys = NEW_KEY_ARRAY(nullIndex + 1);
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
|
@ -132,7 +128,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
KEY_TYPE current = keys[pos];
|
||||
if(!strategy.equals(current, EMPTY_VALUE)) {
|
||||
if(strategy.equals(current, o)) return false;
|
||||
while(!strategy.equals((current = keys[++pos & mask]), EMPTY_VALUE))
|
||||
while(!strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_VALUE))
|
||||
if(strategy.equals(current, o)) return false;
|
||||
}
|
||||
keys[pos] = o;
|
||||
|
@ -163,10 +159,10 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
if(strategy.equals((KEY_TYPE)o, EMPTY_VALUE)) return containsNull;
|
||||
int pos = HashUtil.mix(strategy.hashCode((KEY_TYPE)o)) & mask;
|
||||
KEY_TYPE current = keys[pos];
|
||||
if(!strategy.equals(current, EMPTY_VALUE)) return false;
|
||||
if(strategy.equals(current, EMPTY_VALUE)) return false;
|
||||
if(strategy.equals(current, (KEY_TYPE)o)) return true;
|
||||
while(true) {
|
||||
if(strategy.equals((current = keys[++pos & mask]), EMPTY_VALUE)) return false;
|
||||
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_VALUE)) return false;
|
||||
else if(strategy.equals(current, (KEY_TYPE)o)) return true;
|
||||
}
|
||||
}
|
||||
|
@ -176,10 +172,10 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
if(strategy.equals((KEY_TYPE)o, EMPTY_VALUE)) return (containsNull ? removeNullIndex() : false);
|
||||
int pos = HashUtil.mix(strategy.hashCode((KEY_TYPE)o)) & mask;
|
||||
KEY_TYPE current = keys[pos];
|
||||
if(!strategy.equals(current, EMPTY_VALUE)) return false;
|
||||
if(strategy.equals(current, EMPTY_VALUE)) return false;
|
||||
if(strategy.equals(current, (KEY_TYPE)o)) return removeIndex(pos);
|
||||
while(true) {
|
||||
if(strategy.equals((current = keys[++pos & mask]), EMPTY_VALUE)) return false;
|
||||
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_VALUE)) return false;
|
||||
else if(strategy.equals(current, (KEY_TYPE)o)) return removeIndex(pos);
|
||||
}
|
||||
}
|
||||
|
@ -190,10 +186,10 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
if(strategy.equals(o, EMPTY_VALUE)) return containsNull;
|
||||
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
|
||||
KEY_TYPE current = keys[pos];
|
||||
if(!strategy.equals(current, EMPTY_VALUE)) return false;
|
||||
if(strategy.equals(current, EMPTY_VALUE)) return false;
|
||||
if(strategy.equals(current, o)) return true;
|
||||
while(true) {
|
||||
if(strategy.equals((current = keys[++pos & mask]), EMPTY_VALUE)) return false;
|
||||
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_VALUE)) return false;
|
||||
else if(strategy.equals(current, o)) return true;
|
||||
}
|
||||
}
|
||||
|
@ -203,10 +199,10 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
if(strategy.equals(o, EMPTY_VALUE)) return (containsNull ? removeNullIndex() : false);
|
||||
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
|
||||
KEY_TYPE current = keys[pos];
|
||||
if(!strategy.equals(current, EMPTY_VALUE)) return false;
|
||||
if(strategy.equals(current, EMPTY_VALUE)) return false;
|
||||
if(strategy.equals(current, o)) return removeIndex(pos);
|
||||
while(true) {
|
||||
if(strategy.equals((current = keys[++pos & mask]), EMPTY_VALUE)) return false;
|
||||
if(strategy.equals((current = keys[pos = (++pos & mask)]), EMPTY_VALUE)) return false;
|
||||
else if(strategy.equals(current, o)) return removeIndex(pos);
|
||||
}
|
||||
}
|
||||
|
@ -278,15 +274,11 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
|
||||
protected void rehash(int newSize) {
|
||||
int newMask = newSize - 1;
|
||||
#if TYPE_OBJECT
|
||||
KEY_TYPE[] newKeys = (KEY_TYPE[])new Object[newSize + 1];
|
||||
#else
|
||||
KEY_TYPE[] newKeys = new KEY_TYPE[newSize + 1];
|
||||
#endif
|
||||
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_VALUE));
|
||||
if(!strategy.equals(newKeys[pos = HashUtil.mix(TO_HASH(keys[i])) & newMask], EMPTY_VALUE))
|
||||
while(!strategy.equals(newKeys[++pos & newMask], EMPTY_VALUE));
|
||||
while(!strategy.equals(newKeys[pos = (++pos & newMask)], EMPTY_VALUE));
|
||||
newKeys[pos] = keys[i];
|
||||
}
|
||||
nullIndex = newSize;
|
||||
|
@ -316,31 +308,46 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
private class SetIterator implements ITERATOR KEY_GENERIC_TYPE {
|
||||
int pos = nullIndex;
|
||||
int lastReturned = -1;
|
||||
int count = size;
|
||||
int nextIndex = Integer.MIN_VALUE;
|
||||
boolean returnNull = containsNull;
|
||||
LIST KEY_GENERIC_TYPE wrapped = null;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return count != 0;
|
||||
if(nextIndex == Integer.MIN_VALUE) {
|
||||
if(returnNull) {
|
||||
returnNull = false;
|
||||
nextIndex = nullIndex;
|
||||
}
|
||||
else {
|
||||
while(true) {
|
||||
if(--pos < 0) {
|
||||
if(wrapped == null || wrapped.size() <= -pos - 1) break;
|
||||
nextIndex = -pos - 1;
|
||||
break;
|
||||
}
|
||||
if(EQUALS_NOT_NULL(keys[pos])){
|
||||
nextIndex = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nextIndex != Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE NEXT() {
|
||||
if(count != 0) throw new NoSuchElementException();
|
||||
count--;
|
||||
if(returnNull) {
|
||||
returnNull = false;
|
||||
lastReturned = nullIndex;
|
||||
return keys[nullIndex];
|
||||
}
|
||||
while(true) {
|
||||
if(pos-- < 0) {
|
||||
lastReturned = Integer.MAX_VALUE;
|
||||
return wrapped.GET_KEY(-pos - 1);
|
||||
}
|
||||
if(!strategy.equals(keys[pos], EMPTY_VALUE)) return keys[lastReturned = pos];
|
||||
if(!hasNext()) throw new NoSuchElementException();
|
||||
if(nextIndex < 0){
|
||||
lastReturned = Integer.MAX_VALUE;
|
||||
KEY_TYPE value = wrapped.GET_KEY(nextIndex);
|
||||
nextIndex = Integer.MIN_VALUE;
|
||||
return value;
|
||||
}
|
||||
KEY_TYPE value = keys[(lastReturned = nextIndex)];
|
||||
nextIndex = Integer.MIN_VALUE;
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -375,7 +382,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
|
|||
}
|
||||
if(startPos < last) {
|
||||
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
|
||||
wrapped.add(keys[pos]);
|
||||
wrapped.add(keys[startPos]);
|
||||
}
|
||||
keys[last] = current;
|
||||
}
|
||||
|
|
|
@ -44,11 +44,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
this.minCapacity = nullIndex = HashUtil.arraySize(minCapacity, loadFactor);
|
||||
mask = nullIndex - 1;
|
||||
maxFill = Math.min((int)Math.ceil(nullIndex * loadFactor), nullIndex - 1);
|
||||
#if TYPE_OBJECT
|
||||
keys = (KEY_TYPE[])new Object[nullIndex + 1];
|
||||
#else
|
||||
keys = new KEY_TYPE[nullIndex + 1];
|
||||
#endif
|
||||
keys = NEW_KEY_ARRAY(nullIndex + 1);
|
||||
}
|
||||
|
||||
public HASH_SET(KEY_TYPE[] array) {
|
||||
|
@ -125,7 +121,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
KEY_TYPE current = keys[pos];
|
||||
if(EQUALS_NOT_NULL(current)) {
|
||||
if(EQUALS(current, o)) return false;
|
||||
while(EQUALS_NOT_NULL((current = keys[++pos & mask])))
|
||||
while(EQUALS_NOT_NULL((current = keys[pos = (++pos & mask)])))
|
||||
if(EQUALS(current, o)) return false;
|
||||
}
|
||||
keys[pos] = o;
|
||||
|
@ -158,7 +154,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
if(EQUALS_NULL(current)) return false;
|
||||
if(EQUALS_KEY_TYPE(current, o)) return true;
|
||||
while(true) {
|
||||
if(EQUALS_NULL((current = keys[++pos & mask]))) return false;
|
||||
if(EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
|
||||
else if(EQUALS_KEY_TYPE(current, o)) return true;
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +167,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
if(EQUALS_NULL(current)) return false;
|
||||
if(EQUALS_KEY_TYPE(current, o)) return removeIndex(pos);
|
||||
while(true) {
|
||||
if(EQUALS_NULL((current = keys[++pos & mask]))) return false;
|
||||
if(EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
|
||||
else if(EQUALS_KEY_TYPE(current, o)) return removeIndex(pos);
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +181,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
if(EQUALS_NULL(current)) return false;
|
||||
if(EQUALS(current, o)) return true;
|
||||
while(true) {
|
||||
if(EQUALS_NULL((current = keys[++pos & mask]))) return false;
|
||||
if(EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
|
||||
else if(EQUALS(current, o)) return true;
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +194,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
if(EQUALS_NULL(current)) return false;
|
||||
if(EQUALS(current, o)) return removeIndex(pos);
|
||||
while(true) {
|
||||
if(EQUALS_NULL((current = keys[++pos & mask]))) return false;
|
||||
if(EQUALS_NULL((current = keys[pos = (++pos & mask)]))) return false;
|
||||
else if(EQUALS(current, o)) return removeIndex(pos);
|
||||
}
|
||||
}
|
||||
|
@ -270,15 +266,11 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
|
||||
protected void rehash(int newSize) {
|
||||
int newMask = newSize - 1;
|
||||
#if TYPE_OBJECT
|
||||
KEY_TYPE[] newKeys = (KEY_TYPE[])new Object[newSize + 1];
|
||||
#else
|
||||
KEY_TYPE[] newKeys = new KEY_TYPE[newSize + 1];
|
||||
#endif
|
||||
KEY_TYPE[] newKeys = NEW_KEY_ARRAY(newSize + 1);
|
||||
for(int i = nullIndex, pos = 0, j = (size - (containsNull ? 1 : 0));j-- != 0;) {
|
||||
while(EQUALS_NULL(keys[--i]));
|
||||
if(EQUALS_NOT_NULL(newKeys[pos = HashUtil.mix(TO_HASH(keys[i])) & newMask]))
|
||||
while(EQUALS_NOT_NULL(newKeys[++pos & newMask]));
|
||||
while(EQUALS_NOT_NULL(newKeys[pos = (++pos & newMask)]));
|
||||
newKeys[pos] = keys[i];
|
||||
}
|
||||
nullIndex = newSize;
|
||||
|
@ -308,31 +300,47 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
private class SetIterator implements ITERATOR KEY_GENERIC_TYPE {
|
||||
int pos = nullIndex;
|
||||
int lastReturned = -1;
|
||||
int count = size;
|
||||
int nextIndex = Integer.MIN_VALUE;
|
||||
boolean returnNull = containsNull;
|
||||
LIST KEY_GENERIC_TYPE wrapped = null;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return count != 0;
|
||||
if(nextIndex == Integer.MIN_VALUE) {
|
||||
if(returnNull) {
|
||||
returnNull = false;
|
||||
nextIndex = nullIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(true) {
|
||||
if(--pos < 0) {
|
||||
if(wrapped == null || wrapped.size() <= -pos - 1) break;
|
||||
nextIndex = -pos - 1;
|
||||
break;
|
||||
}
|
||||
if(EQUALS_NOT_NULL(keys[pos])){
|
||||
nextIndex = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nextIndex != Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KEY_TYPE NEXT() {
|
||||
if(count != 0) throw new NoSuchElementException();
|
||||
count--;
|
||||
if(returnNull) {
|
||||
returnNull = false;
|
||||
lastReturned = nullIndex;
|
||||
return keys[nullIndex];
|
||||
}
|
||||
while(true) {
|
||||
if(pos-- < 0) {
|
||||
lastReturned = Integer.MAX_VALUE;
|
||||
return wrapped.GET_KEY(-pos - 1);
|
||||
}
|
||||
if(EQUALS_NOT_NULL(keys[pos])) return keys[lastReturned = pos];
|
||||
if(!hasNext()) throw new NoSuchElementException();
|
||||
if(nextIndex < 0){
|
||||
lastReturned = Integer.MAX_VALUE;
|
||||
KEY_TYPE value = wrapped.GET_KEY(nextIndex);
|
||||
nextIndex = Integer.MIN_VALUE;
|
||||
return value;
|
||||
}
|
||||
KEY_TYPE value = keys[(lastReturned = nextIndex)];
|
||||
nextIndex = Integer.MIN_VALUE;
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -367,7 +375,7 @@ public class HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE imp
|
|||
}
|
||||
if(startPos < last) {
|
||||
if(wrapped == null) wrapped = new ARRAY_LISTBRACES(2);
|
||||
wrapped.add(keys[pos]);
|
||||
wrapped.add(keys[startPos]);
|
||||
}
|
||||
keys[last] = current;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
package speiger.src.collections.PACKAGE.sets;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Collection;
|
||||
#if TYPE_OBJECT
|
||||
import java.util.Comparator;
|
||||
#endif
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
|
||||
#if !TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.collections.COLLECTION;
|
||||
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
|
||||
#if !TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.utils.ITERATORS;
|
||||
#endif
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
|
||||
public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
|
||||
{
|
||||
|
@ -30,6 +38,36 @@ public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
|
|||
public RB_TREE_SET() {
|
||||
}
|
||||
|
||||
public RB_TREE_SET(KEY_TYPE[] array) {
|
||||
this(array, 0, array.length);
|
||||
}
|
||||
|
||||
public RB_TREE_SET(KEY_TYPE[] array, int offset, int length) {
|
||||
SanityChecks.checkArrayCapacity(array.length, offset, length);
|
||||
for(int i = 0;i<length;i++) add(array[offset+i]);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public RB_TREE_SET(Collection<? extends CLASS_TYPE> collection) {
|
||||
addAll(collection);
|
||||
}
|
||||
|
||||
public RB_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection) {
|
||||
addAll(collection);
|
||||
}
|
||||
|
||||
public RB_TREE_SET(Iterator<CLASS_TYPE> iterator) {
|
||||
#if !TYPE_OBJECT
|
||||
this(ITERATORS.wrap(iterator));
|
||||
#else
|
||||
while(iterator.hasNext()) add(iterator.next());
|
||||
#endif
|
||||
}
|
||||
|
||||
public RB_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
|
||||
while(iterator.hasNext()) add(iterator.NEXT());
|
||||
}
|
||||
|
||||
#if !TYPE_OBJECT
|
||||
@Override
|
||||
public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; }
|
||||
|
|
|
@ -624,21 +624,36 @@ public class ARRAYS
|
|||
i++;
|
||||
else if(compare == 0) swap(array, ++i, j);
|
||||
else {
|
||||
swap(array, i++, j);
|
||||
int k = j;
|
||||
for(;k < to - 1 && comp.compare(array[j], array[k + 1]) > 0;k++);
|
||||
if(j == k)
|
||||
for(;k < to - 1 && comp.compare(array[i], array[k + 1]) > 0;k++);
|
||||
if(j == k) {
|
||||
swap(array, i++, j);
|
||||
continue;
|
||||
KEY_TYPE value = array[j];
|
||||
System.arraycopy(array, j + 1, array, j, k - j);
|
||||
array[k] = value;
|
||||
}
|
||||
else if(j + 1 == k) {
|
||||
KEY_TYPE value = array[j];
|
||||
System.arraycopy(array, i, array, i+1, j - i);
|
||||
array[i] = value;
|
||||
i++;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
KEY_TYPE[] data = NEW_KEY_ARRAY(k - j);
|
||||
System.arraycopy(array, j, data, 0, data.length);
|
||||
System.arraycopy(array, i, array, i+data.length, j - i);
|
||||
System.arraycopy(data, 0, array, i, data.length);
|
||||
i+=data.length;
|
||||
j+=data.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
*/
|
||||
public static COMPAREABLE_BRACES void memFreeMergeSort(KEY_TYPE[] array) {
|
||||
|
@ -647,7 +662,10 @@ public class ARRAYS
|
|||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
*/
|
||||
|
@ -657,7 +675,10 @@ public class ARRAYS
|
|||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
|
@ -677,21 +698,36 @@ public class ARRAYS
|
|||
i++;
|
||||
else if(comp == 0) swap(array, ++i, j);
|
||||
else {
|
||||
swap(array, i++, j);
|
||||
int k = j;
|
||||
for(;k < to - 1 && COMPARE_TO(array[j], array[k + 1]) > 0;k++);
|
||||
if(j == k)
|
||||
for(;k < to - 1 && COMPARE_TO(array[i], array[k + 1]) > 0;k++);
|
||||
if(j == k) {
|
||||
swap(array, i++, j);
|
||||
continue;
|
||||
KEY_TYPE value = array[j];
|
||||
System.arraycopy(array, j + 1, array, j, k - j);
|
||||
array[k] = value;
|
||||
}
|
||||
else if(j + 1 == k) {
|
||||
KEY_TYPE value = array[j];
|
||||
System.arraycopy(array, i, array, i+1, j - i);
|
||||
array[i] = value;
|
||||
i++;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
KEY_TYPE[] data = NEW_KEY_ARRAY(k - j);
|
||||
System.arraycopy(array, j, data, 0, data.length);
|
||||
System.arraycopy(array, i, array, i+data.length, j - i);
|
||||
System.arraycopy(data, 0, array, i, data.length);
|
||||
i+=data.length;
|
||||
j+=data.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
|
@ -702,7 +738,10 @@ public class ARRAYS
|
|||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
|
@ -714,7 +753,10 @@ public class ARRAYS
|
|||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
|
@ -731,7 +773,10 @@ public class ARRAYS
|
|||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
|
@ -741,7 +786,10 @@ public class ARRAYS
|
|||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @Note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
|
@ -752,7 +800,10 @@ public class ARRAYS
|
|||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort,
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast.
|
||||
* This implementation is inspired by <a href="https://github.com/vigna/fastutil">FastUtil</a> original merge sort, but without the need to allocate a copy of the original Array.
|
||||
* It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario.
|
||||
* It does stack allocate tiny amounts of data for shifting around elements.
|
||||
* @author Speiger
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
|
@ -1174,14 +1225,26 @@ public class ARRAYS
|
|||
i++;
|
||||
else if(comp == 0) swap(array, ++i, j);
|
||||
else {
|
||||
swap(array, i++, j);
|
||||
int k = j;
|
||||
for(;k < to - 1 && COMPARE_TO(array[j], array[k + 1]) > 0;k++);
|
||||
if(j == k)
|
||||
for(;k < to - 1 && COMPARE_TO(array[i], array[k + 1]) > 0;k++);
|
||||
if(j == k) {
|
||||
swap(array, i++, j);
|
||||
continue;
|
||||
KEY_TYPE value = array[j];
|
||||
System.arraycopy(array, j + 1, array, j, k - j);
|
||||
array[k] = value;
|
||||
}
|
||||
else if(j + 1 == k) {
|
||||
KEY_TYPE value = array[j];
|
||||
System.arraycopy(array, i, array, i+1, j - i);
|
||||
array[i] = value;
|
||||
i++;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
KEY_TYPE[] data = NEW_KEY_ARRAY(k - j);
|
||||
System.arraycopy(array, j, data, 0, data.length);
|
||||
System.arraycopy(array, i, array, i+data.length, j - i);
|
||||
System.arraycopy(data, 0, array, i, data.length);
|
||||
i+=data.length;
|
||||
j+=data.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1219,14 +1282,26 @@ public class ARRAYS
|
|||
i++;
|
||||
else if(compare == 0) swap(array, ++i, j);
|
||||
else {
|
||||
swap(array, i++, j);
|
||||
int k = j;
|
||||
for(;k < to - 1 && comp.compare(array[j], array[k + 1]) > 0;k++);
|
||||
if(j == k)
|
||||
for(;k < to - 1 && comp.compare(array[i], array[k + 1]) > 0;k++);
|
||||
if(j == k) {
|
||||
swap(array, i++, j);
|
||||
continue;
|
||||
KEY_TYPE value = array[j];
|
||||
System.arraycopy(array, j + 1, array, j, k - j);
|
||||
array[k] = value;
|
||||
}
|
||||
else if(j + 1 == k) {
|
||||
KEY_TYPE value = array[j];
|
||||
System.arraycopy(array, i, array, i+1, j - i);
|
||||
array[i] = value;
|
||||
i++;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
KEY_TYPE[] data = NEW_KEY_ARRAY(k - j);
|
||||
System.arraycopy(array, j, data, 0, data.length);
|
||||
System.arraycopy(array, i, array, i+data.length, j - i);
|
||||
System.arraycopy(data, 0, array, i, data.length);
|
||||
i+=data.length;
|
||||
j+=data.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ public class ITERATORS
|
|||
*/
|
||||
public static GENERIC_BRACES int unwrap(KEY_TYPE[] a, Iterator<? extends CLASS_TYPE> i, int offset, int max) {
|
||||
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
|
||||
if(offset + max >= a.length) throw new IllegalStateException("largest array index exceeds array size");
|
||||
if(offset + max > a.length) throw new IllegalStateException("largest array index exceeds array size");
|
||||
int index = 0;
|
||||
for(;index<max && i.hasNext();index++) a[index+offset] = OBJ_TO_KEY(i.next());
|
||||
return index;
|
||||
|
@ -145,7 +145,7 @@ public class ITERATORS
|
|||
*/
|
||||
public static GENERIC_BRACES int unwrap(KEY_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset, int max) {
|
||||
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
|
||||
if(offset + max >= a.length) throw new IllegalStateException("largest array index exceeds array size");
|
||||
if(offset + max > a.length) throw new IllegalStateException("largest array index exceeds array size");
|
||||
int index = 0;
|
||||
for(;index<max && i.hasNext();index++) a[index+offset] = i.NEXT();
|
||||
return index;
|
||||
|
@ -187,7 +187,7 @@ public class ITERATORS
|
|||
*/
|
||||
public static GENERIC_BRACES int unwrap(CLASS_TYPE[] a, ITERATOR KEY_GENERIC_TYPE i, int offset, int max) {
|
||||
if(max < 0) throw new IllegalStateException("The max size is smaller then 0");
|
||||
if(offset + max >= a.length) throw new IllegalStateException("largest array index exceeds array size");
|
||||
if(offset + max > a.length) throw new IllegalStateException("largest array index exceeds array size");
|
||||
int index = 0;
|
||||
for(;index<max && i.hasNext();index++) a[index+offset] = KEY_TO_OBJ(i.NEXT());
|
||||
return index;
|
||||
|
|
|
@ -26,7 +26,7 @@ public abstract class BaseIntCollectionTest extends BaseIntIterableTest
|
|||
@Test
|
||||
public void testAdd() {
|
||||
if(!getValidCollectionTests().contains(CollectionTest.ADD)) return;
|
||||
IntCollection collection = create(TEST_EMPTY);
|
||||
IntCollection collection = create(EMPTY_ARRAY);
|
||||
Assert.assertTrue(collection.isEmpty());
|
||||
collection.add(2012);
|
||||
Assert.assertFalse(collection.isEmpty());
|
||||
|
@ -56,9 +56,9 @@ public abstract class BaseIntCollectionTest extends BaseIntIterableTest
|
|||
public void testContainsAll() {
|
||||
if(!getValidCollectionTests().contains(CollectionTest.CONTAINS_ALL)) return;
|
||||
IntCollection collection = create(TEST_ARRAY);
|
||||
Assert.assertTrue(create(CONTAINS_ARRAY).containsAll(collection));
|
||||
Assert.assertFalse(create(ADD_ARRAY).containsAll(collection));
|
||||
Assert.assertTrue(collection.containsAll(Arrays.asList(IntArrays.wrap(TEST_ARRAY))));
|
||||
Assert.assertTrue(collection.containsAll(create(CONTAINS_ARRAY)));
|
||||
Assert.assertFalse(collection.containsAll(create(ADD_ARRAY)));
|
||||
Assert.assertTrue(collection.containsAll(Arrays.asList(IntArrays.wrap(CONTAINS_ARRAY))));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -129,11 +129,13 @@ public abstract class BaseIntCollectionTest extends BaseIntIterableTest
|
|||
IntCollection collection = create(TEST_ARRAY);
|
||||
int[] array = collection.toIntArray();
|
||||
IntArrays.stableSort(array);
|
||||
Assert.assertTrue(Arrays.equals(TEST_ARRAY, array));
|
||||
Assert.assertArrayEquals(array, TEST_ARRAY);
|
||||
int[] other = collection.toIntArray(new int[collection.size()]);
|
||||
IntArrays.stableSort(other);
|
||||
Assert.assertTrue(Arrays.equals(TEST_ARRAY, other));
|
||||
Assert.assertTrue(Arrays.equals(TEST_ARRAY, IntArrays.unwrap(collection.toArray(new Integer[collection.size()]))));
|
||||
Assert.assertArrayEquals(other, TEST_ARRAY);
|
||||
other = IntArrays.unwrap(collection.toArray(new Integer[collection.size()]));
|
||||
IntArrays.stableSort(other);
|
||||
Assert.assertArrayEquals(other, TEST_ARRAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -148,7 +150,7 @@ public abstract class BaseIntCollectionTest extends BaseIntIterableTest
|
|||
@Test
|
||||
public void testWrapper() {
|
||||
if(!getValidCollectionTests().contains(CollectionTest.WRAPPER)) return;
|
||||
IntCollection collection = create(TEST_EMPTY);
|
||||
IntCollection collection = create(TEST_ARRAY);
|
||||
collection = IntCollections.synchronizedCollection(collection);
|
||||
Assert.assertTrue(collection instanceof SynchronizedCollection);
|
||||
collection = IntCollections.unmodifiableCollection(collection);
|
||||
|
|
|
@ -12,7 +12,7 @@ import speiger.src.collections.tests.IterableTest;
|
|||
|
||||
public abstract class BaseIntIterableTest
|
||||
{
|
||||
protected static final int[] TEST_EMPTY = new int[0];
|
||||
protected static final int[] EMPTY_ARRAY = new int[0];
|
||||
protected static final int[] TEST_ARRAY = IntStream.range(0, 100).toArray();
|
||||
|
||||
protected abstract IntIterable create(int[] data);
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package speiger.src.collections.ints.base;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import speiger.src.collections.ints.sets.IntNavigableSet;
|
||||
import speiger.src.collections.tests.NavigableSetTest;
|
||||
|
||||
public abstract class BaseIntNavigableSetTest extends BaseIntSortedSetTest
|
||||
{
|
||||
@Override
|
||||
protected abstract IntNavigableSet create(int[] data);
|
||||
|
||||
protected EnumSet<NavigableSetTest> getValidNavigableSetTests() { return EnumSet.allOf(NavigableSetTest.class); }
|
||||
|
||||
@Test
|
||||
public void lowerTest() {
|
||||
if(getValidNavigableSetTests().contains(NavigableSetTest.LOWER)) {
|
||||
Assert.assertTrue(create(TEST_ARRAY).lower(50) < 50);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void higherTest() {
|
||||
if(getValidNavigableSetTests().contains(NavigableSetTest.HIGHER)) {
|
||||
Assert.assertTrue(create(TEST_ARRAY).higher(50) > 50);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ceilTest() {
|
||||
if(getValidNavigableSetTests().contains(NavigableSetTest.CEILING)) {
|
||||
Assert.assertTrue(create(TEST_ARRAY).ceiling(50) >= 50);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void floorTest() {
|
||||
if(getValidNavigableSetTests().contains(NavigableSetTest.FLOOR)) {
|
||||
Assert.assertTrue(create(TEST_ARRAY).floor(50) <= 50);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void naviSubSetTest() {
|
||||
if(getValidNavigableSetTests().contains(NavigableSetTest.SUB_SET)) {
|
||||
IntNavigableSet set = create(TEST_ARRAY);
|
||||
IntNavigableSet subSet = set.subSet(25, 75);
|
||||
Assert.assertTrue(subSet.lower(50) < 50);
|
||||
Assert.assertTrue(subSet.higher(50) > 50);
|
||||
Assert.assertTrue(subSet.ceiling(50) >= 50);
|
||||
Assert.assertTrue(subSet.floor(50) <= 50);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void naviHeadSetTest() {
|
||||
if(getValidNavigableSetTests().contains(NavigableSetTest.HEAD_SET)) {
|
||||
IntNavigableSet set = create(TEST_ARRAY);
|
||||
IntNavigableSet subSet = set.headSet(75);
|
||||
Assert.assertTrue(subSet.lower(50) < 50);
|
||||
Assert.assertTrue(subSet.higher(50) > 50);
|
||||
Assert.assertTrue(subSet.ceiling(50) >= 50);
|
||||
Assert.assertTrue(subSet.floor(50) <= 50);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void naviTailSetTest() {
|
||||
if(getValidNavigableSetTests().contains(NavigableSetTest.TAIL_SET)) {
|
||||
IntNavigableSet set = create(TEST_ARRAY);
|
||||
IntNavigableSet subSet = set.tailSet(25);
|
||||
Assert.assertTrue(subSet.lower(50) < 50);
|
||||
Assert.assertTrue(subSet.higher(50) > 50);
|
||||
Assert.assertTrue(subSet.ceiling(50) >= 50);
|
||||
Assert.assertTrue(subSet.floor(50) <= 50);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package speiger.src.collections.ints.base;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import speiger.src.collections.ints.sets.IntSortedSet;
|
||||
import speiger.src.collections.tests.SortedSetTest;
|
||||
|
||||
public abstract class BaseIntSortedSetTest extends BaseIntCollectionTest
|
||||
{
|
||||
@Override
|
||||
protected abstract IntSortedSet create(int[] data);
|
||||
|
||||
protected EnumSet<SortedSetTest> getValidSortedSetTests() { return EnumSet.allOf(SortedSetTest.class); }
|
||||
|
||||
@Test
|
||||
public void addMoveTest() {
|
||||
if(getValidSortedSetTests().contains(SortedSetTest.ADD_MOVE)) {
|
||||
IntSortedSet set = create(TEST_ARRAY);
|
||||
Assert.assertTrue(set.addAndMoveToFirst(1050));
|
||||
Assert.assertFalse(set.addAndMoveToLast(5));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moveTest() {
|
||||
if(getValidSortedSetTests().contains(SortedSetTest.MOVE)) {
|
||||
IntSortedSet set = create(TEST_ARRAY);
|
||||
Assert.assertTrue(set.moveToFirst(5));
|
||||
Assert.assertFalse(set.moveToFirst(5));
|
||||
Assert.assertTrue(set.moveToLast(5));
|
||||
Assert.assertFalse(set.moveToLast(5));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void peekTest() {
|
||||
if(getValidSortedSetTests().contains(SortedSetTest.PEEK)) {
|
||||
IntSortedSet set = create(TEST_ARRAY);
|
||||
Assert.assertEquals(set.firstInt(), 0);
|
||||
Assert.assertEquals(set.lastInt(), 99);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pollTest() {
|
||||
if(getValidSortedSetTests().contains(SortedSetTest.POLL)) {
|
||||
IntSortedSet set = create(TEST_ARRAY);
|
||||
Assert.assertEquals(set.pollFirstInt(), 0);
|
||||
Assert.assertEquals(set.pollLastInt(), 99);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subSetTest() {
|
||||
if(getValidSortedSetTests().contains(SortedSetTest.SUB_SET)) {
|
||||
IntSortedSet set = create(TEST_ARRAY);
|
||||
IntSortedSet subSet = set.subSet(25, 75);
|
||||
Assert.assertTrue(subSet.remove(50));
|
||||
Assert.assertFalse(subSet.remove(50));
|
||||
Assert.assertFalse(subSet.contains(20));
|
||||
Assert.assertFalse(subSet.contains(80));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headSetTest() {
|
||||
if(getValidSortedSetTests().contains(SortedSetTest.HEAD_SET)) {
|
||||
IntSortedSet set = create(TEST_ARRAY);
|
||||
IntSortedSet subSet = set.headSet(75);
|
||||
Assert.assertTrue(subSet.remove(50));
|
||||
Assert.assertFalse(subSet.remove(50));
|
||||
Assert.assertFalse(subSet.contains(80));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tailSetTest() {
|
||||
if(getValidSortedSetTests().contains(SortedSetTest.TAIL_SET)) {
|
||||
IntSortedSet set = create(TEST_ARRAY);
|
||||
IntSortedSet subSet = set.tailSet(25);
|
||||
Assert.assertTrue(subSet.remove(50));
|
||||
Assert.assertFalse(subSet.remove(50));
|
||||
Assert.assertFalse(subSet.contains(20));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package speiger.src.collections.ints.sets;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import speiger.src.collections.ints.base.BaseIntNavigableSetTest;
|
||||
import speiger.src.collections.tests.SortedSetTest;
|
||||
|
||||
public class IntAVLTreeSetTests extends BaseIntNavigableSetTest
|
||||
{
|
||||
@Override
|
||||
protected IntNavigableSet create(int[] data) {
|
||||
return new IntAVLTreeSet(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EnumSet<SortedSetTest> getValidSortedSetTests() { return EnumSet.of(SortedSetTest.PEEK, SortedSetTest.POLL, SortedSetTest.HEAD_SET, SortedSetTest.SUB_SET, SortedSetTest.TAIL_SET);}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package speiger.src.collections.ints.sets;
|
||||
|
||||
import speiger.src.collections.ints.base.BaseIntSortedSetTest;
|
||||
|
||||
public class IntArraySetTests extends BaseIntSortedSetTest
|
||||
{
|
||||
@Override
|
||||
protected IntSortedSet create(int[] data) { return new IntArraySet(data.clone()); }
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package speiger.src.collections.ints.sets;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import speiger.src.collections.ints.base.BaseIntCollectionTest;
|
||||
import speiger.src.collections.ints.base.BaseIntSortedSetTest;
|
||||
import speiger.src.collections.ints.collections.IntCollection;
|
||||
import speiger.src.collections.ints.utils.IntStrategy;
|
||||
import speiger.src.collections.tests.SortedSetTest;
|
||||
|
||||
public class IntHashSetTests
|
||||
{
|
||||
public static abstract class BaseIntOpenHashSetTests extends BaseIntSortedSetTest
|
||||
{
|
||||
@Override
|
||||
protected EnumSet<SortedSetTest> getValidSortedSetTests() { return EnumSet.of(SortedSetTest.ADD_MOVE, SortedSetTest.MOVE, SortedSetTest.PEEK, SortedSetTest.POLL); }
|
||||
}
|
||||
|
||||
public static class IntOpenHashSetTests extends BaseIntCollectionTest
|
||||
{
|
||||
@Override
|
||||
protected IntCollection create(int[] data) { return new IntOpenHashSet(data); }
|
||||
}
|
||||
|
||||
public static class IntLinkedOpenHashSetTests extends BaseIntOpenHashSetTests
|
||||
{
|
||||
@Override
|
||||
protected IntSortedSet create(int[] data) { return new IntLinkedOpenHashSet(data); }
|
||||
}
|
||||
|
||||
public static class IntOpenCustomHashSetTests extends BaseIntCollectionTest
|
||||
{
|
||||
@Override
|
||||
protected IntCollection create(int[] data) { return new IntOpenCustomHashSet(data, new DefaultStrategy()); }
|
||||
}
|
||||
|
||||
public static class IntLinkedOpenCustomHashSetTests extends BaseIntOpenHashSetTests
|
||||
{
|
||||
@Override
|
||||
protected IntSortedSet create(int[] data) { return new IntLinkedOpenCustomHashSet(data, new DefaultStrategy()); }
|
||||
}
|
||||
|
||||
public static class DefaultStrategy implements IntStrategy
|
||||
{
|
||||
@Override
|
||||
public int hashCode(int o) { return Integer.hashCode(o); }
|
||||
@Override
|
||||
public boolean equals(int key, int value) { return key == value; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package speiger.src.collections.ints.sets;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import speiger.src.collections.ints.base.BaseIntNavigableSetTest;
|
||||
import speiger.src.collections.tests.SortedSetTest;
|
||||
|
||||
public class IntRBTreeSetTests extends BaseIntNavigableSetTest
|
||||
{
|
||||
|
||||
@Override
|
||||
protected IntNavigableSet create(int[] data) {
|
||||
return new IntRBTreeSet(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EnumSet<SortedSetTest> getValidSortedSetTests() { return EnumSet.of(SortedSetTest.PEEK, SortedSetTest.POLL, SortedSetTest.HEAD_SET, SortedSetTest.SUB_SET, SortedSetTest.TAIL_SET);}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package speiger.src.collections.ints.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JavaTests
|
||||
{
|
||||
protected static final Integer[] CONTAINS_ARRAY = new Integer[]{23, 45, 63, 89, 32};
|
||||
protected static final Integer[] TEST_ARRAY = IntStream.range(0, 100).mapToObj(Integer::valueOf).toArray(Integer[]::new);
|
||||
|
||||
private TreeSet<Integer> create(Integer[] array)
|
||||
{
|
||||
TreeSet<Integer> tree = new TreeSet<Integer>();
|
||||
tree.addAll(Arrays.asList(array));
|
||||
return tree;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleTest()
|
||||
{
|
||||
TreeSet<Integer> collection = create(TEST_ARRAY);
|
||||
Assert.assertTrue(collection.removeAll(create(CONTAINS_ARRAY)));
|
||||
Assert.assertFalse(collection.removeAll(create(CONTAINS_ARRAY)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package speiger.src.collections.tests;
|
||||
|
||||
public enum NavigableSetTest
|
||||
{
|
||||
LOWER,
|
||||
HIGHER,
|
||||
CEILING,
|
||||
FLOOR,
|
||||
SUB_SET,
|
||||
HEAD_SET,
|
||||
TAIL_SET;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package speiger.src.collections.tests;
|
||||
|
||||
public enum SortedSetTest
|
||||
{
|
||||
ADD_MOVE,
|
||||
MOVE,
|
||||
PEEK,
|
||||
POLL,
|
||||
SUB_SET,
|
||||
HEAD_SET,
|
||||
TAIL_SET;
|
||||
}
|
Loading…
Reference in New Issue