1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.file; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collection; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.TreeMap; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Statistics about the contents of a file. 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class Statistics { 2899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} data about each type of item */ 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final HashMap<String, Data> dataMap; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Statistics() { 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataMap = new HashMap<String, Data>(50); 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds the given item to the statistics. 40de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 4199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param item {@code non-null;} the item to add 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void add(Item item) { 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String typeName = item.typeName(); 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Data data = dataMap.get(typeName); 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (data == null) { 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataMap.put(typeName, new Data(item, typeName)); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data.add(item); 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds the given list of items to the statistics. 56de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 5799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param list {@code non-null;} the list of items to add 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addAll(Section list) { 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Collection<? extends Item> items = list.items(); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Item item : items) { 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project add(item); 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes the statistics as an annotation. 68de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void writeAnnotation(AnnotatedOutput out) { 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataMap.size() == 0) { 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(0, "\nstatistics:\n"); 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TreeMap<String, Data> sortedData = new TreeMap<String, Data>(); 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Data data : dataMap.values()) { 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sortedData.put(data.name, data); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Data data : sortedData.values()) { 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data.writeAnnotation(out); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder sb = new StringBuilder(); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("Statistics:\n"); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TreeMap<String, Data> sortedData = new TreeMap<String, Data>(); 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Data data : dataMap.values()) { 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sortedData.put(data.name, data); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (Data data : sortedData.values()) { 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(data.toHuman()); 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Statistical data about a particular class. 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class Data { 11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} name to use as a label */ 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final String name; 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0;} number of instances */ 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int count; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 11799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0;} total size of instances in bytes */ 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int totalSize; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0;} largest size of any individual item */ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int largestSize; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 12399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0;} smallest size of any individual item */ 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int smallestSize; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance for the given item. 128de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 12999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param item {@code non-null;} item in question 13099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param name {@code non-null;} type name to use 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Data(Item item, String name) { 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = item.writeSize(); 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.name = name; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.count = 1; 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.totalSize = size; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.largestSize = size; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.smallestSize = size; 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Incorporates a new item. This assumes the type name matches. 144de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 14599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param item {@code non-null;} item to incorporate 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void add(Item item) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = item.writeSize(); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count++; 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project totalSize += size; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size > largestSize) { 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project largestSize = size; 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (size < smallestSize) { 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project smallestSize = size; 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes this instance as an annotation. 164de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 16599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void writeAnnotation(AnnotatedOutput out) { 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.annotate(toHuman()); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generates a human-readable string for this data item. 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return string for human consumption. 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder sb = new StringBuilder(); 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" " + name + ": " + 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count + " item" + (count == 1 ? "" : "s") + "; " + 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project totalSize + " bytes total\n"); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (smallestSize == largestSize) { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" " + smallestSize + " bytes/item\n"); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int average = totalSize / count; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" " + smallestSize + ".." + largestSize + 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " bytes/item; average " + average + "\n"); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 195