diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CharArrayObjectMapTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CharArrayObjectMapTest.java new file mode 100644 index 00000000000..093dd4a8d5e --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CharArrayObjectMapTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2016 Google, Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.parser.tests; + +import java.util.Random; + +import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; + +import junit.framework.TestCase; + +/** + * Tests for {@link CharArrayObjectMap}. + */ +public class CharArrayObjectMapTest extends TestCase { + + public void testMapAdd() { + CharArrayObjectMap map = new CharArrayObjectMap(4); + char[] key1 = "key1".toCharArray(); + Integer value1 = 43; + map.put(key1, value1); + + char[] key2 = "key1".toCharArray(); + Object value2 = map.get(key2); + assertEquals(value1, value2); + + for (int i = 0; i < 25; ++i) { + map.put(("ikey" + i).toCharArray(), Integer.valueOf(i)); + } + + for (int i = 0; i < 25; ++i) { + Object ivalue1 = map.get(("ikey" + i).toCharArray()); + assertEquals(i, ivalue1); + } + } + + public void testDuplicates() { + CharArrayObjectMap map = new CharArrayObjectMap(4); + String[] keys = new String[] { + "a", "b", "c", "c", "value", "value", "context", "context", "result", "d", "e", "f", "g", "h", "i", "j", + "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "z" + }; + for (int i = 0; i < keys.length; i++) { + String key = keys[i]; + map.put(key.toCharArray(), key + i); + } + assertEquals(29, map.size()); + for (int i = 0; i < keys.length; i++) { + String key = keys[i]; + if (i != 2 && i != 4 && i != 6 && i != 31) { + assertEquals(key + i, map.get(key.toCharArray())); + } + } + } + + public void testCollisionRatio() { + Random random = new Random(239); + CharArrayObjectMap map = new CharArrayObjectMap(1); + for (int i = 0; i < 20000; i++) { + int r = random.nextInt(); + map.put(("key" + Integer.toUnsignedString(i)).toCharArray(), i); + double collisionRatio = (double) map.countCollisions() / map.size(); + assertTrue(String.format("Collision ratio %.3f is unexpectedly high for map size of %d.", collisionRatio, map.size()), + collisionRatio <= 0.4); + } + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ObjectMapTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ObjectMapTest.java index 82cd9192eeb..a269e10b604 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ObjectMapTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ObjectMapTest.java @@ -14,15 +14,12 @@ */ package org.eclipse.cdt.core.parser.tests; -import java.util.Random; - -import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap; import junit.framework.TestCase; /** - * @author aniefer + * Tests for {@link ObjectMap}. */ public class ObjectMapTest extends TestCase { @@ -138,36 +135,4 @@ public class ObjectMapTest extends TestCase { insertContents(map, res); assertContents(map, res); } - - public void testMapAdd() { - CharArrayObjectMap map = new CharArrayObjectMap(4); - char[] key1 = "key1".toCharArray(); - Integer value1 = 43; - map.put(key1, value1); - - char[] key2 = "key1".toCharArray(); - Object value2 = map.get(key2); - assertEquals(value1, value2); - - for (int i = 0; i < 25; ++i) { - map.put(("ikey" + i).toCharArray(), Integer.valueOf(i)); - } - - for (int i = 0; i < 25; ++i) { - Object ivalue1 = map.get(("ikey" + i).toCharArray()); - assertEquals(i, ivalue1); - } - } - - public void testCollisionRatio() { - Random random = new Random(239); - CharArrayObjectMap map = new CharArrayObjectMap(1); - for (int i = 0; i < 20000; i++) { - int r = random.nextInt(); - map.put(("key" + Integer.toUnsignedString(i)).toCharArray(), i); - double collisionRatio = (double) map.countCollisions() / map.size(); - assertTrue(String.format("Collision ratio %.3f is unexpectedly high for map size of %d.", collisionRatio, map.size()), - collisionRatio <= 0.4); - } - } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java index 8929bcbb4d5..ce44122bac0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java @@ -11,10 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.core.parser.tests; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - import org.eclipse.cdt.core.model.tests.CModelElementsTests; import org.eclipse.cdt.core.model.tests.StructuralCModelElementsTests; import org.eclipse.cdt.core.parser.tests.ast2.DOMGCCParserExtensionTestSuite; @@ -22,6 +18,10 @@ import org.eclipse.cdt.core.parser.tests.ast2.DOMParserTestSuite; import org.eclipse.cdt.core.parser.tests.ast2.SemanticsTests; import org.eclipse.cdt.core.parser.tests.scanner.ScannerTestSuite; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + /** * Combines all tests for the parsers. */ @@ -34,6 +34,7 @@ public class ParserTestSuite extends TestCase { suite.addTestSuite(ContentAssistMatcherFactoryTest.class); suite.addTestSuite(CModelElementsTests.class); suite.addTestSuite(StructuralCModelElementsTests.class); + suite.addTestSuite(CharArrayObjectMapTest.class); suite.addTestSuite(ObjectMapTest.class); suite.addTestSuite(SemanticsTests.class); suite.addTest(ScannerTestSuite.suite()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayObjectMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayObjectMap.java index 2152096b560..da8a868d072 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayObjectMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayObjectMap.java @@ -25,7 +25,7 @@ import java.util.function.Consumer; /** * @author Doug Schaefer */ -public class CharArrayObjectMap extends CharTable { +public class CharArrayObjectMap extends CharTable { public static final CharArrayObjectMap EMPTY_MAP = new CharArrayObjectMap(0) { @Override public Object clone() { return this; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharTable.java index 6280a0b18ae..f33b0fa3d20 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharTable.java @@ -169,7 +169,7 @@ public class CharTable extends HashTable { if (CharArrayUtils.equals(buffer, start, len, keyTable[i])) return i; - // Follow the next chain + // Follow the next chain. for (i = nextTable[i] - 1; i >= 0 && i != nextTable[i] - 1; i = nextTable[i] - 1) { if (CharArrayUtils.equals(buffer, start, len, keyTable[i])) return i; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/HashTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/HashTable.java index 6a773a169dd..abceb621d86 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/HashTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/HashTable.java @@ -173,17 +173,18 @@ public class HashTable implements Cloneable { return offset; } - protected void linkIntoHashTable(int i, int hash) { + protected final void linkIntoHashTable(int i, int hash) { if (nextTable == null) return; - if (hashTable[hash] == 0) { + int j = hashTable[hash]; + if (j == 0) { hashTable[hash] = i + 1; } else { // Need to link. - int j = hashTable[hash] - 1; + j--; int k; - while ((k = nextTable[j]) != 0) { + while ((k = nextTable[j]) != 0 && k != j + 1) { j = k - 1; } nextTable[j] = i + 1;