Started massive unit testing library these are the first fixes.
-Fixed: AbstractCollection.retainAll didn't push removed values through the consumer. -Fixed: AbstractCollection.toArray wouldn't reset the last entry if the input array was larger then the elements in the collection. -Fixed: SubList didn't check for ranges properly or didn't use parent list to validate changes. -Fixed: ArrayList.addElements didn't check input array fully and used the wrong variable to move the elements around. -Fixed: LinkedList.addElements(EmptyInput) would crash. -Fixed: LinkedList.swapRemove didn't account for if the removed element was the prelast one. -Fixed: LinkedList.removeElements would break the implementation if the list was almost empty and the middle element was removed. -Fixed: LinkedHashSet.addAndMoveToFirst wouldn't move elements to the first place.
This commit is contained in:
parent
72943cb22c
commit
e7da7acc08
|
@ -18,7 +18,7 @@ repositories {
|
||||||
}
|
}
|
||||||
|
|
||||||
archivesBaseName = 'Primitive Collections'
|
archivesBaseName = 'Primitive Collections'
|
||||||
version = '0.6.1';
|
version = '0.6.1.10';
|
||||||
|
|
||||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaVersion.current();
|
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = JavaVersion.current();
|
||||||
|
|
||||||
|
|
|
@ -230,6 +230,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
||||||
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
|
for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();) {
|
||||||
KEY_TYPE e = iter.NEXT();
|
KEY_TYPE e = iter.NEXT();
|
||||||
if(!c.contains(e)) {
|
if(!c.contains(e)) {
|
||||||
|
r.accept(e);
|
||||||
iter.remove();
|
iter.remove();
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
@ -256,6 +257,7 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC_TYPE extends AbstractColle
|
||||||
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
|
public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) {
|
||||||
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
|
if(a == null || a.length < size()) a = new KEY_TYPE[size()];
|
||||||
ITERATORS.unwrap(a, iterator());
|
ITERATORS.unwrap(a, iterator());
|
||||||
|
if (a.length > size()) a[size()] = EMPTY_KEY_VALUE;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -315,7 +315,7 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
|
||||||
public void removeElements(int from, int to) {
|
public void removeElements(int from, int to) {
|
||||||
if(to-from <= 0) return;
|
if(to-from <= 0) return;
|
||||||
checkSubRange(from);
|
checkSubRange(from);
|
||||||
checkSubRange(to);
|
checkAddSubRange(to);
|
||||||
list.removeElements(from+parentOffset, to+parentOffset);
|
list.removeElements(from+parentOffset, to+parentOffset);
|
||||||
size -= to - from;
|
size -= to - from;
|
||||||
}
|
}
|
||||||
|
@ -324,9 +324,9 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
|
||||||
@Override
|
@Override
|
||||||
public <K> K[] extractElements(int from, int to, Class<K> type) {
|
public <K> K[] extractElements(int from, int to, Class<K> type) {
|
||||||
checkSubRange(from);
|
checkSubRange(from);
|
||||||
checkSubRange(to);
|
checkAddSubRange(to);
|
||||||
K[] result = list.extractElements(from+parentOffset, to+parentOffset, type);
|
K[] result = list.extractElements(from+parentOffset, to+parentOffset, type);
|
||||||
size -= to - from;
|
size -= result.length;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,9 +334,9 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION
|
||||||
@Override
|
@Override
|
||||||
public KEY_TYPE[] extractElements(int from, int to) {
|
public KEY_TYPE[] extractElements(int from, int to) {
|
||||||
checkSubRange(from);
|
checkSubRange(from);
|
||||||
checkSubRange(to);
|
checkAddSubRange(to);
|
||||||
KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset);
|
KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset);
|
||||||
size -= to - from;
|
size -= result.length;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -324,8 +324,9 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
||||||
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
|
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
|
||||||
if(length <= 0) return;
|
if(length <= 0) return;
|
||||||
checkAddRange(from);
|
checkAddRange(from);
|
||||||
|
SanityChecks.checkArrayCapacity(a.length, offset, length);
|
||||||
grow(size + length);
|
grow(size + length);
|
||||||
if(from != size) System.arraycopy(data, from, data, from+length, size - length);
|
if(from != size) System.arraycopy(data, from, data, from+length, size - from);
|
||||||
size+=length;
|
size+=length;
|
||||||
System.arraycopy(a, offset, data, from, length);
|
System.arraycopy(a, offset, data, from, length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,6 +365,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
|
||||||
KEY_TYPE[] data = this.data;
|
KEY_TYPE[] data = this.data;
|
||||||
int size = data.length;
|
int size = data.length;
|
||||||
if(from < 0 || from > size) throw new IndexOutOfBoundsException("Index: " + from + ", Size: " + size);
|
if(from < 0 || from > size) throw new IndexOutOfBoundsException("Index: " + from + ", Size: " + size);
|
||||||
|
SanityChecks.checkArrayCapacity(a.length, offset, length);
|
||||||
KEY_TYPE[] newElements;
|
KEY_TYPE[] newElements;
|
||||||
if(from == size) {
|
if(from == size) {
|
||||||
newElements = Arrays.copyOf(data, size+length);
|
newElements = Arrays.copyOf(data, size+length);
|
||||||
|
@ -1580,7 +1581,7 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
checkSubRange(from);
|
checkSubRange(from);
|
||||||
checkSubRange(to);
|
checkAddSubRange(to);
|
||||||
list.removeElements(from+parentOffset, to+parentOffset);
|
list.removeElements(from+parentOffset, to+parentOffset);
|
||||||
size -= to - from;
|
size -= to - from;
|
||||||
}
|
}
|
||||||
|
@ -1596,9 +1597,9 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
checkSubRange(from);
|
checkSubRange(from);
|
||||||
checkSubRange(to);
|
checkAddSubRange(to);
|
||||||
K[] result = list.extractElements(from+parentOffset, to+parentOffset, type);
|
K[] result = list.extractElements(from+parentOffset, to+parentOffset, type);
|
||||||
size -= to - from;
|
size -= result.length;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1613,9 +1614,9 @@ public class COPY_ON_WRITE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENER
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
checkSubRange(from);
|
checkSubRange(from);
|
||||||
checkSubRange(to);
|
checkAddSubRange(to);
|
||||||
KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset);
|
KEY_TYPE[] result = list.extractElements(from+parentOffset, to+parentOffset);
|
||||||
size -= to - from;
|
size -= result.length;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|
|
@ -276,6 +276,7 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
|
public void addElements(int from, KEY_TYPE[] a, int offset, int length) {
|
||||||
|
if(length <= 0) return;
|
||||||
SanityChecks.checkArrayCapacity(a.length, offset, length);
|
SanityChecks.checkArrayCapacity(a.length, offset, length);
|
||||||
checkAddRange(from);
|
checkAddRange(from);
|
||||||
Entry KEY_GENERIC_TYPE next;
|
Entry KEY_GENERIC_TYPE next;
|
||||||
|
@ -617,12 +618,14 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
||||||
first = temp;
|
first = temp;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
else if(before.next != last) {
|
||||||
Entry KEY_GENERIC_TYPE temp = last;
|
Entry KEY_GENERIC_TYPE temp = last;
|
||||||
last = temp.prev;
|
last = temp.prev;
|
||||||
last.next = null;
|
last.next = null;
|
||||||
temp.next = before.next;
|
temp.next = before.next;
|
||||||
temp.prev = before;
|
temp.prev = before;
|
||||||
before.next = temp;
|
before.next = temp;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,12 +650,14 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
||||||
first = temp;
|
first = temp;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if(before.next != last) {
|
||||||
Entry KEY_GENERIC_TYPE temp = last;
|
Entry KEY_GENERIC_TYPE temp = last;
|
||||||
last = temp.prev;
|
last = temp.prev;
|
||||||
last.next = null;
|
last.next = null;
|
||||||
temp.next = before.next;
|
temp.next = before.next;
|
||||||
temp.prev = before;
|
temp.prev = before;
|
||||||
before.next = temp;
|
before.next = temp;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -695,16 +700,18 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
||||||
if(from < size - to) {
|
if(from < size - to) {
|
||||||
Entry KEY_GENERIC_TYPE entry = getNode(from);
|
Entry KEY_GENERIC_TYPE entry = getNode(from);
|
||||||
while(length > 0) {
|
while(length > 0) {
|
||||||
entry = entry.next;
|
Entry KEY_GENERIC_TYPE next = entry.next;
|
||||||
unlink(entry.prev);
|
unlink(entry);
|
||||||
|
entry = next;
|
||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Entry KEY_GENERIC_TYPE entry = getNode(to);
|
Entry KEY_GENERIC_TYPE entry = getNode(to);
|
||||||
while(length > 0) {
|
while(length > 0) {
|
||||||
entry = entry.prev;
|
Entry KEY_GENERIC_TYPE prev = entry.prev;
|
||||||
unlink(entry.next);
|
unlink(entry);
|
||||||
|
entry = prev;
|
||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,15 +727,17 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
||||||
if(from < size - to) {
|
if(from < size - to) {
|
||||||
Entry KEY_GENERIC_TYPE entry = getNode(from);
|
Entry KEY_GENERIC_TYPE entry = getNode(from);
|
||||||
for(int i = 0;length > 0;i++, length--) {
|
for(int i = 0;length > 0;i++, length--) {
|
||||||
entry = entry.next;
|
Entry KEY_GENERIC_TYPE next = entry.next;
|
||||||
a[i] = (K)unlink(entry.prev);
|
a[i] = (K)unlink(entry);
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
Entry KEY_GENERIC_TYPE entry = getNode(to);
|
Entry KEY_GENERIC_TYPE entry = getNode(to);
|
||||||
for(int i = length-1;length > 0;i--) {
|
for(int i = length-1;length > 0;i--, length--) {
|
||||||
entry = entry.prev;
|
Entry KEY_GENERIC_TYPE prev = entry.prev;
|
||||||
a[i] = (K)unlink(entry.next);
|
a[i] = (K)unlink(entry);
|
||||||
|
entry = prev;
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
@ -744,15 +753,17 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
|
||||||
if(from < size - to) {
|
if(from < size - to) {
|
||||||
Entry KEY_GENERIC_TYPE entry = getNode(from);
|
Entry KEY_GENERIC_TYPE entry = getNode(from);
|
||||||
for(int i = 0;length > 0;i++, length--) {
|
for(int i = 0;length > 0;i++, length--) {
|
||||||
entry = entry.next;
|
Entry KEY_GENERIC_TYPE next = entry.next;
|
||||||
d[i] = unlink(entry.prev);
|
d[i] = unlink(entry);
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
Entry KEY_GENERIC_TYPE entry = getNode(to);
|
Entry KEY_GENERIC_TYPE entry = getNode(to);
|
||||||
for(int i = length-1;length > 0;i--) {
|
for(int i = length-1;length > 0;i--, length--) {
|
||||||
entry = entry.prev;
|
Entry KEY_GENERIC_TYPE prev = entry.prev;
|
||||||
d[i] = unlink(entry.next);
|
d[i] = unlink(entry);
|
||||||
|
entry = prev;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
||||||
}
|
}
|
||||||
containsNull = true;
|
containsNull = true;
|
||||||
onNodeAdded(nullIndex);
|
onNodeAdded(nullIndex);
|
||||||
|
moveToFirstIndex(nullIndex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
|
int pos = HashUtil.mix(strategy.hashCode(o)) & mask;
|
||||||
|
@ -249,6 +250,7 @@ public class LINKED_CUSTOM_HASH_SET KEY_GENERIC_TYPE extends CUSTOM_HASH_SET KEY
|
||||||
}
|
}
|
||||||
keys[pos] = o;
|
keys[pos] = o;
|
||||||
onNodeAdded(pos);
|
onNodeAdded(pos);
|
||||||
|
moveToFirstIndex(pos);
|
||||||
}
|
}
|
||||||
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
|
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -208,6 +208,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
||||||
}
|
}
|
||||||
containsNull = true;
|
containsNull = true;
|
||||||
onNodeAdded(nullIndex);
|
onNodeAdded(nullIndex);
|
||||||
|
moveToFirstIndex(nullIndex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
|
int pos = HashUtil.mix(KEY_TO_HASH(o)) & mask;
|
||||||
|
@ -220,6 +221,7 @@ public class LINKED_HASH_SET KEY_GENERIC_TYPE extends HASH_SET KEY_GENERIC_TYPE
|
||||||
}
|
}
|
||||||
keys[pos] = o;
|
keys[pos] = o;
|
||||||
onNodeAdded(pos);
|
onNodeAdded(pos);
|
||||||
|
moveToFirstIndex(pos);
|
||||||
}
|
}
|
||||||
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
|
if(size++ >= maxFill) rehash(HashUtil.arraySize(size+1, loadFactor));
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue