/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.test.unit; import java.util.Random; import org.h2.test.TestBase; import org.h2.util.StringUtils; /** * Tests the string cache facility. */ public class TestStringCache extends TestBase { /** * Flag to indicate the test should stop. */ volatile boolean stop; private Random random = new Random(1); private String[] some = { null, "", "ABC", "this is a medium sized string", "1", "2" }; private boolean returnNew; private boolean useIntern; /** * This method is called when executing this application from the command * line. * * @param args the command line parameters */ public static void main(String... args) { new TestStringCache().runBenchmark(); } public void test() throws InterruptedException { returnNew = true; StringUtils.clearCache(); testSingleThread(getSize(5000, 20000)); testMultiThreads(); returnNew = false; StringUtils.clearCache(); testSingleThread(getSize(5000, 20000)); testMultiThreads(); } private void runBenchmark() { returnNew = false; for (int i = 0; i < 6; i++) { useIntern = (i % 2) == 0; long time = System.currentTimeMillis(); testSingleThread(100000); time = System.currentTimeMillis() - time; System.out.println(time + " ms (useIntern=" + useIntern + ")"); } } private String randomString() { if (random.nextBoolean()) { String s = some[random.nextInt(some.length)]; if (s != null && random.nextBoolean()) { s = new String(s); } return s; } int len = random.nextBoolean() ? random.nextInt(1000) : random.nextInt(10); StringBuilder buff = new StringBuilder(len); for (int i = 0; i < len; i++) { buff.append(random.nextInt(0xfff)); } return buff.toString(); } /** * Test one string operation using the string cache. */ void testString() { String a = randomString(); if (returnNew) { String b = StringUtils.fromCacheOrNew(a); try { assertEquals(a, b); } catch (Exception e) { TestBase.logError("error", e); } if (a != null && a == b && a.length() > 0) { throw new AssertionError("a=" + System.identityHashCode(a) + " b=" + System.identityHashCode(b)); } } else { String b; if (useIntern) { b = a == null ? null : a.intern(); } else { b = StringUtils.cache(a); } try { assertEquals(a, b); } catch (Exception e) { TestBase.logError("error", e); } } } private void testSingleThread(int len) { for (int i = 0; i < len; i++) { testString(); } } private void testMultiThreads() throws InterruptedException { int threadCount = getSize(3, 100); Thread[] threads = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { Thread t = new Thread(new Runnable() { public void run() { while (!stop) { testString(); } } }); threads[i] = t; } for (int i = 0; i < threadCount; i++) { threads[i].start(); } int wait = getSize(200, 2000); Thread.sleep(wait); stop = true; for (int i = 0; i < threadCount; i++) { threads[i].join(); } } }