blob: 0c0f12e676cab90e2a144c9b332825a8b4c21867 [file] [log] [blame]
/*
* Copyright (c) 2006 JetBrains s.r.o. All Rights Reserved.
*/
package com.intellij.util.io;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.containers.IntObjectCache;
import junit.framework.TestCase;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class StringEnumeratorTest extends TestCase {
private static final String COLLISION_1 = "";
private static final String COLLISION_2 = "\u0000";
private static final String UTF_1 = "\ue534";
private static final String UTF_2 =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
private PersistentStringEnumerator myEnumerator;
private File myFile;
@Override
protected void setUp() throws Exception {
super.setUp();
myFile = FileUtil.createTempFile("persistent", "trie");
myEnumerator = new PersistentStringEnumerator(myFile);
}
@Override
protected void tearDown() throws Exception {
myEnumerator.close();
IOUtil.deleteAllFilesStartingWith(myFile);
assertTrue(!myFile.exists());
super.tearDown();
}
public void testAddEqualStrings() throws IOException {
final int index = myEnumerator.enumerate("IntelliJ IDEA");
myEnumerator.enumerate("Just another string");
assertEquals(index, myEnumerator.enumerate("IntelliJ IDEA"));
}
public void testAddEqualStringsAndMuchGarbage() throws IOException {
final Set<String> stringsAded = new HashSet<String>();
final int index = myEnumerator.enumerate("IntelliJ IDEA");
stringsAded.add("IntelliJ IDEA");
// clear strings and nodes cache
for (int i = 0; i < 20000; ++i) {
final String v = Integer.toString(i) + "Just another string";
stringsAded.add(v);
final int idx = myEnumerator.enumerate(v);
assertEquals(v, myEnumerator.valueOf(idx));
}
assertEquals(index, myEnumerator.enumerate("IntelliJ IDEA"));
final Set<String> enumerated = new HashSet<String>(myEnumerator.getAllDataObjects(null));
assertEquals(stringsAded, enumerated);
}
public void testCollision() throws Exception {
int id1 = myEnumerator.enumerate(COLLISION_1);
int id2 = myEnumerator.enumerate(COLLISION_2);
assertFalse(id1 == id2);
assertEquals(COLLISION_1, myEnumerator.valueOf(id1));
assertEquals(COLLISION_2, myEnumerator.valueOf(id2));
assertEquals(new HashSet<String>(Arrays.asList(COLLISION_1, COLLISION_2)), new HashSet<String>(myEnumerator.getAllDataObjects(null)));
}
public void testCollision1() throws Exception {
int id1 = myEnumerator.enumerate(COLLISION_1);
assertEquals(id1, myEnumerator.tryEnumerate(COLLISION_1));
assertEquals(PersistentEnumerator.NULL_ID, myEnumerator.tryEnumerate(COLLISION_2));
int id2 = myEnumerator.enumerate(COLLISION_2);
assertFalse(id1 == id2);
assertEquals(id1, myEnumerator.tryEnumerate(COLLISION_1));
assertEquals(id2, myEnumerator.tryEnumerate(COLLISION_2));
assertEquals(PersistentEnumerator.NULL_ID, myEnumerator.tryEnumerate("some string"));
assertEquals(COLLISION_1, myEnumerator.valueOf(id1));
assertEquals(COLLISION_2, myEnumerator.valueOf(id2));
assertEquals(new HashSet<String>(Arrays.asList(COLLISION_1, COLLISION_2)), new HashSet<String>(myEnumerator.getAllDataObjects(null)));
}
public void testUTFString() throws Exception {
int id1 = myEnumerator.enumerate(UTF_1);
int id2 = myEnumerator.enumerate(UTF_2);
assertFalse(id1 == id2);
assertEquals(UTF_1, myEnumerator.valueOf(id1));
assertEquals(UTF_2, myEnumerator.valueOf(id2));
assertEquals(new HashSet<String>(Arrays.asList(UTF_1, UTF_2)), new HashSet<String>(myEnumerator.getAllDataObjects(null)));
}
public void testOpeningClosing() throws IOException {
ArrayList<String> strings = new ArrayList<String>(2000);
for (int i = 0; i < 2000; ++i) {
strings.add(createRandomString());
}
for (int i = 0; i < 2000; ++i) {
myEnumerator.enumerate(strings.get(i));
myEnumerator.close();
myEnumerator = new PersistentStringEnumerator(myFile);
}
for (int i = 0; i < 2000; ++i) {
myEnumerator.enumerate(strings.get(i));
assertTrue(!myEnumerator.isDirty());
myEnumerator.close();
myEnumerator = new PersistentStringEnumerator(myFile);
}
for (int i = 0; i < 2000; ++i) {
assertTrue(!myEnumerator.isDirty());
myEnumerator.close();
myEnumerator = new PersistentStringEnumerator(myFile);
}
final HashSet<String> allStringsSet = new HashSet<String>(strings);
assertEquals(allStringsSet, new HashSet<String>(myEnumerator.getAllDataObjects(null)));
final String additionalString = createRandomString();
allStringsSet.add(additionalString);
myEnumerator.enumerate(additionalString);
assertTrue(myEnumerator.isDirty());
assertEquals(allStringsSet, new HashSet<String>(myEnumerator.getAllDataObjects(null)));
}
public void testPerformance() throws IOException {
final IntObjectCache<String> stringCache = new IntObjectCache<String>(2000);
final IntObjectCache.DeletedPairsListener listener = new IntObjectCache.DeletedPairsListener() {
@Override
public void objectRemoved(final int key, final Object value) {
try {
assertEquals(myEnumerator.enumerate((String)value), key);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
};
PlatformTestUtil.startPerformanceTest("PersistentStringEnumerator performance failed", 2500, new ThrowableRunnable() {
@Override
public void run() throws Exception {
stringCache.addDeletedPairsListener(listener);
for (int i = 0; i < 100000; ++i) {
final String string = createRandomString();
stringCache.cacheObject(myEnumerator.enumerate(string), string);
}
stringCache.removeDeletedPairsListener(listener);
stringCache.removeAll();
}
}).cpuBound().assertTiming();
myEnumerator.close();
System.out.printf("File size = %d bytes\n", myFile.length());
}
private static final StringBuilder builder = new StringBuilder(100);
private static final Random random = new Random();
static String createRandomString() {
builder.setLength(0);
int len = random.nextInt(40) + 10;
for (int i = 0; i < len; ++i) {
builder.append((char)(32 + random.nextInt(2 + i >> 1)));
}
return builder.toString();
}
}