blob: a6eac5d9ffa56f9ff790b08e8694f95d593ad2e4 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* 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.google.gwt.soyc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* Compile Report information about a compiled module.
*/
public class GlobalInformation {
private static final SizeBreakdown[] EMPTY_SIZE_BREAKDOWN = new SizeBreakdown[0];
public Map<String, Map<String, String>> dependencies = null;
private Map<String, String> classToPackage = new TreeMap<String, String>();
private HashMap<String, HashSet<String>> classToWhatItDependsOn = new HashMap<String, HashSet<String>>();
private Map<Integer, SizeBreakdown> exclusiveCodeBreakdowns = new HashMap<Integer, SizeBreakdown>();
private SizeBreakdown initialCodeBreakdown = new SizeBreakdown(
"Initially downloaded code", "initial");
private SizeBreakdown leftoversBreakdown = new SizeBreakdown(
"Leftovers code, code not in any other fragment", "leftovers");
private Map<String, TreeSet<String>> packageToClasses = new TreeMap<String, TreeSet<String>>();
private final String permutationId;
private ArrayList<Integer> initialFragmentLoadSequence = new ArrayList<Integer>();
private HashMap<Integer, List<String>> fragmentDescriptors =
new HashMap<Integer, List<String>>();
private SizeBreakdown totalCodeBreakdown = new SizeBreakdown("Total program",
"total");
public GlobalInformation(String permutationId) {
this.permutationId = permutationId;
}
public SizeBreakdown[] allSizeBreakdowns() {
List<SizeBreakdown> breakdowns = new ArrayList<SizeBreakdown>();
breakdowns.add(totalCodeBreakdown);
breakdowns.add(initialCodeBreakdown);
if (getNumFragments() > 0) {
breakdowns.add(leftoversBreakdown);
for (int fragment = 1; fragment <= getNumFragments(); fragment++) {
breakdowns.add(fragmentCodeBreakdown(fragment));
}
}
return breakdowns.toArray(EMPTY_SIZE_BREAKDOWN);
}
/**
* Computes all package sizes.
*/
public void computePackageSizes() {
for (SizeBreakdown breakdown : allSizeBreakdowns()) {
computePackageSizes(breakdown.packageToSize, breakdown.classToSize);
}
}
/**
* Gets the mapping from each class to its package.
*
* @return classToPackage
*/
public final Map<String, String> getClassToPackage() {
return classToPackage;
}
/**
* Gets the mapping from a class to what it depends on.
*
* @return classToWhatItDependsOn
*/
public final HashMap<String, HashSet<String>> getClassToWhatItDependsOn() {
return classToWhatItDependsOn;
}
/**
* Gets the exclusive code breakdown.
*
* @return exclusiveCodeBreakdown
*/
public final Map<Integer, SizeBreakdown> getExclusiveCodeBreakdowns() {
return exclusiveCodeBreakdowns;
}
/**
* Gets the initial fragment size breakdown.
*
* @return initialCodeBreakdown
*/
public final SizeBreakdown getInitialCodeBreakdown() {
return initialCodeBreakdown;
}
/**
* Gets the leftovers fragment size breakdown.
*
* @return leftoversCodeBreakdown
*/
public final SizeBreakdown getLeftoversBreakdown() {
return leftoversBreakdown;
}
/**
* Gets the number of fragments..
*
* @return the number of fragments.
*/
public final int getNumFragments() {
return fragmentDescriptors.size();
}
/**
* Gets the mapping from packages to classes.
*
* @return packageToClasses
*/
public final Map<String, TreeSet<String>> getPackageToClasses() {
return packageToClasses;
}
public String getPermutationId() {
return permutationId;
}
/**
* Gets the initial load sequence.
*
* @return initialFragmentLoadSequence
*/
public final ArrayList<Integer> getInitialFragmentLoadSequence() {
return initialFragmentLoadSequence;
}
/**
* Adds a descriptor (a split point) to a fragment.
*
* @param fragment the fragment number.
* @param desc a string describing a split point for fragment <code>fragment</code>
*
*/
public final void addFragmentDescriptor(int fragment, String desc) {
List<String> descriptions = fragmentDescriptors.get(fragment);
if (descriptions == null) {
descriptions = new ArrayList<String>();
fragmentDescriptors.put(fragment, descriptions);
}
descriptions.add(desc);
}
/**
* Gets the the descriptors associated with a
* fragment.
*
* @param fragment the fragment number
* @return a list of descriptors (each representing a single split point.
*/
public final List<String> getFragmentDescriptors(int fragment) {
return fragmentDescriptors.get(fragment);
}
/**
* Gets the total code breakdown.
*
* @return totalCodeBreakdown
*/
public final SizeBreakdown getTotalCodeBreakdown() {
return totalCodeBreakdown;
}
/**
* Gets an exclusive code breakdown for a fragment.
*
* @param fragment the fragment id
* @return exlusive code breakdown for fragment
*/
public SizeBreakdown fragmentCodeBreakdown(int fragment) {
assert fragment >= 1 && fragment <= getNumFragments();
if (!exclusiveCodeBreakdowns.containsKey(fragment)) {
exclusiveCodeBreakdowns.put(fragment, new SizeBreakdown("split point " + fragment
+ ": " + fragmentDescriptors.get(fragment), "fragment" + fragment));
}
return exclusiveCodeBreakdowns.get(fragment);
}
/**
* Computes package sizes from class sizes. TODO(spoon) move this to the
* SizeBreakdown class.
*
* @param packageToSize mapping from packages to their sizes
* @param classToSize mapping from classes to their sizes
*/
private void computePackageSizes(Map<String, Integer> packageToSize,
Map<String, Integer> classToSize) {
packageToSize.clear();
for (String packageName : packageToClasses.keySet()) {
packageToSize.put(packageName, 0);
for (String className : packageToClasses.get(packageName)) {
if (classToSize.containsKey(className)) {
int curSize = classToSize.get(className);
int newSize = curSize + packageToSize.get(packageName);
packageToSize.put(packageName, newSize);
}
}
}
}
}