blob: 07c07ffdb05a1d91e51f1756544fa0f696023ba1 [file] [log] [blame]
/*
* Copyright 2000-2013 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.
*/
/*
* User: anna
* Date: 28-Jun-2007
*/
package com.intellij.internal;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
import com.intellij.util.Function;
import gnu.trove.TObjectIntHashMap;
import gnu.trove.TObjectIntProcedure;
import java.util.*;
public class ComputeVirtualFileNameStatAction extends AnAction implements DumbAware {
public ComputeVirtualFileNameStatAction() {
super("Compute VF name statistics");
}
public static void main(String[] args) {
new ComputeVirtualFileNameStatAction().actionPerformed(null);
}
@Override
public void actionPerformed(AnActionEvent e) {
long start = System.currentTimeMillis();
suffixes.clear();
nameCount.clear();
VirtualFile[] roots = ManagingFS.getInstance().getRoots(LocalFileSystem.getInstance());
for (VirtualFile root : roots) {
compute(root);
}
final List<Pair<String,Integer>> names = new ArrayList<Pair<String, Integer>>(nameCount.size());
nameCount.forEachEntry(new TObjectIntProcedure<String>() {
@Override
public boolean execute(String name, int count) {
names.add(Pair.create(name, count));
return true;
}
});
Collections.sort(names, new Comparator<Pair<String, Integer>>() {
@Override
public int compare(Pair<String, Integer> o1, Pair<String, Integer> o2) {
return o2.second - o1.second;
}
});
System.out.println("Most frequent names ("+names.size()+" total):");
int saveByIntern = 0;
for (Pair<String, Integer> pair : names) {
int count = pair.second;
String name = pair.first;
System.out.println(name + " -> " + count);
saveByIntern += count * name.length();
if (count == 1) break;
}
System.out.println("Total save if names were interned: "+saveByIntern+"; ------------");
//System.out.println("Prefixes: ("+prefixes.size()+" total)");
//show(prefixes);
System.out.println("Suffix counts:("+suffixes.size()+" total)");
show(suffixes);
final TObjectIntHashMap<String> save = new TObjectIntHashMap<String>();
// compute economy
suffixes.forEachEntry(new TObjectIntProcedure<String>() {
@Override
public boolean execute(String s, int count) {
save.put(s, count * s.length());
return true;
}
});
System.out.println("Supposed save by stripping suffixes: ("+save.size()+" total)");
final List<Pair<String, Integer>> saveSorted = show(save);
final List<String> picked = new ArrayList<String>();
//List<String> candidates = new ArrayList<String>();
//int i =0;
//for (Pair<String, Integer> pair : sorted) {
// if (i++>1000) break;
// candidates.add(pair.first);
//}
//final TObjectIntHashMap<String> counts = new TObjectIntHashMap<String>();
//suffixes.forEachEntry(new TObjectIntProcedure<String>() {
// @Override
// public boolean execute(String a, int b) {
// counts.put(a, b);
// return true;
// }
//});
while (picked.size() != 15) {
Pair<String, Integer> cp = saveSorted.get(0);
final String candidate = cp.first;
picked.add(candidate);
System.out.println("Candidate: '"+candidate+"', save = "+cp.second);
Collections.sort(picked, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.length() - o1.length(); // longer first
}
});
saveSorted.clear();
// adjust
suffixes.forEachEntry(new TObjectIntProcedure<String>() {
@Override
public boolean execute(String s, int count) {
for (int i = picked.size() - 1; i >= 0; i--) {
String pick = picked.get(i);
if (pick.endsWith(s)) {
count -= suffixes.get(pick);
break;
}
}
saveSorted.add(Pair.create(s, s.length() * count));
return true;
}
});
Collections.sort(saveSorted, new Comparator<Pair<String, Integer>>() {
@Override
public int compare(Pair<String, Integer> o1, Pair<String, Integer> o2) {
return o2.second.compareTo(o1.second);
}
});
}
System.out.println("Picked: "+ StringUtil.join(picked, new Function<String, String>() {
@Override
public String fun(String s) {
return "\""+s+"\"";
}
}, ","));
Collections.sort(picked, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.length() - o1.length(); // longer first
}
});
int saved = 0;
for (int i = 0; i < picked.size(); i++) {
String s = picked.get(i);
int count = suffixes.get(s);
for (int k=0; k<i;k++) {
String prev = picked.get(k);
if (prev.endsWith(s)) {
count -= suffixes.get(prev);
break;
}
}
saved += count * s.length();
}
System.out.println("total saved = " + saved);
System.out.println("Time spent: " + (System.currentTimeMillis() - start));
}
private static List<Pair<String,Integer>> show(final TObjectIntHashMap<String> prefixes) {
final List<Pair<String,Integer>> prefs = new ArrayList<Pair<String, Integer>>(prefixes.size());
prefixes.forEachEntry(new TObjectIntProcedure<String>() {
@Override
public boolean execute(String s, int count) {
prefs.add(Pair.create(s, count));
return true;
}
});
Collections.sort(prefs, new Comparator<Pair<String, Integer>>() {
@Override
public int compare(Pair<String, Integer> o1, Pair<String, Integer> o2) {
return o2.second.compareTo(o1.second);
}
});
int i =0;
for (Pair<String, Integer> pref : prefs) {
Integer count = pref.second;
System.out.printf("%60.60s : %d\n", pref.first, count);
if (/*count<500 || */i++ > 100) {
System.out.println("\n.......<" + count + "...\n");
break;
}
}
return prefs;
}
//TObjectIntHashMap<String> prefixes = new TObjectIntHashMap<String>();
TObjectIntHashMap<String> suffixes = new TObjectIntHashMap<String>();
TObjectIntHashMap<String> nameCount = new TObjectIntHashMap<String>();
private void compute(VirtualFile root) {
String name = root.getName();
if (!nameCount.increment(name)) nameCount.put(name, 1);
for (int i=1; i<=name.length(); i++) {
//String prefix = name.substring(0, i);
//if (!prefixes.increment(prefix)) prefixes.put(prefix, 1);
String suffix = name.substring(name.length()-i);
if (!suffixes.increment(suffix)) suffixes.put(suffix, 1);
}
Collection<VirtualFile> cachedChildren = ((VirtualFileSystemEntry)root).getCachedChildren();
//VirtualFile[] cachedChildren = ((VirtualFileSystemEntry)root).getChildren();
for (VirtualFile cachedChild : cachedChildren) {
compute(cachedChild);
}
}
}