OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / sdk / ddms / libs / ddmuilib / src / com / android / ddmuilib / BaseHeapPanel.java
diff --git a/sdk/ddms/libs/ddmuilib/src/com/android/ddmuilib/BaseHeapPanel.java b/sdk/ddms/libs/ddmuilib/src/com/android/ddmuilib/BaseHeapPanel.java
new file mode 100644 (file)
index 0000000..3e66ea5
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.HeapSegment;
+import com.android.ddmlib.ClientData.HeapData;
+import com.android.ddmlib.HeapSegment.HeapSegmentElement;
+
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+
+/**
+ * Base Panel for heap panels.
+ */
+public abstract class BaseHeapPanel extends TablePanel {
+
+    /** store the processed heap segment, so that we don't recompute Image for nothing */
+    protected byte[] mProcessedHeapData;
+    private Map<Integer, ArrayList<HeapSegmentElement>> mHeapMap;
+
+    /**
+     * Serialize the heap data into an array. The resulting array is available through
+     * <code>getSerializedData()</code>.
+     * @param heapData The heap data to serialize
+     * @return true if the data changed.
+     */
+    protected boolean serializeHeapData(HeapData heapData) {
+        Collection<HeapSegment> heapSegments;
+
+        // Atomically get and clear the heap data.
+        synchronized (heapData) {
+            // get the segments
+            heapSegments = heapData.getHeapSegments();
+            
+            
+            if (heapSegments != null) {
+                // if they are not null, we never processed them.
+                // Before we process then, we drop them from the HeapData
+                heapData.clearHeapData();
+
+                // process them into a linear byte[]
+                doSerializeHeapData(heapSegments);
+                heapData.setProcessedHeapData(mProcessedHeapData);
+                heapData.setProcessedHeapMap(mHeapMap);
+                
+            } else {
+                // the heap segments are null. Let see if the heapData contains a 
+                // list that is already processed.
+                
+                byte[] pixData = heapData.getProcessedHeapData();
+                
+                // and compare it to the one we currently have in the panel.
+                if (pixData == mProcessedHeapData) {
+                    // looks like its the same
+                    return false;
+                } else {
+                    mProcessedHeapData = pixData;
+                }
+                
+                Map<Integer, ArrayList<HeapSegmentElement>> heapMap =
+                    heapData.getProcessedHeapMap();
+                mHeapMap = heapMap;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the serialized heap data
+     */
+    protected byte[] getSerializedData() {
+        return mProcessedHeapData;
+    }
+
+    /**
+     * Processes and serialize the heapData.
+     * <p/>
+     * The resulting serialized array is {@link #mProcessedHeapData}.
+     * <p/>
+     * the resulting map is {@link #mHeapMap}.
+     * @param heapData the collection of {@link HeapSegment} that forms the heap data.
+     */
+    private void doSerializeHeapData(Collection<HeapSegment> heapData) {
+        mHeapMap = new TreeMap<Integer, ArrayList<HeapSegmentElement>>();
+
+        Iterator<HeapSegment> iterator;
+        ByteArrayOutputStream out;
+
+        out = new ByteArrayOutputStream(4 * 1024);
+
+        iterator = heapData.iterator();
+        while (iterator.hasNext()) {
+            HeapSegment hs = iterator.next();
+
+            HeapSegmentElement e = null;
+            while (true) {
+                int v;
+
+                e = hs.getNextElement(null);
+                if (e == null) {
+                    break;
+                }
+                
+                if (e.getSolidity() == HeapSegmentElement.SOLIDITY_FREE) {
+                    v = 1;
+                } else {
+                    v = e.getKind() + 2;
+                }
+                
+                // put the element in the map
+                ArrayList<HeapSegmentElement> elementList = mHeapMap.get(v);
+                if (elementList == null) {
+                    elementList = new ArrayList<HeapSegmentElement>();
+                    mHeapMap.put(v, elementList);
+                }
+                elementList.add(e);
+
+
+                int len = e.getLength() / 8;
+                while (len > 0) {
+                    out.write(v);
+                    --len;
+                }
+            }
+        }
+        mProcessedHeapData = out.toByteArray();
+        
+        // sort the segment element in the heap info.
+        Collection<ArrayList<HeapSegmentElement>> elementLists = mHeapMap.values();
+        for (ArrayList<HeapSegmentElement> elementList : elementLists) {
+            Collections.sort(elementList);
+        }
+    }
+    
+    /**
+     * Creates a linear image of the heap data.
+     * @param pixData
+     * @param h
+     * @param palette
+     * @return
+     */
+    protected ImageData createLinearHeapImage(byte[] pixData, int h, PaletteData palette) {
+        int w = pixData.length / h;
+        if (pixData.length % h != 0) {
+            w++;
+        }
+
+        // Create the heap image.
+        ImageData id = new ImageData(w, h, 8, palette);
+
+        int x = 0;
+        int y = 0;
+        for (byte b : pixData) {
+            if (b >= 0) {
+                id.setPixel(x, y, b);
+            }
+
+            y++;
+            if (y >= h) {
+                y = 0;
+                x++;
+            }
+        }
+
+        return id;
+    }
+
+
+}