OSDN Git Service

Merge "Add eclipse version to usage stat ping."
[android-x86/sdk.git] / ddms / libs / ddmuilib / src / com / android / ddmuilib / BaseHeapPanel.java
1 /*
2  * Copyright (C) 2007 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.ddmuilib;
18
19 import com.android.ddmlib.HeapSegment;
20 import com.android.ddmlib.ClientData.HeapData;
21 import com.android.ddmlib.HeapSegment.HeapSegmentElement;
22
23 import org.eclipse.swt.graphics.ImageData;
24 import org.eclipse.swt.graphics.PaletteData;
25
26 import java.io.ByteArrayOutputStream;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Iterator;
31 import java.util.Map;
32 import java.util.TreeMap;
33
34
35 /**
36  * Base Panel for heap panels.
37  */
38 public abstract class BaseHeapPanel extends TablePanel {
39
40     /** store the processed heap segment, so that we don't recompute Image for nothing */
41     protected byte[] mProcessedHeapData;
42     private Map<Integer, ArrayList<HeapSegmentElement>> mHeapMap;
43
44     /**
45      * Serialize the heap data into an array. The resulting array is available through
46      * <code>getSerializedData()</code>.
47      * @param heapData The heap data to serialize
48      * @return true if the data changed.
49      */
50     protected boolean serializeHeapData(HeapData heapData) {
51         Collection<HeapSegment> heapSegments;
52
53         // Atomically get and clear the heap data.
54         synchronized (heapData) {
55             // get the segments
56             heapSegments = heapData.getHeapSegments();
57             
58             
59             if (heapSegments != null) {
60                 // if they are not null, we never processed them.
61                 // Before we process then, we drop them from the HeapData
62                 heapData.clearHeapData();
63
64                 // process them into a linear byte[]
65                 doSerializeHeapData(heapSegments);
66                 heapData.setProcessedHeapData(mProcessedHeapData);
67                 heapData.setProcessedHeapMap(mHeapMap);
68                 
69             } else {
70                 // the heap segments are null. Let see if the heapData contains a 
71                 // list that is already processed.
72                 
73                 byte[] pixData = heapData.getProcessedHeapData();
74                 
75                 // and compare it to the one we currently have in the panel.
76                 if (pixData == mProcessedHeapData) {
77                     // looks like its the same
78                     return false;
79                 } else {
80                     mProcessedHeapData = pixData;
81                 }
82                 
83                 Map<Integer, ArrayList<HeapSegmentElement>> heapMap =
84                     heapData.getProcessedHeapMap();
85                 mHeapMap = heapMap;
86             }
87         }
88
89         return true;
90     }
91
92     /**
93      * Returns the serialized heap data
94      */
95     protected byte[] getSerializedData() {
96         return mProcessedHeapData;
97     }
98
99     /**
100      * Processes and serialize the heapData.
101      * <p/>
102      * The resulting serialized array is {@link #mProcessedHeapData}.
103      * <p/>
104      * the resulting map is {@link #mHeapMap}.
105      * @param heapData the collection of {@link HeapSegment} that forms the heap data.
106      */
107     private void doSerializeHeapData(Collection<HeapSegment> heapData) {
108         mHeapMap = new TreeMap<Integer, ArrayList<HeapSegmentElement>>();
109
110         Iterator<HeapSegment> iterator;
111         ByteArrayOutputStream out;
112
113         out = new ByteArrayOutputStream(4 * 1024);
114
115         iterator = heapData.iterator();
116         while (iterator.hasNext()) {
117             HeapSegment hs = iterator.next();
118
119             HeapSegmentElement e = null;
120             while (true) {
121                 int v;
122
123                 e = hs.getNextElement(null);
124                 if (e == null) {
125                     break;
126                 }
127                 
128                 if (e.getSolidity() == HeapSegmentElement.SOLIDITY_FREE) {
129                     v = 1;
130                 } else {
131                     v = e.getKind() + 2;
132                 }
133                 
134                 // put the element in the map
135                 ArrayList<HeapSegmentElement> elementList = mHeapMap.get(v);
136                 if (elementList == null) {
137                     elementList = new ArrayList<HeapSegmentElement>();
138                     mHeapMap.put(v, elementList);
139                 }
140                 elementList.add(e);
141
142
143                 int len = e.getLength() / 8;
144                 while (len > 0) {
145                     out.write(v);
146                     --len;
147                 }
148             }
149         }
150         mProcessedHeapData = out.toByteArray();
151         
152         // sort the segment element in the heap info.
153         Collection<ArrayList<HeapSegmentElement>> elementLists = mHeapMap.values();
154         for (ArrayList<HeapSegmentElement> elementList : elementLists) {
155             Collections.sort(elementList);
156         }
157     }
158     
159     /**
160      * Creates a linear image of the heap data.
161      * @param pixData
162      * @param h
163      * @param palette
164      * @return
165      */
166     protected ImageData createLinearHeapImage(byte[] pixData, int h, PaletteData palette) {
167         int w = pixData.length / h;
168         if (pixData.length % h != 0) {
169             w++;
170         }
171
172         // Create the heap image.
173         ImageData id = new ImageData(w, h, 8, palette);
174
175         int x = 0;
176         int y = 0;
177         for (byte b : pixData) {
178             if (b >= 0) {
179                 id.setPixel(x, y, b);
180             }
181
182             y++;
183             if (y >= h) {
184                 y = 0;
185                 x++;
186             }
187         }
188
189         return id;
190     }
191
192
193 }