• 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.heapdump;
18 
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Comparator;
22 import java.util.Iterator;
23 import java.util.List;
24 
25 /**
26  * Provides Comparators and helper functions for sorting Instances, Sites, and
27  * other things.
28  *
29  * Note: The Comparators defined here impose orderings that are inconsistent
30  * with equals. They should not be used for element lookup or search. They
31  * should only be used for showing elements to the user in different orders.
32  */
33 public class Sort {
34   /**
35    * Compare instances by their total retained size.
36    * Different instances with the same total retained size are considered
37    * equal for the purposes of comparison.
38    * This sorts instances from larger retained size to smaller retained size.
39    */
40   public static final Comparator<AhatInstance> INSTANCE_BY_TOTAL_RETAINED_SIZE
41     = new Comparator<AhatInstance>() {
42     @Override
43     public int compare(AhatInstance a, AhatInstance b) {
44       return Long.compare(b.getTotalRetainedSize(), a.getTotalRetainedSize());
45     }
46   };
47 
48   /**
49    * Compare instances by their retained size for a given heap index.
50    * Different instances with the same total retained size are considered
51    * equal for the purposes of comparison.
52    * This sorts instances from larger retained size to smaller retained size.
53    */
54   public static class InstanceByHeapRetainedSize implements Comparator<AhatInstance> {
55     private AhatHeap mHeap;
56 
InstanceByHeapRetainedSize(AhatHeap heap)57     public InstanceByHeapRetainedSize(AhatHeap heap) {
58       mHeap = heap;
59     }
60 
61     @Override
compare(AhatInstance a, AhatInstance b)62     public int compare(AhatInstance a, AhatInstance b) {
63       return Long.compare(b.getRetainedSize(mHeap), a.getRetainedSize(mHeap));
64     }
65   }
66 
67   /**
68    * Compare objects based on a list of comparators, giving priority to the
69    * earlier comparators in the list.
70    */
71   public static class WithPriority<T> implements Comparator<T> {
72     private List<Comparator<T>> mComparators;
73 
WithPriority(Comparator<T>.... comparators)74     public WithPriority(Comparator<T>... comparators) {
75       mComparators = Arrays.asList(comparators);
76     }
77 
WithPriority(List<Comparator<T>> comparators)78     public WithPriority(List<Comparator<T>> comparators) {
79       mComparators = comparators;
80     }
81 
82     @Override
compare(T a, T b)83     public int compare(T a, T b) {
84       int res = 0;
85       Iterator<Comparator<T>> iter = mComparators.iterator();
86       while (res == 0 && iter.hasNext()) {
87         res = iter.next().compare(a, b);
88       }
89       return res;
90     }
91   }
92 
defaultInstanceCompare(AhatSnapshot snapshot)93   public static Comparator<AhatInstance> defaultInstanceCompare(AhatSnapshot snapshot) {
94     List<Comparator<AhatInstance>> comparators = new ArrayList<Comparator<AhatInstance>>();
95 
96     // Priority goes to the app heap, if we can find one.
97     AhatHeap appHeap = snapshot.getHeap("app");
98     if (appHeap != null) {
99       comparators.add(new InstanceByHeapRetainedSize(appHeap));
100     }
101 
102     // Next is by total retained size.
103     comparators.add(INSTANCE_BY_TOTAL_RETAINED_SIZE);
104     return new WithPriority<AhatInstance>(comparators);
105   }
106 
107   /**
108    * Compare Sites by the size of objects allocated on a given heap.
109    * Different object infos with the same size on the given heap are
110    * considered equal for the purposes of comparison.
111    * This sorts sites from larger size to smaller size.
112    */
113   public static class SiteByHeapSize implements Comparator<Site> {
114     AhatHeap mHeap;
115 
SiteByHeapSize(AhatHeap heap)116     public SiteByHeapSize(AhatHeap heap) {
117       mHeap = heap;
118     }
119 
120     @Override
compare(Site a, Site b)121     public int compare(Site a, Site b) {
122       return Long.compare(b.getSize(mHeap), a.getSize(mHeap));
123     }
124   }
125 
126   /**
127    * Compare Sites by the total size of objects allocated.
128    * This sorts sites from larger size to smaller size.
129    */
130   public static final Comparator<Site> SITE_BY_TOTAL_SIZE = new Comparator<Site>() {
131     @Override
132     public int compare(Site a, Site b) {
133       return Long.compare(b.getTotalSize(), a.getTotalSize());
134     }
135   };
136 
defaultSiteCompare(AhatSnapshot snapshot)137   public static Comparator<Site> defaultSiteCompare(AhatSnapshot snapshot) {
138     List<Comparator<Site>> comparators = new ArrayList<Comparator<Site>>();
139 
140     // Priority goes to the app heap, if we can find one.
141     AhatHeap appHeap = snapshot.getHeap("app");
142     if (appHeap != null) {
143       comparators.add(new SiteByHeapSize(appHeap));
144     }
145 
146     // Next is by total size.
147     comparators.add(SITE_BY_TOTAL_SIZE);
148     return new WithPriority<Site>(comparators);
149   }
150 
151   /**
152    * Compare Site.ObjectsInfo by their size.
153    * Different object infos with the same total retained size are considered
154    * equal for the purposes of comparison.
155    * This sorts object infos from larger retained size to smaller size.
156    */
157   public static final Comparator<Site.ObjectsInfo> OBJECTS_INFO_BY_SIZE
158     = new Comparator<Site.ObjectsInfo>() {
159     @Override
160     public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
161       return Long.compare(b.numBytes, a.numBytes);
162     }
163   };
164 
165   /**
166    * Compare Site.ObjectsInfo by heap name.
167    * Different object infos with the same heap name are considered equal for
168    * the purposes of comparison.
169    */
170   public static final Comparator<Site.ObjectsInfo> OBJECTS_INFO_BY_HEAP_NAME
171     = new Comparator<Site.ObjectsInfo>() {
172     @Override
173     public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
174       return a.heap.getName().compareTo(b.heap.getName());
175     }
176   };
177 
178   /**
179    * Compare Site.ObjectsInfo by class name.
180    * Different object infos with the same class name are considered equal for
181    * the purposes of comparison.
182    */
183   public static final Comparator<Site.ObjectsInfo> OBJECTS_INFO_BY_CLASS_NAME
184     = new Comparator<Site.ObjectsInfo>() {
185     @Override
186     public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
187       String aName = a.getClassName();
188       String bName = b.getClassName();
189       return aName.compareTo(bName);
190     }
191   };
192 }
193 
194