forked from Speiger/Primitive-Collections
Implemented tests.
-Added: ConcurrentHashMap test suite -Fixed: Bugs found in ConcurrentHashMaps with the iterator and clear function.
This commit is contained in:
parent
4448eca787
commit
d2c7c151bc
|
@ -550,7 +550,7 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
for(int i = 0,m=segments.length;i<m;i++) {
|
||||
size += segments[i].size;
|
||||
}
|
||||
return size > Integer.MAX_VALUE ? Integer.MAX_VALUE : 0;
|
||||
return size > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)size;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1288,16 +1288,16 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
int currentSegment = -1;
|
||||
|
||||
MapIterator() {
|
||||
nextSegment = getFirstSegment();
|
||||
if(nextSegment != -1) next = segments[nextSegment].firstIndex;
|
||||
currentSegment = getFirstSegment();
|
||||
if(currentSegment != -1) next = segments[currentSegment].firstIndex;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return next != -1;
|
||||
return next != -1 || nextSegment != -1;
|
||||
}
|
||||
|
||||
public boolean hasPrevious() {
|
||||
return previous != -1;
|
||||
return previous != -1 || previousSegment != -1;
|
||||
}
|
||||
|
||||
public int currentSegment() {
|
||||
|
@ -1306,16 +1306,30 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
|
||||
public int previousEntry() {
|
||||
if(!hasPrevious()) throw new NoSuchElementException();
|
||||
next = current = previous;
|
||||
nextSegment = currentSegment = previousSegment;
|
||||
if(previousSegment != -1) {
|
||||
nextSegment = currentSegment;
|
||||
currentSegment = previousSegment;
|
||||
previousSegment = -1;
|
||||
next = current = segments[currentSegment].lastIndex;
|
||||
}
|
||||
else {
|
||||
next = current = previous;
|
||||
}
|
||||
findPreviousIndex();
|
||||
return current;
|
||||
}
|
||||
|
||||
public int nextEntry() {
|
||||
if(!hasNext()) throw new NoSuchElementException();
|
||||
previous = current = next;
|
||||
previousSegment = currentSegment = nextSegment;
|
||||
if(nextSegment != -1) {
|
||||
previousSegment = currentSegment;
|
||||
currentSegment = nextSegment;
|
||||
nextSegment = -1;
|
||||
previous = current = segments[currentSegment].firstIndex;
|
||||
}
|
||||
else {
|
||||
previous = current = next;
|
||||
}
|
||||
findNextIndex();
|
||||
return current;
|
||||
}
|
||||
|
@ -1328,15 +1342,14 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
if(current == previous) findPreviousIndex();
|
||||
else findNextIndex();
|
||||
seg.size--;
|
||||
if(previousSegment != currentSegment) seg.firstIndex = next;
|
||||
if(previous == -1) seg.firstIndex = next;
|
||||
else seg.links[previous] ^= ((seg.links[previous] ^ (next & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
|
||||
|
||||
if(nextSegment != currentSegment) seg.lastIndex = previous;
|
||||
if(next == -1) seg.lastIndex = previous;
|
||||
else seg.links[next] ^= ((seg.links[next] ^ ((previous & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
|
||||
|
||||
if(current == seg.nullIndex) {
|
||||
current = -1;
|
||||
currentSegment = -1;
|
||||
seg.containsNull = false;
|
||||
seg.keys[seg.nullIndex] = EMPTY_KEY_VALUE;
|
||||
seg.values[seg.nullIndex] = EMPTY_VALUE;
|
||||
|
@ -1344,7 +1357,6 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
else {
|
||||
int slot, last, startPos = current;
|
||||
current = -1;
|
||||
currentSegment = -1;
|
||||
KEY_TYPE current;
|
||||
while(true) {
|
||||
startPos = ((last = startPos) + 1) & seg.mask;
|
||||
|
@ -1372,10 +1384,9 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
}
|
||||
|
||||
protected void findPreviousIndex() {
|
||||
previous = (int)(segments[currentSegment].links[current] >> 32);
|
||||
previous = (int)(segments[currentSegment].links[current] >>> 32);
|
||||
if(previous == -1) {
|
||||
previousSegment = findPreviousSegment(currentSegment-1);
|
||||
if(previousSegment != -1) previous = segments[previousSegment].lastIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1383,7 +1394,6 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
next = (int)(segments[currentSegment].links[current]);
|
||||
if(next == -1) {
|
||||
nextSegment = findNextSegment(currentSegment+1);
|
||||
if(nextSegment != -1) next = segments[nextSegment].firstIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1926,6 +1936,8 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
containsNull = false;
|
||||
Arrays.fill(keys, EMPTY_KEY_VALUE);
|
||||
Arrays.fill(values, EMPTY_VALUE);
|
||||
firstIndex = -1;
|
||||
lastIndex = -1;
|
||||
}
|
||||
finally {
|
||||
unlock();
|
||||
|
@ -1966,6 +1978,8 @@ public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY
|
|||
values = NEW_VALUE_ARRAY(arraySize);
|
||||
links = new long[arraySize];
|
||||
this.size = 0;
|
||||
firstIndex = -1;
|
||||
lastIndex = -1;
|
||||
containsNull = false;
|
||||
}
|
||||
finally {
|
||||
|
|
|
@ -1438,7 +1438,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
|
|||
if(previous == -1) firstIndex = next;
|
||||
else links[previous] ^= ((links[previous] ^ (next & 0xFFFFFFFFL)) & 0xFFFFFFFFL);
|
||||
|
||||
if (next == -1) lastIndex = previous;
|
||||
if(next == -1) lastIndex = previous;
|
||||
else links[next] ^= ((links[next] ^ ((previous & 0xFFFFFFFFL) << 32)) & 0xFFFFFFFF00000000L);
|
||||
if(current == nullIndex) {
|
||||
current = -1;
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.google.common.collect.testing.features.MapFeature;
|
|||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import speiger.src.collections.objects.maps.impl.concurrent.Object2ObjectConcurrentOpenHashMap;
|
||||
import speiger.src.collections.objects.maps.impl.customHash.Object2ObjectLinkedOpenCustomHashMap;
|
||||
import speiger.src.collections.objects.maps.impl.customHash.Object2ObjectOpenCustomHashMap;
|
||||
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectLinkedOpenHashMap;
|
||||
|
@ -42,6 +43,7 @@ public class ObjectMapTests extends TestCase
|
|||
suite.addTest(suite("LinkedHashMap", Object2ObjectLinkedOpenHashMap::new, true));
|
||||
suite.addTest(suite("CustomHashMap", () -> new Object2ObjectOpenCustomHashMap<>(Strategy.INSTANCE), true));
|
||||
suite.addTest(suite("LinkedCustomHashMap", () -> new Object2ObjectLinkedOpenCustomHashMap<>(Strategy.INSTANCE), true));
|
||||
suite.addTest(suite("ConcurrentHashMap", Object2ObjectConcurrentOpenHashMap::new, true));
|
||||
suite.addTest(navigableSuite("RBTreeMap_NonNull", Object2ObjectRBTreeMap::new, false));
|
||||
suite.addTest(navigableSuite("AVLTreeMap_NonNull", Object2ObjectAVLTreeMap::new, false));
|
||||
suite.addTest(navigableSuite("RBTreeMap_Null", () -> new Object2ObjectRBTreeMap<>(new NullFriendlyComparator()), true));
|
||||
|
|
Loading…
Reference in New Issue