From 8fbde688c8502bedaeee121b75598b1882d43d9e Mon Sep 17 00:00:00 2001 From: Cowtowncoder Date: Wed, 22 Apr 2015 16:58:52 -0700 Subject: [PATCH] Add tests to try to reproduce #191 (no luck yet) --- .../jackson/core/sym/TestSymbolTables.java | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/fasterxml/jackson/core/sym/TestSymbolTables.java b/src/test/java/com/fasterxml/jackson/core/sym/TestSymbolTables.java index b26144550e..ffd569c410 100644 --- a/src/test/java/com/fasterxml/jackson/core/sym/TestSymbolTables.java +++ b/src/test/java/com/fasterxml/jackson/core/sym/TestSymbolTables.java @@ -3,7 +3,7 @@ import java.io.IOException; import java.nio.charset.Charset; -import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.*; public class TestSymbolTables extends com.fasterxml.jackson.core.BaseTest { @@ -133,4 +133,79 @@ public void testCollisionsWithChars187() throws IOException // as well as collision counts assertEquals(10, symbols.maxCollisionLength()); } + + // [core#191]: similarly, but for "short" symbols: + public void testShortNameCollisionsViaParser() throws Exception + { + JsonFactory f = new JsonFactory(); + String json = _shortDoc191(); + JsonParser p; + + // First: ensure that char-based is fine + p = f.createParser(json); + while (p.nextToken() != null) { } + p.close(); + + // and then that byte-based + p = f.createParser(json.getBytes("UTF-8")); + while (p.nextToken() != null) { } + p.close(); + } + + // [core#191] + public void testShortNameCollisionsDirect() throws IOException + { + final int COUNT = 400; + + // First, char-based + { + CharsToNameCanonicalizer symbols = CharsToNameCanonicalizer.createRoot(1); + for (int i = 0; i < COUNT; ++i) { + String id = String.valueOf((char) i); + char[] ch = id.toCharArray(); + symbols.findSymbol(ch, 0, ch.length, symbols.calcHash(id)); + } + assertEquals(COUNT, symbols.size()); + assertEquals(1024, symbols.bucketCount()); + + assertEquals(0, symbols.collisionCount()); + assertEquals(0, symbols.maxCollisionLength()); + } + + // then byte-based + { + BytesToNameCanonicalizer symbols = + BytesToNameCanonicalizer.createRoot(1).makeChild(JsonFactory.Feature.collectDefaults()); + for (int i = 0; i < COUNT; ++i) { + String id = String.valueOf((char) i); + int[] quads = BytesToNameCanonicalizer.calcQuads(id.getBytes("UTF-8")); + symbols.addName(id, quads, quads.length); + } + assertEquals(COUNT, symbols.size()); + assertEquals(1024, symbols.bucketCount()); + + assertEquals(15, symbols.collisionCount()); + assertEquals(1, symbols.maxCollisionLength()); + } + } + + private String _shortDoc191() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + for (int i = 0; i < 400; ++i) { + if (i > 0) { + sb.append(",\n"); + } + sb.append('"'); + char c = (char) i; + if (Character.isLetterOrDigit(c)) { + sb.append((char) i); + } else { + sb.append(String.format("\\u%04x", i)); + } + sb.append("\" : "+i); + } + sb.append("}\n"); + return sb.toString(); + } }