We are now to 16k tests. Fixed loads of issues.

-Added: Tests for Lists and Sets.
-Fixed: SubLists are now stable (they weren't before)
-Fixed: All the bugs that the unit tests found so far.
-Updated: ReadMe/Changelog
This commit is contained in:
2021-12-11 12:53:58 +01:00
parent eaa45976c7
commit e1df59d512
24 changed files with 747 additions and 219 deletions
@@ -1389,6 +1389,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
private class MapIterator {
int pos = nullIndex;
int returnedPos = -1;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
@@ -1420,6 +1421,7 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
returnedPos = pos;
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
int value = findIndex(wrapped.GET_KEY(nextIndex));
@@ -1439,9 +1441,10 @@ public class CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VAL
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else if(lastReturned >= 0) shiftKeys(lastReturned);
else if(returnedPos >= 0) shiftKeys(returnedPos);
else {
CUSTOM_HASH_MAP.this.remove(wrapped.GET_KEY(-lastReturned - 1));
CUSTOM_HASH_MAP.this.remove(wrapped.GET_KEY(-returnedPos - 1));
lastReturned = -1;
return;
}
size--;
@@ -1345,6 +1345,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
private class MapIterator {
int pos = nullIndex;
int returnedPos = -1;
int lastReturned = -1;
int nextIndex = Integer.MIN_VALUE;
boolean returnNull = containsNull;
@@ -1376,6 +1377,7 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
returnedPos = pos;
if(nextIndex < 0){
lastReturned = Integer.MAX_VALUE;
int value = findIndex(wrapped.GET_KEY(nextIndex));
@@ -1395,9 +1397,10 @@ public class HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENE
keys[nullIndex] = EMPTY_KEY_VALUE;
values[nullIndex] = EMPTY_VALUE;
}
else if(lastReturned >= 0) shiftKeys(lastReturned);
else if(returnedPos >= 0) shiftKeys(returnedPos);
else {
HASH_MAP.this.remove(wrapped.GET_KEY(-lastReturned - 1));
HASH_MAP.this.remove(wrapped.GET_KEY(-returnedPos - 1));
lastReturned = -1;
return;
}
size--;
@@ -261,7 +261,7 @@ public class IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_
newValues[pos] = b[i];
continue;
}
while(KEY_EQUALS_NOT_NULL((current = newKeys[pos = (++pos & mask)]))) {
while(KEY_EQUALS_NOT_NULL((current = newKeys[pos = (++pos & newMask)]))) {
if(KEY_EQUALS(current, o)) {
found = false;
newValues[pos] = b[i];
@@ -202,8 +202,11 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
int index = findIndex(key);
if(index >= 0) insertIndex(size++, key, value);
return getDefaultReturnValue();
if(index < 0) {
insertIndex(size++, key, value);
return getDefaultReturnValue();
}
return values[index];
}
#if VALUE_PRIMITIVES
@@ -463,6 +466,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
@@ -481,6 +485,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = mappingFunction.GET_VALUE(key);
@@ -488,11 +493,18 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
insertIndex(size++, key, newValue);
return newValue;
}
return values[index];
VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
return newValue;
}
@Override
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
int index = findIndex(key);
if(index == -1) {
VALUE_TYPE newValue = valueProvider.VALUE_GET_KEY();
@@ -500,13 +512,20 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
insertIndex(size++, key, newValue);
return newValue;
}
return values[index];
VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
int index = findIndex(key);
if(index == -1) return getDefaultReturnValue();
if(index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
removeIndex(index);
@@ -518,8 +537,12 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if VALUE_OBJECT
Objects.requireNonNull(value);
#endif
int index = findIndex(key);
VALUE_TYPE newValue = index == -1 ? value : mappingFunction.APPLY_VALUE(values[index], value);
VALUE_TYPE newValue = index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(values[index], value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(index >= 0)
removeIndex(index);
@@ -535,7 +558,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) {
KEY_TYPE key = entry.ENTRY_KEY();
int index = findIndex(key);
VALUE_TYPE newValue = index == -1 ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
VALUE_TYPE newValue = index == -1 || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(index >= 0)
removeIndex(index);
@@ -683,21 +706,18 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
#endif
protected int findIndex(Object key, Object value) {
if(key == null || value == null) return -1;
for(int i = size-1;i>=0;i--)
if(EQUALS_KEY_TYPE(keys[i], key) && EQUALS_VALUE_TYPE(values[i], value)) return i;
return -1;
}
protected int findIndex(Object key) {
if(key == null) return -1;
for(int i = size-1;i>=0;i--)
if(EQUALS_KEY_TYPE(keys[i], key)) return i;
return -1;
}
protected int findValue(Object value) {
if(value == null) return -1;
for(int i = size-1;i>=0;i--)
if(EQUALS_VALUE_TYPE(values[i], value)) return i;
return -1;
@@ -1069,21 +1089,18 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
#endif
protected int findIndex(Object key, Object value) {
if(key == null || value == null) return -1;
for(int i = length-1;i>=0;i--)
if(EQUALS_KEY_TYPE(keys[offset+i], key) && EQUALS_VALUE_TYPE(values[offset+i], value)) return i+offset;
return -1;
}
protected int findIndex(Object key) {
if(key == null) return -1;
for(int i = length-1;i>=0;i--)
if(EQUALS_KEY_TYPE(keys[offset+i], key)) return i+offset;
return -1;
}
protected int findValue(Object value) {
if(value == null) return -1;
for(int i = length-1;i>=0;i--)
if(EQUALS_VALUE_TYPE(values[offset+i], value)) return i+offset;
return -1;
@@ -1268,8 +1285,14 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Deprecated
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return SubMap.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return SubMap.this.containsKey(((Map.Entry<?, ?>)o).getKey());
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
return SubMap.this.findIndex(entry.ENTRY_KEY(), entry.ENTRY_VALUE()) >= 0;
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
return ARRAY_MAP.this.findIndex(entry.getKey(), entry.getValue()) >= 0;
}
}
return false;
}
@@ -1318,7 +1341,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean remove(Object o) {
int oldSize = length;
remove(o);
SubMap.this.remove(o);
return length != oldSize;
}
@@ -1329,7 +1352,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean remove(KEY_TYPE o) {
int oldSize = length;
remove(o);
SubMap.this.remove(o);
return length != oldSize;
}
@@ -1737,12 +1760,14 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
int returnIndex = offset+index;
lastReturned = index--;
return returnIndex;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
int returnIndex = offset+index;
lastReturned = index++;
return returnIndex;
@@ -1944,8 +1969,16 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Deprecated
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return ARRAY_MAP.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return ARRAY_MAP.this.containsKey(((Map.Entry<?, ?>)o).getKey());
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
int index = ARRAY_MAP.this.findIndex(entry.ENTRY_KEY());
if(index >= 0) return VALUE_EQUALS(entry.ENTRY_VALUE(), ARRAY_MAP.this.values[index]);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
int index = ARRAY_MAP.this.findIndex(entry.getKey());
if(index >= 0) return Objects.equals(entry.getValue(), VALUE_TO_OBJ(ARRAY_MAP.this.values[index]));
}
}
return false;
}
@@ -1994,7 +2027,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean remove(Object o) {
int oldSize = size;
remove(o);
ARRAY_MAP.this.remove(o);
return size != oldSize;
}
@@ -2005,7 +2038,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public boolean remove(KEY_TYPE o) {
int oldSize = size;
remove(o);
ARRAY_MAP.this.remove(o);
return size != oldSize;
}
@@ -2401,11 +2434,13 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
}
public int previousEntry() {
if(!hasPrevious()) throw new NoSuchElementException();
lastReturned = index;
return index--;
}
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
lastReturned = index;
return index++;
}
@@ -2480,7 +2515,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
@Override
public String toString() {
return KEY_TO_STRING(keys[index]) + "->" + VALUE_TO_STRING(values[index]);
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]);
}
}
}
@@ -183,6 +183,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
#endif
@Override
public boolean containsKey(Object key) {
if(!keyType.isInstance(key)) return false;
return isSet(((T)key).ordinal());
}
@@ -190,7 +191,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override
public boolean containsValue(Object value) {
for(int i = 0;i<values.length;i++)
if(VALUE_EQUALS(value, values[i])) return true;
if(isSet(i) && VALUE_EQUALS(value, values[i])) return true;
return false;
}
@@ -198,13 +199,25 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override
public boolean containsValue(VALUE_TYPE value) {
for(int i = 0;i<values.length;i++)
if(VALUE_EQUALS(value, values[i])) return true;
if(isSet(i) && VALUE_EQUALS(value, values[i])) return true;
return false;
}
#endif
@Override
public CLASS_VALUE_TYPE remove(Object key) {
if(!keyType.isInstance(key)) return getDefaultReturnValue();
int index = ((T)key).ordinal();
if(!isSet(index)) return getDefaultReturnValue();
clear(index);
VALUE_TYPE result = values[index];
values[index] = EMPTY_VALUE;
return result;
}
@Override
public VALUE_TYPE rem(T key) {
if(!keyType.isInstance(key)) return getDefaultReturnValue();
int index = key.ordinal();
if(!isSet(index)) return getDefaultReturnValue();
clear(index);
@@ -246,6 +259,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
#endif
@Override
public VALUE_TYPE GET_VALUE(T key) {
if(!keyType.isInstance(key)) return getDefaultReturnValue();
int index = key.ordinal();
return isSet(index) ? values[index] : getDefaultReturnValue();
}
@@ -253,6 +267,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
#if VALUE_OBJECT
@Override
public VALUE_TYPE getOrDefault(Object key, VALUE_TYPE defaultValue) {
if(!keyType.isInstance(key)) return defaultValue;
int index = ((T)key).ordinal();
return isSet(index) ? values[index] : defaultValue;
}
@@ -260,6 +275,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
#else
@Override
public VALUE_TYPE getOrDefault(T key, VALUE_TYPE defaultValue) {
if(!keyType.isInstance(key)) return defaultValue;
int index = key.ordinal();
return isSet(index) ? values[index] : defaultValue;
}
@@ -347,7 +363,13 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
values[index] = newValue;
return newValue;
}
return values[index];
VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = mappingFunction.GET_VALUE(key);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
return newValue;
}
@Override
@@ -360,13 +382,19 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
values[index] = newValue;
return newValue;
}
return values[index];
VALUE_TYPE newValue = values[index];
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
newValue = valueProvider.VALUE_GET_KEY();
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
values[index] = newValue;
}
return newValue;
}
@Override
public VALUE_TYPE COMPUTE_IF_PRESENT(T key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal();
if(!isSet(index)) return getDefaultReturnValue();
if(!isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue())) return getDefaultReturnValue();
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, values[index]);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
clear(index);
@@ -380,7 +408,10 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override
public VALUE_TYPE MERGE(T key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
int index = key.ordinal();
VALUE_TYPE newValue = !isSet(index) ? value : mappingFunction.APPLY_VALUE(values[index], value);
#if VALUE_OBJECT
Objects.requireNonNull(value);
#endif
VALUE_TYPE newValue = !isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(values[index], value);
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(isSet(index)) {
clear(index);
@@ -401,7 +432,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : MAPS.fastIterable(m)) {
T key = entry.ENTRY_KEY();
int index = key.ordinal();
VALUE_TYPE newValue = !isSet(index) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
VALUE_TYPE newValue = !isSet(index) || VALUE_EQUALS(values[index], getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(values[index], entry.ENTRY_VALUE());
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
if(isSet(index)) {
clear(index);
@@ -424,6 +455,11 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
Arrays.fill(values, EMPTY_VALUE);
}
@Override
public int size() {
return size;
}
protected void onNodeAdded(int index) {
}
@@ -433,9 +469,9 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
}
protected void set(int index) {
size++;
present[index >> 6] |= (1L << index);
onNodeAdded(index);
present[index >> 6] |= (1L << index);
size++;
}
protected void clear(int index) {
size--;
@@ -452,7 +488,20 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
@Override
public boolean contains(Object o) {
if(o instanceof Map.Entry) return containsKey(((Map.Entry<?, ?>)o).getKey());
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(!keyType.isInstance(entry.ENTRY_KEY())) return false;
int index = ((T)entry.ENTRY_KEY()).ordinal();
if(index >= 0 && ENUM_MAP.this.isSet(index)) return VALUE_EQUALS(entry.ENTRY_VALUE(), ENUM_MAP.this.values[index]);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(!keyType.isInstance(entry.getKey())) return false;
int index = ((T)entry.getKey()).ordinal();
if(index >= 0 && ENUM_MAP.this.isSet(index)) return Objects.equals(entry.getValue(), VALUE_TO_OBJ(ENUM_MAP.this.values[index]));
}
}
return false;
}
@@ -548,8 +597,7 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
class EntryIterator extends MapIterator implements ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
int index = nextEntry();
return new BasicEntry<>(keys[index], values[index]);
return new MapEntry(nextEntry());
}
}
@@ -584,13 +632,74 @@ public class ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE
public int nextEntry() {
if(!hasNext()) throw new NoSuchElementException();
lastReturnValue = nextIndex;
return nextIndex;
nextIndex = -1;
return lastReturnValue;
}
public void remove() {
if(lastReturnValue == -1) throw new IllegalStateException();
clear(lastReturnValue);
values[lastReturnValue] = EMPTY_VALUE;
lastReturnValue = -1;
}
}
protected class MapEntry implements MAP.Entry KEY_VALUE_GENERIC_TYPE, Map.Entry<CLASS_TYPE, CLASS_VALUE_TYPE> {
public int index = -1;
public MapEntry() {}
public MapEntry(int index) {
this.index = index;
}
@Override
public KEY_TYPE ENTRY_KEY() {
return keys[index];
}
@Override
public VALUE_TYPE ENTRY_VALUE() {
return values[index];
}
@Override
public VALUE_TYPE setValue(VALUE_TYPE value) {
VALUE_TYPE oldValue = values[index];
values[index] = value;
return oldValue;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Map.Entry) {
if(obj instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
return KEY_EQUALS(keys[index], entry.ENTRY_KEY()) && VALUE_EQUALS(values[index], entry.ENTRY_VALUE());
}
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
Object key = entry.getKey();
Object value = entry.getValue();
#if TYPE_OBJECT && VALUE_OBJECT
return KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], value);
#else if TYPE_OBJECT
return value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], key) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value));
#else if VALUE_OBJECT
return key instanceof CLASS_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], value);
#else
return key instanceof CLASS_TYPE && value instanceof CLASS_VALUE_TYPE && KEY_EQUALS(keys[index], CLASS_TO_KEY(key)) && VALUE_EQUALS(values[index], CLASS_TO_VALUE(value));
#endif
}
return false;
}
@Override
public int hashCode() {
return KEY_TO_HASH(keys[index]) ^ VALUE_TO_HASH(values[index]);
}
@Override
public String toString() {
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]);
}
}
}
@@ -109,7 +109,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
links = enumMap.links.clone();
size = enumMap.size;
}
if(map instanceof ENUM_MAP) {
else if(map instanceof ENUM_MAP) {
ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
keyType = enumMap.keyType;
keys = enumMap.keys;
@@ -156,7 +156,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
links = enumMap.links.clone();
size = enumMap.size;
}
if(map instanceof ENUM_MAP) {
else if(map instanceof ENUM_MAP) {
ENUM_MAP KEY_VALUE_GENERIC_TYPE enumMap = (ENUM_MAP KEY_VALUE_GENERIC_TYPE)map;
keyType = enumMap.keyType;
keys = enumMap.keys;
@@ -519,8 +519,18 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Deprecated
public boolean contains(Object o) {
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) return LINKED_ENUM_MAP.this.containsKey(((MAP.Entry KEY_VALUE_GENERIC_TYPE)o).ENTRY_KEY());
return LINKED_ENUM_MAP.this.containsKey(((Map.Entry<?, ?>)o).getKey());
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(!keyType.isInstance(entry.ENTRY_KEY())) return false;
int index = ((T)entry.ENTRY_KEY()).ordinal();
if(index >= 0 && LINKED_ENUM_MAP.this.isSet(index)) return VALUE_EQUALS(entry.ENTRY_VALUE(), LINKED_ENUM_MAP.this.values[index]);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(!keyType.isInstance(entry.getKey())) return false;
int index = ((T)entry.getKey()).ordinal();
if(index >= 0 && LINKED_ENUM_MAP.this.isSet(index)) return Objects.equals(entry.getValue(), VALUE_TO_OBJ(LINKED_ENUM_MAP.this.values[index]));
}
}
return false;
}
@@ -572,7 +582,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public boolean remove(Object o) {
int oldSize = size;
remove(o);
LINKED_ENUM_MAP.this.remove(o);
return size != oldSize;
}
@@ -585,7 +595,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public boolean remove(T o) {
int oldSize = size;
remove(o);
LINKED_ENUM_MAP.this.remove(o);
return size != oldSize;
}
@@ -887,6 +897,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
previous = (int)(links[current] >>> 32);
}
else next = (int)links[current];
size--;
if(previous == -1) firstIndex = next;
else links[previous] ^= ((links[previous] ^ (next & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
@@ -894,6 +905,8 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
if (next == -1) lastIndex = previous;
else links[next] ^= ((links[next] ^ ((previous & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
values[current] = EMPTY_VALUE;
present[current >> 6] &= ~(1L << current);
current = -1;
}
public int previousEntry() {
@@ -985,7 +998,7 @@ public class LINKED_ENUM_MAP KEY_ENUM_VALUE_GENERIC_TYPE extends ENUM_MAP KEY_VA
@Override
public String toString() {
return KEY_TO_STRING(keys[index]) + "->" + VALUE_TO_STRING(values[index]);
return KEY_TO_STRING(keys[index]) + "=" + VALUE_TO_STRING(values[index]);
}
}
}
@@ -234,7 +234,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
@Override
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -271,7 +271,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -309,7 +309,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
@Override
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -521,7 +521,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -543,7 +543,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -564,7 +564,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -585,7 +585,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
@@ -602,7 +602,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
VALUE_TYPE newValue = entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(entry.value, value);
@@ -899,6 +899,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
}
}
protected void validate(KEY_TYPE k) { compare(k, k); }
protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);}
/** From CLR */
@@ -1532,13 +1533,13 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
AVL_TREE_MAP.Entry KEY_VALUE_GENERIC_TYPE subEntry = m.findNode(entry.ENTRY_KEY());
if(subEntry != null) return VALUE_EQUALS(entry.ENTRY_VALUE(), subEntry.value);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
#if !TYPE_OBJECT
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
#endif
@@ -1938,13 +1939,13 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
AVL_TREE_MAP.Entry KEY_VALUE_GENERIC_TYPE subEntry = AVL_TREE_MAP.this.findNode(entry.ENTRY_KEY());
if(subEntry != null) return VALUE_EQUALS(entry.ENTRY_VALUE(), subEntry.value);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
#if !TYPE_OBJECT
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
#endif
@@ -234,7 +234,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
@Override
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -271,7 +271,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
@Override
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
@@ -310,7 +310,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
@Override
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) {
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
if(tree == null) {
tree = first = last = new EntryKV_BRACES(key, value, null);
@@ -521,7 +521,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -543,7 +543,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -564,7 +564,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
Objects.requireNonNull(valueProvider);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null) {
@@ -585,7 +585,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
@@ -602,7 +602,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
Objects.requireNonNull(mappingFunction);
#if TYPE_OBJECT
Objects.requireNonNull(key);
validate(key);
#endif
Entry KEY_VALUE_GENERIC_TYPE entry = findNode(key);
VALUE_TYPE newValue = entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(entry.value, value);
@@ -905,6 +905,7 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
}
}
protected void validate(KEY_TYPE k) { compare(k, k); }
protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);}
protected static GENERIC_KEY_VALUE_BRACES boolean isBlack(Entry KEY_VALUE_GENERIC_TYPE p) { return p == null || p.isBlack(); }
protected static GENERIC_KEY_VALUE_BRACES Entry KEY_VALUE_GENERIC_TYPE parentOf(Entry KEY_VALUE_GENERIC_TYPE p) { return (p == null ? null : p.parent); }
@@ -1587,13 +1588,13 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
RB_TREE_MAP.Entry KEY_VALUE_GENERIC_TYPE subEntry = m.findNode(entry.ENTRY_KEY());
if(subEntry != null) return VALUE_EQUALS(entry.ENTRY_VALUE(), subEntry.value);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
#if !TYPE_OBJECT
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
#endif
@@ -1993,13 +1994,13 @@ public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_G
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
RB_TREE_MAP.Entry KEY_VALUE_GENERIC_TYPE subEntry = RB_TREE_MAP.this.findNode(entry.ENTRY_KEY());
if(subEntry != null) return VALUE_EQUALS(entry.ENTRY_VALUE(), subEntry.value);
}
else {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)o;
if(entry.getKey() == null) return false;
if(entry.getKey() == null && comparator() == null) return false;
#if !TYPE_OBJECT
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
#endif