Merge remote branch 'origin/master'

This commit is contained in:
Dmitry Jemerov
2011-12-16 18:32:17 +01:00
10 changed files with 1666 additions and 122 deletions
@@ -1,122 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.cache.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.PsiBundle;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class VfsIndexer {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.cache.impl.VfsIndexer");
public static VirtualFile[] writeFileIndex(
OutputStream stream,
VirtualFile root,
VirtualFileFilter filter) throws IOException {
List<VirtualFile> result = new ArrayList<VirtualFile>();
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
if (progress != null){
progress.setText2(PsiBundle.message("psi.scanning.files.in.folder.progress", root.getPresentableUrl()));
}
DataOutputStream out = stream == null ? null : new DataOutputStream(stream);
_writeFileIndex(out, root, filter, result);
if (out != null){
out.flush();
}
return VfsUtil.toVirtualFileArray(result);
}
private static void _writeFileIndex(DataOutputStream out, VirtualFile file, VirtualFileFilter filter, List<VirtualFile> result) throws IOException {
ProgressManager.checkCanceled();
result.add(file);
if (out != null){
out.writeUTF(file.getName());
}
VirtualFile[] children = file.getChildren();
if (children == null) {
if (out != null){
out.writeInt(0);
}
return;
}
int childrenCount = 0;
for (VirtualFile child : children) {
if (filter.accept(child)) childrenCount++;
}
if (out != null){
out.writeInt(childrenCount);
}
for (VirtualFile child : children) {
if (filter.accept(child)) {
_writeFileIndex(out, child, filter, result);
}
}
}
public static VirtualFile[] readFileIndex(
InputStream stream,
VirtualFile root,
VirtualFileFilter filter
) throws IOException {
List<VirtualFile> result = new ArrayList<VirtualFile>();
DataInputStream in = new DataInputStream(stream);
String rootName = in.readUTF();
LOG.assertTrue(root.getName().equals(rootName));
_readFileIndex(in, root, filter, result);
return VfsUtil.toVirtualFileArray(result);
}
private static void _readFileIndex(DataInputStream in, VirtualFile file, VirtualFileFilter filter, List<VirtualFile> result) throws IOException {
ProgressManager.checkCanceled();
result.add(file);
int childrenCount = in.readInt();
if (childrenCount == 0) return;
for (int i = 0; i < childrenCount; i++) {
String name = in.readUTF();
VirtualFile child = file != null ? file.findChild(name) : null;
if (child != null && !filter.accept(child)){
child = null;
}
_readFileIndex(in, child, filter, result);
}
}
}
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
* Use is subject to license terms.
*/
package com.intellij.run;
import com.intellij.application.options.PathMacrosCollector;
import com.intellij.application.options.PathMacrosImpl;
import com.intellij.util.NotNullFunction;
import junit.framework.TestCase;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.Text;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
/**
* @author Eugene Zhuravlev
* Date: Nov 14, 2006
*/
public class PathMacrosCollectorTest extends TestCase {
public void testCollectMacros() {
Element root = new Element("root");
root.addContent(new Text("$MACro1$ some text $macro2$ other text $MACRo3$"));
root.addContent(new Text("$macro4$ some text"));
root.addContent(new Text("some text$macro5$"));
root.addContent(new Text("file:$mac_ro6$"));
root.addContent(new Text("jar://$macr.o7$ "));
root.addContent(new Text("$mac-ro8$ "));
root.addContent(new Text("$$$ "));
root.addContent(new Text("$c:\\a\\b\\c$ "));
root.addContent(new Text("$Revision 1.23$"));
final Set<String> macros = PathMacrosCollector.getMacroNames(root, null, null, new PathMacrosImpl());
assertEquals(5, macros.size());
assertTrue(macros.contains("MACro1"));
assertTrue(macros.contains("macro4"));
assertTrue(macros.contains("mac_ro6"));
assertTrue(macros.contains("macr.o7"));
assertTrue(macros.contains("mac-ro8"));
}
public void testWithRecursiveFilter() throws Exception {
Element root = new Element("root");
final Element configuration = new Element("configuration");
configuration.setAttribute("value", "some text$macro5$fdsjfhdskjfsd$MACRO$");
root.addContent(configuration);
final Set<String> macros = PathMacrosCollector.getMacroNames(root, null, new NotNullFunction<Object, Boolean>() {
@Override
@NotNull
public Boolean fun(Object o) {
return (o instanceof Attribute) && "value".equals(((Attribute)o).getName());
}
}, new PathMacrosImpl());
assertEquals(2, macros.size());
assertTrue(macros.contains("macro5"));
assertTrue(macros.contains("MACRO"));
}
public void testWithFilter() throws Exception {
Element root = new Element("root");
final Element testTag = new Element("test");
testTag.setAttribute("path", "$MACRO$");
testTag.setAttribute("ignore", "$PATH$");
root.addContent(testTag);
final Set<String> macros = PathMacrosCollector.getMacroNames(root, null, null, new PathMacrosImpl());
assertEquals(2, macros.size());
assertTrue(macros.contains("MACRO"));
assertTrue(macros.contains("PATH"));
final Set<String> filtered = PathMacrosCollector.getMacroNames(root, new NotNullFunction<Object, Boolean>() {
@Override
@NotNull
public Boolean fun(Object o) {
if (o instanceof Attribute && "ignore".equals(((Attribute)o).getName())) return false;
return true;
}
}, null, new PathMacrosImpl());
assertEquals(1, filtered.size());
assertTrue(macros.contains("MACRO"));
}
}
@@ -0,0 +1,102 @@
package com.intellij.structureView;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.smartTree.ActionPresentation;
import com.intellij.ide.util.treeView.smartTree.Group;
import com.intellij.ide.util.treeView.smartTree.Grouper;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class TestGrouper implements Grouper {
private final String[] mySubStrings;
public TestGrouper(String[] subString) {
mySubStrings = subString;
}
@Override
@NotNull
public ActionPresentation getPresentation() {
throw new RuntimeException();
}
@Override
@NotNull
public String getName() {
throw new RuntimeException();
}
private class StringGroup implements Group {
private final String myString;
private final Collection<TreeElement> myChildren;
private final Collection<String> myChildrenUsedStrings;
public StringGroup(String string, final Collection<TreeElement> children, Collection<String> childrenStrings) {
myString = string;
myChildrenUsedStrings = childrenStrings;
myChildren = new ArrayList<TreeElement>(children);
}
@Override
public Collection<TreeElement> getChildren() {
Collection<TreeElement> result = new LinkedHashSet<TreeElement>();
for (TreeElement object : myChildren) {
if (object.toString().indexOf(myString) >= 0) {
result.add(object);
}
}
return result;
}
@Override
public ItemPresentation getPresentation() {
return null;
}
public String toString() {
return "Group:" + myString;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Group)) return false;
final StringGroup group = (StringGroup)o;
if (myString != null ? !myString.equals(group.myString) : group.myString != null) return false;
return true;
}
public int hashCode() {
return (myString != null ? myString.hashCode() : 0);
}
}
@Override
@NotNull
public Collection<Group> group(final AbstractTreeNode parent, Collection<TreeElement> children) {
List<Group> result = new ArrayList<Group>();
Collection<String> parentGroupUsedStrings = parent.getValue() instanceof StringGroup ?
((StringGroup)parent.getValue()).myChildrenUsedStrings :
Collections.<String>emptySet();
Collection<TreeElement> elements = new LinkedHashSet<TreeElement>(children);
for (String subString : mySubStrings) {
if (parentGroupUsedStrings.contains(subString)) continue;
Set<String> childrenStrings = new THashSet<String>(parentGroupUsedStrings);
ContainerUtil.addAll(childrenStrings, mySubStrings);
StringGroup group = new StringGroup(subString, elements, childrenStrings);
Collection<TreeElement> groupChildren = group.getChildren();
if (!groupChildren.isEmpty()) {
elements.removeAll(groupChildren);
result.add(group);
}
}
return result;
}
}
@@ -0,0 +1,142 @@
package com.intellij.structureView;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.structureView.FileEditorPositionListener;
import com.intellij.ide.structureView.ModelListener;
import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.Filter;
import com.intellij.ide.util.treeView.smartTree.Grouper;
import com.intellij.ide.util.treeView.smartTree.Sorter;
import com.intellij.navigation.ItemPresentation;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class TestTreeModel implements StructureViewModel{
private final StringTreeElement myRoot;
private final List<Filter> myFilters = new ArrayList<Filter>();
private final List<Sorter> mySorters = new ArrayList<Sorter>();
public TestTreeModel(StringTreeElement root) {
myRoot = root;
}
@Override
@NotNull
public StructureViewTreeElement getRoot() {
return myRoot;
}
@Override
@NotNull
public Filter[] getFilters() {
return myFilters.toArray(new Filter[myFilters.size()]);
}
@Override
@NotNull
public Grouper[] getGroupers() {
return new Grouper[]{new TestGrouper(new String[]{"a", "b", "c"}),
new TestGrouper(new String[]{"d", "e", "f"})};
}
@Override
@NotNull
public Sorter[] getSorters() {
return mySorters.toArray(new Sorter[mySorters.size()]);
}
public void addFlter(Filter filter) {
myFilters.add(filter);
}
public void addSorter(Sorter sorter) {
mySorters.add(sorter);
}
public static class StringTreeElement implements StructureViewTreeElement {
private final Collection<StructureViewTreeElement> myChildren = new ArrayList<StructureViewTreeElement>();
private final String myValue;
public StringTreeElement(@NonNls String value) {
myValue = value;
}
@Override
public StructureViewTreeElement[] getChildren() {
return myChildren.toArray(new StructureViewTreeElement[myChildren.size()]);
}
@Override
public ItemPresentation getPresentation() {
return new PresentationData(myValue, null, null, null, null);
}
public String toString() {
return myValue;
}
public StringTreeElement addChild(@NonNls String s) {
StringTreeElement child = new StringTreeElement(s);
myChildren.add(child);
return child;
}
@Override
public String getValue() {
return myValue;
}
@Override
public void navigate(boolean requestFocus) {
}
@Override
public boolean canNavigate() {
return false;
}
@Override
public boolean canNavigateToSource() {
return false;
}
}
@Override
public Object getCurrentEditorElement() {
return null;
}
@Override
public void addEditorPositionListener(FileEditorPositionListener listener) {
}
@Override
public void removeEditorPositionListener(FileEditorPositionListener listener) {
}
@Override
public void dispose() {
}
@Override
public boolean shouldEnterElement(final Object element) {
return false;
}
@Override
public void addModelListener(ModelListener modelListener) {
}
@Override
public void removeModelListener(ModelListener modelListener) {
}
}
@@ -0,0 +1,79 @@
package com.intellij.usagesStatistics;
import com.intellij.internal.statistic.StatisticsUploadAssistant;
import com.intellij.internal.statistic.connect.StatisticsHttpClientSender;
import com.intellij.internal.statistic.connect.RemotelyConfigurableStatisticsService;
import com.intellij.internal.statistic.connect.StatisticsConnectionService;
import com.intellij.internal.statistic.connect.StatisticsResult;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.jetbrains.annotations.NonNls;
public class RemotelyConfigurableStatServiceTest extends TestCase {
@NonNls
private static final String STAT_URL = "http://localhost:8080/stat.jsp";
@NonNls
private static final String STAT_CONFIG_URL = "http://localhost:8080/config.jsp";
public void testStatisticsConnectionServiceDefaultSettings() {
final StatisticsConnectionService connectionService = new StatisticsConnectionService(STAT_CONFIG_URL, STAT_URL);
Assert.assertEquals(STAT_URL, connectionService.getServiceUrl());
Assert.assertTrue(connectionService.isTransmissionPermitted());
final String[] attributeNames = connectionService.getAttributeNames();
Assert.assertEquals(attributeNames.length, 2);
Assert.assertEquals(attributeNames[0], "url");
Assert.assertEquals(attributeNames[1], "permitted");
}
public void testEmptyDataSending() {
RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(),
new StatisticsHttpClientSender(),
new StatisticsUploadAssistant() {
@Override
public String getData() {
return "";
}
});
final StatisticsResult result = service.send();
Assert.assertEquals(StatisticsResult.ResultCode.NOTHING_TO_SEND, result.getCode());
}
public void testIncorrectUrlSending() {
RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(STAT_CONFIG_URL, STAT_URL),
new StatisticsHttpClientSender(),
new StatisticsUploadAssistant() {
@Override
public String getData() {
return "group:key1=11";
}
});
final StatisticsResult result = service.send();
Assert.assertEquals(StatisticsResult.ResultCode.SEND_WITH_ERRORS, result.getCode());
}
public void testRemotelyDisabledTransmission() {
RemotelyConfigurableStatisticsService service = new RemotelyConfigurableStatisticsService(new StatisticsConnectionService() {
@Override
public Boolean isTransmissionPermitted() {
return false;
}
}, new StatisticsHttpClientSender(),
new StatisticsUploadAssistant());
final StatisticsResult result = service.send();
Assert.assertEquals(StatisticsResult.ResultCode.NOT_PERMITTED_SERVER, result.getCode());
}
public void testErrorInRemoteConfiguration() {
RemotelyConfigurableStatisticsService service =
new RemotelyConfigurableStatisticsService(new StatisticsConnectionService(STAT_CONFIG_URL, null),
new StatisticsHttpClientSender(),
new StatisticsUploadAssistant());
final StatisticsResult result = service.send();
Assert.assertEquals(StatisticsResult.ResultCode.ERROR_IN_CONFIG, result.getCode());
}
}
@@ -0,0 +1,245 @@
package com.intellij.usagesStatistics;
import com.intellij.internal.statistic.StatisticsUploadAssistant;
import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.PatchedUsage;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.internal.statistic.persistence.BasicSentUsagesPersistenceComponent;
import com.intellij.internal.statistic.persistence.SentUsagesPersistence;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.containers.hash.LinkedHashMap;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class StatisticsUploadAssistantTest extends TestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
public void testCreateNewPatch() {
final Map<GroupDescriptor, Set<UsageDescriptor>> all = createDescriptors("g:a1:1", "g:a2:2", "g:a3:3");
final Map<GroupDescriptor, Set<UsageDescriptor>> sent = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
final Map<GroupDescriptor, Set<PatchedUsage>> patched = StatisticsUploadAssistant.getPatchedUsages(all, sent);
assertMapEquals(patched, createDescriptors("g:a1:1", "g:a2:2", "g:a3:3"));
}
public void testEmptyPatchs() {
final Map<GroupDescriptor, Set<UsageDescriptor>> all = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
final Map<GroupDescriptor, Set<UsageDescriptor>> sent = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
assertEquals(StatisticsUploadAssistant.getPatchedUsages(all, sent).size(), 0);
}
public void testCreateEmptyPatch() {
final Map<GroupDescriptor, Set<UsageDescriptor>> all = createDescriptors("g:a1:1", "g:a2:2", "g:a3:3", "g2:a1:1", "g2:a2:2", "g2:a3:3");
final Map<GroupDescriptor, Set<UsageDescriptor>> sent = createDescriptors("g:a1:1", "g:a2:2", "g:a3:3", "g2:a1:1", "g2:a2:2", "g2:a3:3");
assertEquals(StatisticsUploadAssistant.getPatchedUsages(all, sent).size(), 0);
}
public void testCreatePatchEmptyAll() {
final Map<GroupDescriptor, Set<UsageDescriptor>> all = new HashMap<GroupDescriptor, Set<UsageDescriptor>>();
final Map<GroupDescriptor, Set<UsageDescriptor>> sent = createDescriptors("g:a1:1", "g:a2:2", "g2:a1:1", "g2:a2:2", "g2:a3:3");
final Map<GroupDescriptor, Set<PatchedUsage>> patched = StatisticsUploadAssistant.getPatchedUsages(all, sent);
assertMapEquals(patched, createDescriptors("g:a1:-1", "g2:a2:-2", "g2:a3:-3", "g:a2:-2", "g2:a1:-1"));
}
public void testCreatePatchMerged() {
final Map<GroupDescriptor, Set<UsageDescriptor>> all = createDescriptors("g:a1:100", "g:a2:2", "g2:a1:0", "g2:a2:1");
final Map<GroupDescriptor, Set<UsageDescriptor>> sent = createDescriptors("g:a1:2", "g:a2:100", "g2:a1:1", "g2:a2:1", "g2:a3:3");
final Map<GroupDescriptor, Set<PatchedUsage>> patched = StatisticsUploadAssistant.getPatchedUsages(all, sent);
assertMapEquals(patched, createDescriptors("g:a1:98", "g:a2:-98", "g2:a1:-1", "g2:a3:-3"));
}
public void testPersistSentPatch() {
final Map<GroupDescriptor, Set<UsageDescriptor>> allUsages = createDescriptors("g:a1:-1", "g2:a2:-2", "g2:a3:-3", "g:a2:-2", "g2:a1:-1", "g3:a1:13");
final SentUsagesPersistence usagesPersistence = new BasicSentUsagesPersistenceComponent();
Map<GroupDescriptor, Set<PatchedUsage>> patchedUsages = StatisticsUploadAssistant.getPatchedUsages(allUsages, usagesPersistence);
String result = StatisticsUploadAssistant.getStringPatch(patchedUsages, 500);
StatisticsUploadAssistant.persistSentPatch(result, usagesPersistence);
assertMapEquals(ConvertUsagesUtil.convertString(result), ConvertUsagesUtil.convertString("g:a2=-2,a1=-1;g2:a3=-3,a2=-2,a1=-1;g3:a1=13;"));
patchedUsages = StatisticsUploadAssistant.getPatchedUsages(allUsages, usagesPersistence);
result = StatisticsUploadAssistant.getStringPatch(patchedUsages, 500);
StatisticsUploadAssistant.persistSentPatch(result, usagesPersistence);
assertEquals("sent usages must be persisted", result.length(), 0);
assertEquals(allUsages.size(), usagesPersistence.getSentUsages().size());
}
public void testConvertUsages() {
final Map<GroupDescriptor, Set<PatchedUsage>> patchedUsages = StatisticsUploadAssistant
.getPatchedUsages(createDescriptors("g:a1:-1", "g2:a2:-2", "g2:a3:-3", "g:a2:-2", "g2:a1:-1", "g3:a1:13"),
new HashMap<GroupDescriptor, Set<UsageDescriptor>>());
final String result = ConvertUsagesUtil.convertUsages(patchedUsages);
final Map<GroupDescriptor, Set<UsageDescriptor>> convertedUsages = ConvertUsagesUtil.convertString(result);
assertMapEquals(patchedUsages, convertedUsages);
}
public void testConvertUsagesWithPriority() {
final Map<GroupDescriptor, Set<PatchedUsage>> patchedUsages = new HashMap<GroupDescriptor, Set<PatchedUsage>>();
createPatchDescriptor(patchedUsages, "low", GroupDescriptor.LOWER_PRIORITY, "l1", 1);
createPatchDescriptor(patchedUsages, "low", GroupDescriptor.LOWER_PRIORITY, "l2", 1);
createPatchDescriptor(patchedUsages, "high", GroupDescriptor.HIGHER_PRIORITY, "h", 1);
createPatchDescriptor(patchedUsages, "high", GroupDescriptor.HIGHER_PRIORITY, "h2", 1);
createPatchDescriptor(patchedUsages, "default_1", GroupDescriptor.DEFAULT_PRIORITY, "d11", 1);
createPatchDescriptor(patchedUsages, "default_2", GroupDescriptor.DEFAULT_PRIORITY, "d21", 1);
createPatchDescriptor(patchedUsages, "default_1", GroupDescriptor.DEFAULT_PRIORITY, "d12", 1);
assertEquals(ConvertUsagesUtil.convertUsages(patchedUsages),
"high:h=1,h2=1;default_1:d11=1,d12=1;default_2:d21=1;low:l1=1,l2=1;");
}
public void testConvertUsagesWithEqualPriority() {
final Map<GroupDescriptor, Set<PatchedUsage>> patchedUsages = new HashMap<GroupDescriptor, Set<PatchedUsage>>();
createPatchDescriptor(patchedUsages, "g4", GroupDescriptor.HIGHER_PRIORITY, "1", 1);
createPatchDescriptor(patchedUsages, "g2", GroupDescriptor.HIGHER_PRIORITY, "2", 1);
createPatchDescriptor(patchedUsages, "g1", GroupDescriptor.HIGHER_PRIORITY, "3", 1);
createPatchDescriptor(patchedUsages, "g3", GroupDescriptor.HIGHER_PRIORITY, "4", 1);
assertEquals(ConvertUsagesUtil.convertUsages(patchedUsages), "g1:3=1;g2:2=1;g3:4=1;g4:1=1;");
}
public void testConvertString() {
final Map<GroupDescriptor, Set<PatchedUsage>> patchedUsages = new HashMap<GroupDescriptor, Set<PatchedUsage>>();
createPatchDescriptor(patchedUsages, "g4", GroupDescriptor.HIGHER_PRIORITY, "1", 1);
createPatchDescriptor(patchedUsages, "g2", GroupDescriptor.HIGHER_PRIORITY, "2", 1);
createPatchDescriptor(patchedUsages, "g1", GroupDescriptor.HIGHER_PRIORITY, "3", 1);
createPatchDescriptor(patchedUsages, "g3", GroupDescriptor.HIGHER_PRIORITY, "4", 1);
assertMapEquals(patchedUsages, ConvertUsagesUtil.convertString("g3:4=1;g1:3=1;g4:1=1;g2:2=1;"));
}
public void testConvertEmptyString() {
assertEquals(ConvertUsagesUtil.convertString("").size(), 0);
}
public void testConvertBrokenString() {
assertEquals(ConvertUsagesUtil.convertString("asdfasdfsad").size(), 0);
assertEquals(ConvertUsagesUtil.convertString("asdf:asdfsad").size(), 0);
assertEquals(ConvertUsagesUtil.convertString("asdfa:sd;fsad").size(), 0);
assertEquals(ConvertUsagesUtil.convertString("asdfa:sd;fs,ad").size(), 0);
assertEquals(ConvertUsagesUtil.convertString("asdfa:sd;f;sad").size(), 0);
assertEquals(ConvertUsagesUtil.convertString("asdfa:sd=ds2,f=f,sad=;").size(), 0);
}
public void testPersistSentPatchWithRestrictedSize() {
int size = 15;
final Map<GroupDescriptor, Set<UsageDescriptor>> allUsages = createDescriptors("g:a1:-1", "g2:a2:-2", "g2:a3:-3", "g:a2:-2", "g3:a1:-1", "g3:a2:13");
final SentUsagesPersistence usagesPersistence = new BasicSentUsagesPersistenceComponent();
Map<GroupDescriptor, Set<PatchedUsage>> patchedUsages = StatisticsUploadAssistant.getPatchedUsages(allUsages, usagesPersistence);
String first = StatisticsUploadAssistant.getStringPatch(patchedUsages, size);
StatisticsUploadAssistant.persistSentPatch(first, usagesPersistence);
assertTrue(first.length() <= size);
assertMapEquals(ConvertUsagesUtil.convertString(first), ConvertUsagesUtil.convertString("g:a1=-1,a2=-2"));
patchedUsages = StatisticsUploadAssistant.getPatchedUsages(allUsages, usagesPersistence);
String second = StatisticsUploadAssistant.getStringPatch(patchedUsages, size);
StatisticsUploadAssistant.persistSentPatch(second, usagesPersistence);
assertTrue(second.length() <= size);
assertFalse(second.contains(first));
assertMapEquals(ConvertUsagesUtil.convertString(second), ConvertUsagesUtil.convertString("g2:a2=-2,a3=-3"));
patchedUsages = StatisticsUploadAssistant.getPatchedUsages(allUsages, usagesPersistence);
String third = StatisticsUploadAssistant.getStringPatch(patchedUsages, size);
StatisticsUploadAssistant.persistSentPatch(third, usagesPersistence);
assertTrue(third.length() <= size);
assertFalse(third.contains(first));
assertFalse(third.contains(second));
assertMapEquals(ConvertUsagesUtil.convertString(third), ConvertUsagesUtil.convertString("g3:a1=-1,a2=13"));
patchedUsages = StatisticsUploadAssistant.getPatchedUsages(allUsages, usagesPersistence);
assertEquals(patchedUsages.size(), 0);
assertEquals(allUsages.size(), usagesPersistence.getSentUsages().size());
}
private static <T extends UsageDescriptor> void assertMapEquals(@NotNull Map<GroupDescriptor, Set<T>> expected, @NotNull Map<GroupDescriptor, Set<UsageDescriptor>> actual) {
assertEquals(expected.size(), actual.size());
for (Map.Entry<GroupDescriptor, Set<T>> expectedEntry : expected.entrySet()) {
final GroupDescriptor expectedGroupDescriptor = expectedEntry.getKey();
assertTrue(actual.containsKey(expectedGroupDescriptor));
assertSetEquals(expectedEntry.getValue(), actual.get(expectedEntry.getKey()));
}
}
private static void assertSetEquals(@NotNull Set<? extends UsageDescriptor> expected, @NotNull Set<? extends UsageDescriptor> actual) {
assertEquals(expected.size(), actual.size());
for (UsageDescriptor usageDescriptor : expected) {
boolean exists = false;
for (UsageDescriptor descriptor : actual) {
if (usageDescriptor.getKey().equals(descriptor.getKey()) && usageDescriptor.getValue() == descriptor.getValue()) {
exists = true;
break;
}
}
assertTrue(asString(usageDescriptor) + " usage doesn't exist", exists);
}
}
private static String asString(UsageDescriptor usage) {
return usage.getKey() + "=" + usage.getValue();
}
private static void createPatchDescriptor(Map<GroupDescriptor, Set<PatchedUsage>> patchedUsages, String groupId, double priority, String key, int i) {
final GroupDescriptor groupDescriptor = GroupDescriptor.create(groupId, priority);
if (!patchedUsages.containsKey(groupDescriptor)){
patchedUsages.put(groupDescriptor, new LinkedHashSet<PatchedUsage>());
}
patchedUsages.get(groupDescriptor).add(new PatchedUsage(key, i));
}
protected static UsageDescriptor createDescriptor(String k, int i) {
return new UsageDescriptor(k, i);
}
protected static Map<GroupDescriptor, Set<UsageDescriptor>> createDescriptors(String... strs) {
Map<GroupDescriptor, Set<UsageDescriptor>> set = new LinkedHashMap<GroupDescriptor, Set<UsageDescriptor>>();
for (String str : strs) {
final List<String> list = StringUtil.split(str, ":");
final GroupDescriptor g = GroupDescriptor.create(list.get(0));
if (!set.containsKey(g)) {
set.put(g, new LinkedHashSet<UsageDescriptor>());
}
set.get(g).add(createDescriptor(list.get(1), Integer.parseInt(list.get(2))));
}
return set;
}
}
@@ -0,0 +1,192 @@
/*
* 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 gnu.trove.THashMap;
import junit.framework.TestCase;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class BTreeEnumeratorTest 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";
static class TestStringEnumerator extends PersistentBTreeEnumerator<String> {
public TestStringEnumerator(File file) throws IOException {
super(file, new EnumeratorStringDescriptor(), 4096);
}
}
private TestStringEnumerator myEnumerator;
private File myFile;
@Override
protected void setUp() throws Exception {
super.setUp();
myFile = FileUtil.createTempFile("persistent", "trie");
myEnumerator = new TestStringEnumerator(myFile);
}
@Override
protected void tearDown() throws Exception {
myEnumerator.close();
FileUtil.delete(myFile);
FileUtil.delete(new File(myFile.getParentFile(), myFile.getName() + ".len"));
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 Map<Integer,String> strings = new THashMap<Integer, String>(10001);
String s = "IntelliJ IDEA";
final int index = myEnumerator.enumerate(s);
strings.put(index, s);
// clear strings and nodes cache
for (int i = 0; i < 10000; ++i) {
final String v = Integer.toString(i) + "Just another string";
final int idx = myEnumerator.enumerate(v);
assertEquals(v, myEnumerator.valueOf(idx));
strings.put(idx, v);
}
for(Map.Entry<Integer, String> e:strings.entrySet()) {
assertEquals((int)e.getKey(), myEnumerator.enumerate(e.getValue()));
}
final Set<String> enumerated = new HashSet<String>(myEnumerator.getAllDataObjects(null));
assertEquals(new HashSet<String>(strings.values()), 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 TestStringEnumerator(myFile);
}
for (int i = 0; i < 2000; ++i) {
myEnumerator.enumerate(strings.get(i));
assertTrue(!myEnumerator.isDirty());
myEnumerator.close();
myEnumerator = new TestStringEnumerator(myFile);
}
for (int i = 0; i < 2000; ++i) {
assertTrue(!myEnumerator.isDirty());
myEnumerator.close();
myEnumerator = new TestStringEnumerator(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();
}
}).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(13101977);
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();
}
}
@@ -0,0 +1,342 @@
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 com.intellij.util.io.storage.Storage;
import junit.framework.TestCase;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.*;
/**
* @author Eugene Zhuravlev
* Date: Dec 19, 2007
*/
public class PersistentMapTest extends TestCase {
private PersistentHashMap<String, String> myMap;
private File myFile;
private File myDataFile;
@Override
protected void setUp() throws Exception {
super.setUp();
myFile = FileUtil.createTempFile("persistent", "map");
myDataFile = new File(myFile.getParentFile(), myFile.getName() + PersistentHashMap.DATA_FILE_EXTENSION);
myMap = new PersistentHashMap<String, String>(myFile, new EnumeratorStringDescriptor(), new EnumeratorStringDescriptor());
}
@Override
protected void tearDown() throws Exception {
clearMap(myFile, myMap);
super.tearDown();
}
private static void clearMap(final File file1, PersistentHashMap<?, ?> map) throws IOException {
map.close();
final File[] files = file1.getParentFile().listFiles(new FileFilter() {
@Override
public boolean accept(final File pathname) {
return pathname.getName().startsWith(file1.getName());
}
});
if (files != null) {
for (File file : files) {
FileUtil.delete(file);
assertTrue(!file.exists());
}
}
}
public void testMap() throws IOException {
myMap.put("AAA", "AAA_VALUE");
assertEquals("AAA_VALUE", myMap.get("AAA"));
assertNull(myMap.get("BBB"));
assertEquals(new HashSet<String>(Arrays.asList("AAA")), new HashSet<String>(myMap.getAllKeysWithExistingMapping()));
myMap.put("BBB", "BBB_VALUE");
assertEquals("BBB_VALUE", myMap.get("BBB"));
assertEquals(new HashSet<String>(Arrays.asList("AAA", "BBB")), new HashSet<String>(myMap.getAllKeysWithExistingMapping()));
myMap.put("AAA", "ANOTHER_AAA_VALUE");
assertEquals("ANOTHER_AAA_VALUE", myMap.get("AAA"));
assertEquals(new HashSet<String>(Arrays.asList("AAA", "BBB")), new HashSet<String>(myMap.getAllKeysWithExistingMapping()));
myMap.remove("AAA");
assertNull(myMap.get("AAA"));
assertEquals("BBB_VALUE", myMap.get("BBB"));
assertEquals(new HashSet<String>(Arrays.asList("BBB")), new HashSet<String>(myMap.getAllKeysWithExistingMapping()));
myMap.remove("BBB");
assertNull(myMap.get("AAA"));
assertNull(myMap.get("BBB"));
assertEquals(new HashSet<String>(), new HashSet<String>(myMap.getAllKeysWithExistingMapping()));
myMap.put("AAA", "FINAL_AAA_VALUE");
assertEquals("FINAL_AAA_VALUE", myMap.get("AAA"));
assertNull(myMap.get("BBB"));
assertEquals(new HashSet<String>(Arrays.asList("AAA")), new HashSet<String>(myMap.getAllKeysWithExistingMapping()));
}
public void testOpeningClosing() throws IOException {
List<String> strings = new ArrayList<String>(2000);
for (int i = 0; i < 2000; ++i) {
strings.add(createRandomString());
}
for (int i = 0; i < 2000; ++i) {
final String key = strings.get(i);
myMap.put(key, key + "_value");
myMap.close();
myMap = new PersistentHashMap<String, String>(myFile, new EnumeratorStringDescriptor(), new EnumeratorStringDescriptor());
}
for (int i = 0; i < 2000; ++i) {
final String key = strings.get(i);
final String value = key + "_value";
assertEquals(value, myMap.get(key));
myMap.put(key, value);
assertTrue(myMap.isDirty());
myMap.close();
myMap = new PersistentHashMap<String, String>(myFile, new EnumeratorStringDescriptor(), new EnumeratorStringDescriptor());
}
for (int i = 0; i < 2000; ++i) {
assertTrue(!myMap.isDirty());
myMap.close();
myMap = new PersistentHashMap<String, String>(myFile, new EnumeratorStringDescriptor(), new EnumeratorStringDescriptor());
}
final String randomKey = createRandomString();
myMap.put(randomKey, randomKey + "_value");
assertTrue(myMap.isDirty());
}
public void testOpeningWithCompact() throws IOException {
final int stringsCount = 5/*1000000*/;
Set<String> strings = new HashSet<String>(stringsCount);
for (int i = 0; i < stringsCount; ++i) {
final String key = createRandomString();
strings.add(key);
myMap.put(key, key + "_value");
}
myMap.close();
myMap = new PersistentHashMap<String, String>(myFile, new EnumeratorStringDescriptor(), new EnumeratorStringDescriptor());
{ // before compact
final Collection<String> allKeys = new HashSet<String>(myMap.getAllKeysWithExistingMapping());
assertEquals(strings, allKeys);
for (String key : allKeys) {
final String val = myMap.get(key);
assertEquals(key + "_value", val);
}
}
myMap.compact();
{ // after compact
final Collection<String> allKeys = new HashSet<String>(myMap.getAllKeysWithExistingMapping());
assertEquals(strings, allKeys);
for (String key : allKeys) {
final String val = myMap.get(key);
assertEquals(key + "_value", val);
}
}
}
public void testGarbageSizeUpdatedAfterCompact() throws IOException {
final int stringsCount = 5/*1000000*/;
Set<String> strings = new HashSet<String>(stringsCount);
for (int i = 0; i < stringsCount; ++i) {
final String key = createRandomString();
strings.add(key);
myMap.put(key, key + "_value");
}
// create some garbage
for (String string : strings) {
myMap.remove(string);
}
strings.clear();
for (int i = 0; i < stringsCount; ++i) {
final String key = createRandomString();
strings.add(key);
myMap.put(key, key + "_value");
}
myMap.close();
final int garbageSizeOnClose = myMap.getGarbageSize();
myMap = new PersistentHashMap<String, String>(myFile, new EnumeratorStringDescriptor(), new EnumeratorStringDescriptor());
final int garbageSizeOnOpen = myMap.getGarbageSize();
assertEquals(garbageSizeOnClose, garbageSizeOnOpen);
{ // before compact
final Collection<String> allKeys = new HashSet<String>(myMap.getAllKeysWithExistingMapping());
assertEquals(strings, allKeys);
for (String key : allKeys) {
final String val = myMap.get(key);
assertEquals(key + "_value", val);
}
}
myMap.compact();
assertEquals(0, myMap.getGarbageSize());
myMap.close();
myMap = new PersistentHashMap<String, String>(myFile, new EnumeratorStringDescriptor(), new EnumeratorStringDescriptor());
final int garbageSizeAfterCompact = myMap.getGarbageSize();
assertEquals(0, garbageSizeAfterCompact);
{ // after compact
final Collection<String> allKeys = new HashSet<String>(myMap.getAllKeysWithExistingMapping());
assertEquals(strings, allKeys);
for (String key : allKeys) {
final String val = myMap.get(key);
assertEquals(key + "_value", val);
}
}
}
public void testOpeningWithCompact2() throws IOException {
File file = FileUtil.createTempFile("persistent", "map");
PersistentHashMap<Integer, String> map = new PersistentHashMap<Integer, String>(file, new IntInlineKeyDescriptor(), new EnumeratorStringDescriptor());
try {
final int stringsCount = 5/*1000000*/;
Map<Integer, String> testMapping = new LinkedHashMap<Integer, String>(stringsCount);
for (int i = 0; i < stringsCount; ++i) {
final String key = createRandomString();
String value = key + "_value";
testMapping.put(i, value);
map.put(i, value);
}
map.close();
map = new PersistentHashMap<Integer, String>(file, new IntInlineKeyDescriptor(), new EnumeratorStringDescriptor());
{ // before compact
final Collection<Integer> allKeys = new HashSet<Integer>(map.getAllKeysWithExistingMapping());
assertEquals(new HashSet<Integer>(testMapping.keySet()), allKeys);
for (Integer key : allKeys) {
final String val = map.get(key);
assertEquals(testMapping.get(key), val);
}
}
map.compact();
{ // after compact
final Collection<Integer> allKeys = new HashSet<Integer>(map.getAllKeysWithExistingMapping());
assertEquals(new HashSet<Integer>(testMapping.keySet()), allKeys);
for (Integer key : allKeys) {
final String val = map.get(key);
assertEquals(testMapping.get(key), val);
}
}
}
finally {
clearMap(file, map);
}
}
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 mapKey) {
try {
final String _mapKey = (String)mapKey;
assertEquals(myMap.enumerate(_mapKey), key);
final String expectedMapValue = _mapKey == null ? null : _mapKey + "_value";
final String actual = myMap.get(_mapKey);
assertEquals(expectedMapValue, actual);
myMap.remove(_mapKey);
assertNull(myMap.get(_mapKey));
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
};
PlatformTestUtil.startPerformanceTest("Perforamnce", 9000, new ThrowableRunnable() {
@Override
public void run() throws Exception {
try {
stringCache.addDeletedPairsListener(listener);
for (int i = 0; i < 100000; ++i) {
final String string = createRandomString();
final int id = myMap.enumerate(string);
stringCache.put(id, string);
myMap.put(string, string + "_value");
}
stringCache.removeDeletedPairsListener(listener);
for (String key : stringCache) {
myMap.remove(key);
}
stringCache.removeAll();
myMap.compact();
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
}).ioBound().assertTiming();
myMap.close();
System.out.printf("File size = %d bytes\n", myFile.length());
System.out
.printf("Data file size = %d bytes\n", new File(myDataFile.getParentFile(), myDataFile.getName() + Storage.DATA_EXTENSION).length());
}
public void testPerformance1() throws IOException {
final List<String> strings = new ArrayList<String>(2000);
for (int i = 0; i < 100000; ++i) {
strings.add(createRandomString());
}
PlatformTestUtil.startPerformanceTest("perf1",5000, new ThrowableRunnable() {
@Override
public void run() throws Exception {
for (int i = 0; i < 100000; ++i) {
final String string = strings.get(i);
myMap.put(string, string);
}
for (int i = 0; i < 100000; ++i) {
final String string = createRandomString();
myMap.get(string);
}
for (int i = 0; i < 100000; ++i) {
final String string = createRandomString();
myMap.remove(string);
}
for (String string : strings) {
myMap.remove(string);
}
}
}).assertTiming();
myMap.close();
System.out.printf("File size = %d bytes\n", myFile.length());
System.out
.printf("Data file size = %d bytes\n", new File(myDataFile.getParentFile(), myDataFile.getName() + Storage.DATA_EXTENSION).length());
}
private static String createRandomString() {
return StringEnumeratorTest.createRandomString();
}
}
@@ -0,0 +1,181 @@
/*
* 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();
FileUtil.delete(myFile);
FileUtil.delete(new File(myFile.getParentFile(), myFile.getName() + ".len"));
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();
}
}
@@ -0,0 +1,295 @@
/*
* Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
* Use is subject to license terms.
*/
package com.intellij.util.ui.update;
import com.intellij.testFramework.FlyIdeaTestCase;
import com.intellij.util.WaitFor;
public class MergingUpdateQueueTest extends FlyIdeaTestCase {
public void testOnShowNotify() throws Exception {
final MyUpdate first = new MyUpdate("first");
final MyUpdate second = new MyUpdate("second");
final MyQueue queue = new MyQueue();
queue.queue(first);
queue.queue(second);
assertFalse(first.isExecuted());
assertFalse(second.isExecuted());
queue.showNotify();
waitForExecution(queue);
assertAfterProcessing(first, true, true);
assertAfterProcessing(second, true, true);
}
public void testPriority() throws Exception {
final boolean attemps[] = new boolean[3];
final MyQueue queue = new MyQueue();
final MyUpdate first = new MyUpdate("addedFirstButRunLast") { // default priority is 999
@Override
public void run() {
super.run();
attemps[0] = true;
assertTrue(attemps[1]);
assertTrue(attemps[2]);
}
};
final MyUpdate second = new MyUpdate("addedSecondButRunFirst", Update.HIGH_PRIORITY) {
@Override
public void run() {
super.run();
assertFalse(attemps[0]);
attemps[1] = true;
assertFalse(attemps[2]);
}
};
final MyUpdate third = new MyUpdate("addedThirdButRunSecond", 100) {
@Override
public void run() {
super.run();
assertFalse(attemps[0]);
assertTrue(attemps[1]);
attemps[2] = true;
}
};
queue.queue(first);
queue.queue(second);
queue.queue(third);
waitForExecution(queue);
assertAfterProcessing(first, true, true);
assertAfterProcessing(second, true, true);
assertAfterProcessing(third, true, true);
}
public void testDoNoExecuteExpired() throws Throwable {
final boolean[] expired = new boolean[1];
final MyUpdate first = new MyUpdate("first") {
@Override
public boolean isExpired() {
return expired[0];
}
};
final MyUpdate second = new MyUpdate("second");
final MyQueue queue = new MyQueue();
queue.queue(first);
queue.queue(second);
assertFalse(first.isExecuted());
assertFalse(second.isExecuted());
expired[0] = true;
queue.showNotify();
waitForExecution(queue);
assertAfterProcessing(first, false, true);
assertAfterProcessing(second, true, true);
}
public void testOnShowNotifyMerging() throws Exception {
final MyUpdate twin1 = new MyUpdate("twin");
final MyUpdate twin2 = new MyUpdate("twin");
final MyQueue queue = new MyQueue();
queue.queue(twin1);
queue.queue(twin2);
assertFalse(twin1.isExecuted());
assertFalse(twin2.isExecuted());
queue.showNotify();
waitForExecution(queue);
assertAfterProcessing(twin1, false, true);
assertAfterProcessing(twin2, true, true);
}
public void testExecuteWhenActive() throws Exception {
final MyQueue queue = new MyQueue();
queue.showNotify();
final MyUpdate first = new MyUpdate("first");
final MyUpdate second = new MyUpdate("second");
queue.queue(first);
queue.queue(second);
waitForExecution(queue);
assertAfterProcessing(first, true, true);
assertAfterProcessing(second, true, true);
}
public void testMergeWhenActive() throws Exception {
final MyQueue queue = new MyQueue();
queue.showNotify();
final MyUpdate twin1 = new MyUpdate("twin");
final MyUpdate twin2 = new MyUpdate("twin");
queue.queue(twin1);
queue.queue(twin2);
waitForExecution(queue);
assertAfterProcessing(twin1, false, true);
assertAfterProcessing(twin2, true, true);
}
public void testEatByQueue() throws Exception {
executeEatingTest(false);
}
public void testEatUpdatesInQueue() throws Exception {
executeEatingTest(true);
}
private void executeEatingTest(boolean foodFirst) throws Exception{
final MyQueue queue = new MyQueue();
queue.showNotify();
final MyUpdate food = new MyUpdate("food");
MyUpdate hungry = new MyUpdate("hungry") {
@Override
public boolean canEat(Update update) {
return update == food;
}
};
if (foodFirst) {
queue.queue(food);
queue.queue(hungry);
} else {
queue.queue(hungry);
queue.queue(food);
}
waitForExecution(queue);
assertAfterProcessing(hungry, true, true);
assertAfterProcessing(food, false, false);
}
public void testCuncurrentFlushing() throws Exception {
final MyQueue queue = new MyQueue();
queue.showNotify();
queue.queue(new MyUpdate("update") {
@Override
public boolean isExpired() {
queue.flush();
return false;
}
});
waitForExecution(queue);
}
public void testConcurrentQueing() throws Exception {
final MyQueue queue = new MyQueue();
queue.showNotify();
queue.queue(new MyUpdate("update") {
@Override
public boolean isExpired() {
queue.queue(new MyUpdate("update again"));
return false;
}
});
waitForExecution(queue);
}
private void assertAfterProcessing(MyUpdate update, boolean shouldBeExecuted, boolean shouldBeProcessed) {
assertEquals(shouldBeExecuted, update.isExecuted());
assertEquals(shouldBeProcessed, update.wasProcessed());
}
private static class MyUpdate extends Update {
private boolean myExecuted;
MyUpdate(String s) {
super(s);
}
MyUpdate(Object identity, int priority) {
super(identity, priority);
}
@Override
public void run() {
myExecuted = true;
}
public boolean isExecuted() {
return myExecuted;
}
}
private static class MyQueue extends MergingUpdateQueue {
private boolean myExecuted;
MyQueue() {
super("Test", 400, false, null);
setPassThrough(false);
}
@Override
public void run() {
}
public void onTimer() {
super.run();
}
@Override
protected void execute(final Update[] update) {
super.execute(update);
myExecuted = true;
}
public boolean wasExecuted() {
return myExecuted;
}
@Override
protected boolean isModalityStateCorrect() {
return true;
}
}
private void waitForExecution(final MyQueue queue) {
queue.onTimer();
new WaitFor(5000) {
@Override
protected boolean condition() {
return queue.wasExecuted();
}
};
}
}