Statistics.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
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 Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collection;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.TreeMap;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Statistics about the contents of a file.
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class Statistics {
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** non-null; data about each type of item */
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final HashMap<String, Data> dataMap;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Statistics() {
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dataMap = new HashMap<String, Data>(50);
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds the given item to the statistics.
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param item non-null; the item to add
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void add(Item item) {
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String typeName = item.typeName();
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Data data = dataMap.get(typeName);
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (data == null) {
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dataMap.put(typeName, new Data(item, typeName));
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            data.add(item);
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds the given list of items to the statistics.
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param list non-null; the list of items to add
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addAll(Section list) {
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Collection<? extends Item> items = list.items();
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Item item : items) {
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            add(item);
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Writes the statistics as an annotation.
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param out non-null; where to write to
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void writeAnnotation(AnnotatedOutput out) {
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dataMap.size() == 0) {
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.annotate(0, "\nstatistics:\n");
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        TreeMap<String, Data> sortedData = new TreeMap<String, Data>();
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Data data : dataMap.values()) {
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sortedData.put(data.name, data);
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Data data : sortedData.values()) {
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            data.writeAnnotation(out);
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toHuman() {
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuilder sb = new StringBuilder();
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sb.append("Statistics:\n");
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        TreeMap<String, Data> sortedData = new TreeMap<String, Data>();
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Data data : dataMap.values()) {
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sortedData.put(data.name, data);
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Data data : sortedData.values()) {
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(data.toHuman());
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sb.toString();
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Statistical data about a particular class.
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static class Data {
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** non-null; name to use as a label */
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final String name;
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** &gt;= 0; number of instances */
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private int count;
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** &gt;= 0; total size of instances in bytes */
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private int totalSize;
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** &gt;= 0; largest size of any individual item */
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private int largestSize;
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** &gt;= 0; smallest size of any individual item */
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private int smallestSize;
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Constructs an instance for the given item.
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param item non-null; item in question
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param name non-null; type name to use
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Data(Item item, String name) {
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int size = item.writeSize();
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.name = name;
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.count = 1;
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.totalSize = size;
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.largestSize = size;
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.smallestSize = size;
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Incorporates a new item. This assumes the type name matches.
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param item non-null; item to incorporate
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public void add(Item item) {
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int size = item.writeSize();
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            count++;
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            totalSize += size;
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (size > largestSize) {
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                largestSize = size;
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (size < smallestSize) {
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                smallestSize = size;
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Writes this instance as an annotation.
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param out non-null; where to write to
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public void writeAnnotation(AnnotatedOutput out) {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(toHuman());
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Generates a human-readable string for this data item.
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return string for human consumption.
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public String toHuman() {
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            StringBuilder sb = new StringBuilder();
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append("  " + name + ": " +
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                         count + " item" + (count == 1 ? "" : "s") + "; " +
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                         totalSize + " bytes total\n");
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (smallestSize == largestSize) {
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append("    " + smallestSize + " bytes/item\n");
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int average = totalSize / count;
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append("    " + smallestSize + ".." + largestSize +
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                             " bytes/item; average " + average + "\n");
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return sb.toString();
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
196