package com.didi.codeProfiler;
import java.awt.*;
import java.util.*;
public class CodeLayers extends CodeProfiler {
class ThreadData { Thread thread; double timing, usage;
LineData[] profile=new LineData[256];}
class LineData {double usage, currentSize;}
Hashtable threadTable=new Hashtable();
Vector threads=new Vector();
Font[] lineFont=new Font[300];
public CodeLayers() {
for (int i=1; i<lineFont.length; i++)
lineFont[i]=new Font("Helvetica", Font.BOLD, i);
setBackground(Color.white);
}
public synchronized int line(int i) {
Thread thread=Thread.currentThread();
ThreadData data=(ThreadData)threadTable.get(thread);
if (data==null) {
data=new ThreadData(); data.thread=thread;
threadTable.put(thread, data);
int j;
for (j=0; j<threads.size() && data(j).thread.getPriority()<thread.getPriority(); j++);
threads.insertElementAt(data,j);
}
if (data.profile[i]==null) data.profile[i]=new LineData();
data.profile[i].usage++; data.usage++; data.timing=2;
return i;
}
ThreadData data(int i) { return (ThreadData)threads.elementAt(i);}
void drawCodeLayers(Graphics g, int w, int h) {
g.setColor(getBackground());
g.fillRect(0,0,w,h);
if (programLines==null) return;
int i,j,n=threads.size();
for (i=0; i<n; i++) {
ThreadData data=data(i);
if (data.usage<=0 || data.timing<=0) continue;
LineData[] profile=data.profile;
for (j=0; j<profile.length; j++) {
if (profile[j]==null) continue;
profile[j].currentSize=.95*profile[j].currentSize+
.05*profile[j].usage/data.usage;
profile[j].usage*=.95;
}
nt c=Math.max(0, Math.min(255, 1230-200*data.thread.getPriority()));
g.setColor(new Color((int)(c*.5),64+(int)(c*.5),(int)(100+c*.5)));
double position=Math.min(data.timing,1)-1;
for (j=0; j<programLines.length; j++) {
Line line=programLines[j];
if (!line.hasLineCall || profile[line.lineAsWrittenIndex]==null)
continue;
double u=profile[line.lineAsWrittenIndex].currentSize;
if (u==0) continue;
int lineH=(int)(u*h), lineY=(int)(5+position*(h-10));
g.setFont(lineFont[Math.max(1,Math.min(lineH, lineFont.length-1))]);
int q=line.s.indexOf("line(");
if (q>-1) line.s=line.s.substring(0,q);
line.s=line.s.trim();
if (line.s.length()==0)
line.s=programLines[j-1].s.trim();
g.drawString(line.s,5,lineY+(3*lineH)/4);
position+=u;
}
data.usage*=.95; data.timing-=.04;
}
}
public synchronized void drawAll(Graphics g) {
int w=size().width/2, h=size().height;
if (w<21 || h<21) return;
if (offscreenImage==null ||
w!=offscreenImage.getWidth(this) ||
h!=offscreenImage.getHeight(this)) {
offscreenImage=createImage(w, h);
offscreenGraphics=offscreenImage.getGraphics();
}
if (offscreenGraphics==null) return;
drawCodeLayers(offscreenGraphics, w,h);
g.drawImage(offscreenImage, 0, 0, this);
}
}