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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user