• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ahat;
18 
19 import com.android.tools.perflib.heap.Instance;
20 import com.android.tools.perflib.heap.Heap;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Comparator;
24 import java.util.List;
25 import java.util.Iterator;
26 
27 /**
28  * Provides Comparators and helper functions for sorting Instances, Sites, and
29  * other things.
30  *
31  * Note: The Comparators defined here impose orderings that are inconsistent
32  * with equals. They should not be used for element lookup or search. They
33  * should only be used for showing elements to the user in different orders.
34  */
35 class Sort {
36   /**
37    * Compare instances by their instance id.
38    * This sorts instances from smaller id to larger id.
39    */
40   public static class InstanceById implements Comparator<Instance> {
41     @Override
compare(Instance a, Instance b)42     public int compare(Instance a, Instance b) {
43       return Long.compare(a.getId(), b.getId());
44     }
45   }
46 
47   /**
48    * Compare instances by their total retained size.
49    * Different instances with the same total retained size are considered
50    * equal for the purposes of comparison.
51    * This sorts instances from larger retained size to smaller retained size.
52    */
53   public static class InstanceByTotalRetainedSize implements Comparator<Instance> {
54     @Override
compare(Instance a, Instance b)55     public int compare(Instance a, Instance b) {
56       return Long.compare(b.getTotalRetainedSize(), a.getTotalRetainedSize());
57     }
58   }
59 
60   /**
61    * Compare instances by their retained size for a given heap index.
62    * Different instances with the same total retained size are considered
63    * equal for the purposes of comparison.
64    * This sorts instances from larger retained size to smaller retained size.
65    */
66   public static class InstanceByHeapRetainedSize implements Comparator<Instance> {
67     private int mIndex;
68 
InstanceByHeapRetainedSize(AhatSnapshot snapshot, Heap heap)69     public InstanceByHeapRetainedSize(AhatSnapshot snapshot, Heap heap) {
70       mIndex = snapshot.getHeapIndex(heap);
71     }
72 
InstanceByHeapRetainedSize(int heapIndex)73     public InstanceByHeapRetainedSize(int heapIndex) {
74       mIndex = heapIndex;
75     }
76 
77     @Override
compare(Instance a, Instance b)78     public int compare(Instance a, Instance b) {
79       return Long.compare(b.getRetainedSize(mIndex), a.getRetainedSize(mIndex));
80     }
81   }
82 
83   /**
84    * Compare objects based on a list of comparators, giving priority to the
85    * earlier comparators in the list.
86    */
87   public static class WithPriority<T> implements Comparator<T> {
88     private List<Comparator<T>> mComparators;
89 
WithPriority(Comparator<T>.... comparators)90     public WithPriority(Comparator<T>... comparators) {
91       mComparators = Arrays.asList(comparators);
92     }
93 
WithPriority(List<Comparator<T>> comparators)94     public WithPriority(List<Comparator<T>> comparators) {
95       mComparators = comparators;
96     }
97 
98     @Override
compare(T a, T b)99     public int compare(T a, T b) {
100       int res = 0;
101       Iterator<Comparator<T>> iter = mComparators.iterator();
102       while (res == 0 && iter.hasNext()) {
103         res = iter.next().compare(a, b);
104       }
105       return res;
106     }
107   }
108 
defaultInstanceCompare(AhatSnapshot snapshot)109   public static Comparator<Instance> defaultInstanceCompare(AhatSnapshot snapshot) {
110     List<Comparator<Instance>> comparators = new ArrayList<Comparator<Instance>>();
111 
112     // Priority goes to the app heap, if we can find one.
113     Heap appHeap = snapshot.getHeap("app");
114     if (appHeap != null) {
115       comparators.add(new InstanceByHeapRetainedSize(snapshot, appHeap));
116     }
117 
118     // Next is by total retained size.
119     comparators.add(new InstanceByTotalRetainedSize());
120     return new WithPriority<Instance>(comparators);
121   }
122 
123   /**
124    * Compare Sites by the size of objects allocated on a given heap.
125    * Different object infos with the same size on the given heap are
126    * considered equal for the purposes of comparison.
127    * This sorts sites from larger size to smaller size.
128    */
129   public static class SiteBySize implements Comparator<Site> {
130     String mHeap;
131 
SiteBySize(String heap)132     public SiteBySize(String heap) {
133       mHeap = heap;
134     }
135 
136     @Override
compare(Site a, Site b)137     public int compare(Site a, Site b) {
138       return Long.compare(b.getSize(mHeap), a.getSize(mHeap));
139     }
140   }
141 
142   /**
143    * Compare Site.ObjectsInfo by their size.
144    * Different object infos with the same total retained size are considered
145    * equal for the purposes of comparison.
146    * This sorts object infos from larger retained size to smaller size.
147    */
148   public static class ObjectsInfoBySize implements Comparator<Site.ObjectsInfo> {
149     @Override
compare(Site.ObjectsInfo a, Site.ObjectsInfo b)150     public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
151       return Long.compare(b.numBytes, a.numBytes);
152     }
153   }
154 
155   /**
156    * Compare Site.ObjectsInfo by heap name.
157    * Different object infos with the same heap name are considered equal for
158    * the purposes of comparison.
159    */
160   public static class ObjectsInfoByHeapName implements Comparator<Site.ObjectsInfo> {
161     @Override
compare(Site.ObjectsInfo a, Site.ObjectsInfo b)162     public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
163       return a.heap.getName().compareTo(b.heap.getName());
164     }
165   }
166 
167   /**
168    * Compare Site.ObjectsInfo by class name.
169    * Different object infos with the same class name are considered equal for
170    * the purposes of comparison.
171    */
172   public static class ObjectsInfoByClassName implements Comparator<Site.ObjectsInfo> {
173     @Override
compare(Site.ObjectsInfo a, Site.ObjectsInfo b)174     public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
175       String aName = AhatSnapshot.getClassName(a.classObj);
176       String bName = AhatSnapshot.getClassName(b.classObj);
177       return aName.compareTo(bName);
178     }
179   }
180 
181   /**
182    * Compare AhatSnapshot.NativeAllocation by heap name.
183    * Different allocations with the same heap name are considered equal for
184    * the purposes of comparison.
185    */
186   public static class NativeAllocationByHeapName
187       implements Comparator<InstanceUtils.NativeAllocation> {
188     @Override
compare(InstanceUtils.NativeAllocation a, InstanceUtils.NativeAllocation b)189     public int compare(InstanceUtils.NativeAllocation a, InstanceUtils.NativeAllocation b) {
190       return a.heap.getName().compareTo(b.heap.getName());
191     }
192   }
193 
194   /**
195    * Compare InstanceUtils.NativeAllocation by their size.
196    * Different allocations with the same size are considered equal for the
197    * purposes of comparison.
198    * This sorts allocations from larger size to smaller size.
199    */
200   public static class NativeAllocationBySize implements Comparator<InstanceUtils.NativeAllocation> {
201     @Override
compare(InstanceUtils.NativeAllocation a, InstanceUtils.NativeAllocation b)202     public int compare(InstanceUtils.NativeAllocation a, InstanceUtils.NativeAllocation b) {
203       return Long.compare(b.size, a.size);
204     }
205   }
206 }
207 
208