Home | History | Annotate | Download | only in src
      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
     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
     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 
     69     public InstanceByHeapRetainedSize(AhatSnapshot snapshot, Heap heap) {
     70       mIndex = snapshot.getHeapIndex(heap);
     71     }
     72 
     73     public InstanceByHeapRetainedSize(int heapIndex) {
     74       mIndex = heapIndex;
     75     }
     76 
     77     @Override
     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 
     90     public WithPriority(Comparator<T>... comparators) {
     91       mComparators = Arrays.asList(comparators);
     92     }
     93 
     94     public WithPriority(List<Comparator<T>> comparators) {
     95       mComparators = comparators;
     96     }
     97 
     98     @Override
     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 
    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 
    132     public SiteBySize(String heap) {
    133       mHeap = heap;
    134     }
    135 
    136     @Override
    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
    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
    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
    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
    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
    202     public int compare(InstanceUtils.NativeAllocation a, InstanceUtils.NativeAllocation b) {
    203       return Long.compare(b.size, a.size);
    204     }
    205   }
    206 }
    207 
    208