TreeMap passes all tests from Apache Harmony

This commit is contained in:
konsoletyper 2014-04-01 16:42:02 +04:00
parent 161c4c76b7
commit 05569f4eef
2 changed files with 92 additions and 33 deletions

View File

@ -246,9 +246,7 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
while (node != null) { while (node != null) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
int cmp = comparator.compare((K)key, node.getKey()); int cmp = comparator.compare((K)key, node.getKey());
if (cmp == 0) { if (cmp < 0) {
break;
} else if (cmp < 0) {
lastLeftTurn = node; lastLeftTurn = node;
node = node.left; node = node.left;
} else { } else {
@ -266,9 +264,7 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
while (node != null) { while (node != null) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
int cmp = comparator.compare((K)key, node.getKey()); int cmp = comparator.compare((K)key, node.getKey());
if (cmp == 0) { if (cmp < 0) {
break;
} else if (cmp < 0) {
path[depth++] = node; path[depth++] = node;
node = node.left; node = node.left;
} else { } else {
@ -296,6 +292,27 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
return lastRightTurn; return lastRightTurn;
} }
TreeNode<K, V>[] pathToExactOrPrev(Object key) {
@SuppressWarnings("unchecked")
TreeNode<K, V>[] path = (TreeNode<K, V>[])new TreeNode<?, ?>[height()];
int depth = 0;
TreeNode<K, V> node = root;
while (node != null) {
@SuppressWarnings("unchecked")
int cmp = comparator.compare((K)key, node.getKey());
if (cmp == 0) {
path[depth++] = node;
break;
} else if (cmp > 0) {
path[depth++] = node;
node = node.right;
} else {
node = node.left;
}
}
return TArrays.copyOf(path, depth);
}
TreeNode<K, V>[] pathToFirst() { TreeNode<K, V>[] pathToFirst() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
TreeNode<K, V>[] path = (TreeNode<K, V>[])new TreeNode<?, ?>[height()]; TreeNode<K, V>[] path = (TreeNode<K, V>[])new TreeNode<?, ?>[height()];
@ -314,9 +331,7 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
while (node != null) { while (node != null) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
int cmp = comparator.compare((K)key, node.getKey()); int cmp = comparator.compare((K)key, node.getKey());
if (cmp == 0) { if (cmp > 0) {
return node;
} else if (cmp > 0) {
lastRightTurn = node; lastRightTurn = node;
node = node.right; node = node.right;
} else { } else {
@ -326,6 +341,24 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
return lastRightTurn; return lastRightTurn;
} }
TreeNode<K, V>[] pathToPrev(Object key) {
@SuppressWarnings("unchecked")
TreeNode<K, V>[] path = (TreeNode<K, V>[])new TreeNode<?, ?>[height()];
int depth = 0;
TreeNode<K, V> node = root;
while (node != null) {
@SuppressWarnings("unchecked")
int cmp = comparator.compare((K)key, node.getKey());
if (cmp > 0) {
path[depth++] = node;
node = node.right;
} else {
node = node.left;
}
}
return TArrays.copyOf(path, depth);
}
private TreeNode<K, V> getOrCreateNode(TreeNode<K, V> root, K key) { private TreeNode<K, V> getOrCreateNode(TreeNode<K, V> root, K key) {
if (root == null) { if (root == null) {
return new TreeNode<>(key); return new TreeNode<>(key);
@ -407,7 +440,7 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
@Override @Override
public TSortedMap<K, V> tailMap(K fromKey) { public TSortedMap<K, V> tailMap(K fromKey) {
return new SubMap<>(this, fromKey, false, true, null, false, false); return new SubMap<>(this, fromKey, true, true, null, false, false);
} }
@Override @Override
@ -465,6 +498,7 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
} }
private static class EntrySet<K, V> extends TAbstractSet<Entry<K, V>> { private static class EntrySet<K, V> extends TAbstractSet<Entry<K, V>> {
private int modCount = -1;
private TTreeMap<K, V> owner; private TTreeMap<K, V> owner;
private K from; private K from;
private boolean fromIncluded; private boolean fromIncluded;
@ -472,6 +506,7 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
private K to; private K to;
private boolean toIncluded; private boolean toIncluded;
private boolean toChecked; private boolean toChecked;
private int cachedSize;
public EntrySet(TTreeMap<K, V> owner, K from, boolean fromIncluded, boolean fromChecked, public EntrySet(TTreeMap<K, V> owner, K from, boolean fromIncluded, boolean fromChecked,
K to, boolean toIncluded, boolean toChecked) { K to, boolean toIncluded, boolean toChecked) {
@ -486,18 +521,29 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
@Override @Override
public int size() { public int size() {
int size = owner.size(); int size = cachedSize;
if (fromChecked) { if (modCount != owner.modCount) {
TreeNode<K, V> node = fromIncluded ? owner.findPrev(from) : owner.findExactOrPrev(from); modCount = owner.modCount;
if (node != null) { size = owner.size();
size -= node.size; if (fromChecked) {
TreeNode<K, V>[] path = fromIncluded ? owner.pathToPrev(from) : owner.pathToExactOrPrev(from);
for (TreeNode<K, V> node : path) {
if (node.left != null) {
size -= node.left.size;
}
}
size -= path.length;
} }
} if (toChecked) {
if (toChecked) { TreeNode<K, V> path[] = toIncluded ? owner.pathToNext(to) : owner.pathToExactOrNext(to);
TreeNode<K, V> node = toIncluded ? owner.findNext(to) : owner.findExactOrNext(to); for (TreeNode<K, V> node : path) {
if (node != null) { if (node.right != null) {
size -= node.size; size -= node.right.size;
}
}
size -= path.length;
} }
cachedSize = size;
} }
return size; return size;
} }
@ -546,7 +592,7 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return from == to; return size() == 0;
} }
} }
@ -608,7 +654,9 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
} }
} }
private static class SubMap<K, V> extends TAbstractMap<K, V> implements TSortedMap<K, V> { private static class SubMap<K, V> extends TAbstractMap<K, V> implements TSortedMap<K, V>, TSerializable {
private int modCount = -1;
private int cachedSize;
private TTreeMap<K, V> owner; private TTreeMap<K, V> owner;
private K from; private K from;
private boolean fromIncluded; private boolean fromIncluded;
@ -679,18 +727,29 @@ public class TTreeMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
@Override @Override
public int size() { public int size() {
int size = owner.size(); int size = cachedSize;
if (fromChecked) { if (modCount != owner.modCount) {
TreeNode<K, V> node = fromIncluded ? owner.findPrev(from) : owner.findExactOrPrev(from); modCount = owner.modCount;
if (node != null) { size = owner.size();
size -= node.size; if (fromChecked) {
TreeNode<K, V>[] path = fromIncluded ? owner.pathToPrev(from) : owner.pathToExactOrPrev(from);
for (TreeNode<K, V> node : path) {
if (node.left != null) {
size -= node.left.size;
}
}
size -= path.length;
} }
} if (toChecked) {
if (toChecked) { TreeNode<K, V> path[] = toIncluded ? owner.pathToNext(to) : owner.pathToExactOrNext(to);
TreeNode<K, V> node = toIncluded ? owner.findNext(to) : owner.findExactOrNext(to); for (TreeNode<K, V> node : path) {
if (node != null) { if (node.right != null) {
size -= node.size; size -= node.right.size;
}
}
size -= path.length;
} }
cachedSize = size;
} }
return size; return size;
} }

View File

@ -471,7 +471,7 @@ public class TreeMapTest {
// Regression for Harmony-1066 // Regression for Harmony-1066
assertTrue(tail instanceof Serializable); assertTrue(tail instanceof Serializable);
SortedMap<Integer,Integer> intMap,sub; SortedMap<Integer,Integer> intMap,sub;
int size = 16; int size = 16;
intMap = new TreeMap<>(); intMap = new TreeMap<>();
for(int i=0; i<size; i++) { for(int i=0; i<size; i++) {