blob: 93d147a49e9de0bce8f768023f473ba22ff05a55 [file] [log] [blame]
Richard Uhlerb730b782015-07-15 16:01:58 -07001/*
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
Richard Uhlerf629cfd2016-12-12 13:11:26 +000017package com.android.ahat.heapdump;
Richard Uhlerb730b782015-07-15 16:01:58 -070018
Richard Uhlerb730b782015-07-15 16:01:58 -070019import java.util.ArrayList;
20import java.util.Arrays;
21import java.util.Comparator;
Richard Uhlerb730b782015-07-15 16:01:58 -070022import java.util.Iterator;
Gus Smithe6a63872016-06-09 16:50:44 -070023import java.util.List;
Richard Uhlerb730b782015-07-15 16:01:58 -070024
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 */
Richard Uhlerf629cfd2016-12-12 13:11:26 +000033public class Sort {
Richard Uhlerb730b782015-07-15 16:01:58 -070034 /**
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 */
Richard Uhlerf629cfd2016-12-12 13:11:26 +000040 public static final Comparator<AhatInstance> INSTANCE_BY_TOTAL_RETAINED_SIZE
41 = new Comparator<AhatInstance>() {
Richard Uhlerb730b782015-07-15 16:01:58 -070042 @Override
Richard Uhlercda4f2e2016-09-09 09:56:20 +010043 public int compare(AhatInstance a, AhatInstance b) {
Richard Uhlerb730b782015-07-15 16:01:58 -070044 return Long.compare(b.getTotalRetainedSize(), a.getTotalRetainedSize());
45 }
Richard Uhlerf629cfd2016-12-12 13:11:26 +000046 };
Richard Uhlerb730b782015-07-15 16:01:58 -070047
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 */
Richard Uhlercda4f2e2016-09-09 09:56:20 +010054 public static class InstanceByHeapRetainedSize implements Comparator<AhatInstance> {
55 private AhatHeap mHeap;
Richard Uhlerb730b782015-07-15 16:01:58 -070056
Richard Uhlercda4f2e2016-09-09 09:56:20 +010057 public InstanceByHeapRetainedSize(AhatHeap heap) {
58 mHeap = heap;
Richard Uhlerb730b782015-07-15 16:01:58 -070059 }
60
61 @Override
Richard Uhlercda4f2e2016-09-09 09:56:20 +010062 public int compare(AhatInstance a, AhatInstance b) {
63 return Long.compare(b.getRetainedSize(mHeap), a.getRetainedSize(mHeap));
Richard Uhlerb730b782015-07-15 16:01:58 -070064 }
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
74 public WithPriority(Comparator<T>... comparators) {
75 mComparators = Arrays.asList(comparators);
76 }
77
78 public WithPriority(List<Comparator<T>> comparators) {
79 mComparators = comparators;
80 }
81
82 @Override
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
Richard Uhlercda4f2e2016-09-09 09:56:20 +010093 public static Comparator<AhatInstance> defaultInstanceCompare(AhatSnapshot snapshot) {
94 List<Comparator<AhatInstance>> comparators = new ArrayList<Comparator<AhatInstance>>();
Richard Uhlerb730b782015-07-15 16:01:58 -070095
96 // Priority goes to the app heap, if we can find one.
Richard Uhlercda4f2e2016-09-09 09:56:20 +010097 AhatHeap appHeap = snapshot.getHeap("app");
Richard Uhlerb730b782015-07-15 16:01:58 -070098 if (appHeap != null) {
Richard Uhlercda4f2e2016-09-09 09:56:20 +010099 comparators.add(new InstanceByHeapRetainedSize(appHeap));
Richard Uhlerb730b782015-07-15 16:01:58 -0700100 }
101
102 // Next is by total retained size.
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000103 comparators.add(INSTANCE_BY_TOTAL_RETAINED_SIZE);
Richard Uhlercda4f2e2016-09-09 09:56:20 +0100104 return new WithPriority<AhatInstance>(comparators);
Richard Uhlerb730b782015-07-15 16:01:58 -0700105 }
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 */
Richard Uhlercda4f2e2016-09-09 09:56:20 +0100113 public static class SiteByHeapSize implements Comparator<Site> {
114 AhatHeap mHeap;
Richard Uhlerb730b782015-07-15 16:01:58 -0700115
Richard Uhlercda4f2e2016-09-09 09:56:20 +0100116 public SiteByHeapSize(AhatHeap heap) {
Richard Uhlerb730b782015-07-15 16:01:58 -0700117 mHeap = heap;
118 }
119
120 @Override
121 public int compare(Site a, Site b) {
122 return Long.compare(b.getSize(mHeap), a.getSize(mHeap));
123 }
124 }
125
126 /**
Richard Uhlercda4f2e2016-09-09 09:56:20 +0100127 * Compare Sites by the total size of objects allocated.
128 * This sorts sites from larger size to smaller size.
129 */
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000130 public static final Comparator<Site> SITE_BY_TOTAL_SIZE = new Comparator<Site>() {
Richard Uhlercda4f2e2016-09-09 09:56:20 +0100131 @Override
132 public int compare(Site a, Site b) {
133 return Long.compare(b.getTotalSize(), a.getTotalSize());
134 }
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000135 };
Richard Uhlercda4f2e2016-09-09 09:56:20 +0100136
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.
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000147 comparators.add(SITE_BY_TOTAL_SIZE);
Richard Uhlercda4f2e2016-09-09 09:56:20 +0100148 return new WithPriority<Site>(comparators);
149 }
150
151 /**
Richard Uhlerb730b782015-07-15 16:01:58 -0700152 * 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 */
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000157 public static final Comparator<Site.ObjectsInfo> OBJECTS_INFO_BY_SIZE
158 = new Comparator<Site.ObjectsInfo>() {
Richard Uhlerb730b782015-07-15 16:01:58 -0700159 @Override
160 public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
161 return Long.compare(b.numBytes, a.numBytes);
162 }
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000163 };
Richard Uhlerb730b782015-07-15 16:01:58 -0700164
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 */
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000170 public static final Comparator<Site.ObjectsInfo> OBJECTS_INFO_BY_HEAP_NAME
171 = new Comparator<Site.ObjectsInfo>() {
Richard Uhlerb730b782015-07-15 16:01:58 -0700172 @Override
173 public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
174 return a.heap.getName().compareTo(b.heap.getName());
175 }
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000176 };
Richard Uhlerb730b782015-07-15 16:01:58 -0700177
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 */
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000183 public static final Comparator<Site.ObjectsInfo> OBJECTS_INFO_BY_CLASS_NAME
184 = new Comparator<Site.ObjectsInfo>() {
Richard Uhlerb730b782015-07-15 16:01:58 -0700185 @Override
186 public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
Richard Uhlercda4f2e2016-09-09 09:56:20 +0100187 String aName = a.getClassName();
188 String bName = b.getClassName();
Richard Uhlerb730b782015-07-15 16:01:58 -0700189 return aName.compareTo(bName);
190 }
Richard Uhlerf629cfd2016-12-12 13:11:26 +0000191 };
Richard Uhlerb730b782015-07-15 16:01:58 -0700192}
193