diff --git a/gson/src/main/java/com/google/gson/internal/LinkedHashTreeMap.java b/gson/src/main/java/com/google/gson/internal/LinkedHashTreeMap.java index bb30bbac..18549675 100644 --- a/gson/src/main/java/com/google/gson/internal/LinkedHashTreeMap.java +++ b/gson/src/main/java/com/google/gson/internal/LinkedHashTreeMap.java @@ -38,6 +38,8 @@ import java.util.Set; * LinkedHashMap classes. */ public final class LinkedHashTreeMap extends AbstractMap implements Serializable { + private static final int MAX_CAPACITY = 8192; + @SuppressWarnings({ "unchecked", "rawtypes" }) // to avoid Comparable>> private static final Comparator NATURAL_ORDER = new Comparator() { public int compare(Comparable a, Comparable b) { @@ -564,10 +566,15 @@ public final class LinkedHashTreeMap extends AbstractMap implements * twice as many trees, each of (approximately) half the previous size. */ static Node[] doubleCapacity(Node[] oldTable) { - // TODO: don't do anything if we're already at MAX_CAPACITY int oldCapacity = oldTable.length; + if (oldCapacity >= MAX_CAPACITY) { + return oldTable; + } + + int newCapacity = oldCapacity * 2; + @SuppressWarnings("unchecked") // Arrays and generics don't get along. - Node[] newTable = new Node[oldCapacity * 2]; + Node[] newTable = new Node[newCapacity]; AvlIterator iterator = new AvlIterator(); AvlBuilder leftBuilder = new AvlBuilder(); AvlBuilder rightBuilder = new AvlBuilder(); @@ -584,7 +591,7 @@ public final class LinkedHashTreeMap extends AbstractMap implements int leftSize = 0; int rightSize = 0; for (Node node; (node = iterator.next()) != null; ) { - if ((node.hash & oldCapacity) == 0) { + if ((node.hash & (newCapacity - 1)) == i) { leftSize++; } else { rightSize++; @@ -599,7 +606,7 @@ public final class LinkedHashTreeMap extends AbstractMap implements rightBuilder.reset(rightSize); iterator.reset(root); for (Node node; (node = iterator.next()) != null; ) { - if ((node.hash & oldCapacity) == 0) { + if ((node.hash & (newCapacity - 1)) == i) { leftBuilder.add(node); } else { rightBuilder.add(node);