001: // $Id: PerfHeader.java,v 1.10 2006/08/05 11:11:21 belaban Exp $
002:
003: package org.jgroups.protocols;
004:
005: import org.jgroups.Header;
006: import org.jgroups.Message;
007: import org.jgroups.stack.Protocol;
008: import org.jgroups.util.Util;
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011:
012: import java.io.*;
013: import java.util.HashMap;
014: import java.util.Iterator;
015: import java.util.Vector;
016:
017: /**
018: * Inserted by PERF into each message. Records the time taken by each protocol to process the message to
019: * which this header is attached. Travels down through the stack and up the other stack with the message.
020: *
021: * @author Bela Ban
022: */
023: public class PerfHeader extends Header {
024: Object sender = null;
025: Object receiver = null;
026: long start_time = 0; // time when header was created
027: long end_time = 0; // time when header was received
028: long network_send = 0; // time the packet was put on the network
029: long network_recv = 0; // time the packet was received from the network
030: long network_time = 0; // time spent on the network (between bottom layers)
031: HashMap down = new HashMap(); // key=protocol name, val=PerfEntry
032: HashMap up = new HashMap(); // key=protocol name, val=PerfEntry
033: final static int UP = 1;
034: final static int DOWN = 2;
035: final static String classname = "org.jgroups.protocols.PerfHeader";
036: static long size = 0;
037: private static Message msg2;
038: static Log log = LogFactory.getLog(PerfHeader.class);
039:
040: static {
041: size = Util.sizeOf(classname);
042: if (size <= 0)
043: size = 400;
044: }
045:
046: // Needed for externalization
047: public PerfHeader() {
048: }
049:
050: public PerfHeader(Object sender, Object receiver) {
051: this .sender = sender;
052: this .receiver = receiver;
053: start_time = System.currentTimeMillis();
054: }
055:
056: public String toString() {
057: return "[PerfHeader]";
058: }
059:
060: public String printContents(boolean detailed) {
061: return printContents(detailed, null);
062: }
063:
064: public String printContents(boolean detailed, Vector prots) {
065: StringBuffer sb = new StringBuffer();
066: String key;
067: PerfEntry val;
068: Protocol p;
069:
070: if (sender != null)
071: sb.append("sender=").append(sender).append('\n');
072: if (receiver != null)
073: sb.append("receiver=").append(receiver).append('\n');
074:
075: if (detailed)
076: sb.append("start_time=").append(start_time).append(
077: "\nend_time=").append(end_time).append('\n');
078:
079: if (end_time >= start_time)
080: sb.append("total time=").append((end_time - start_time))
081: .append('\n');
082: else
083: sb.append("total time=n/a\n");
084:
085: if (detailed) {
086: if (network_send > 0)
087: sb.append("network_send=").append(network_send).append(
088: '\n');
089: if (network_recv > 0)
090: sb.append("network_recv=").append(network_recv).append(
091: '\n');
092: }
093:
094: if (network_time > 0)
095: sb.append("network=").append(network_time).append('\n');
096:
097: sb.append("\nDOWN\n-----\n");
098: if (prots != null) {
099: for (int i = 0; i < prots.size(); i++) {
100: p = (Protocol) prots.elementAt(i);
101: key = p.getName();
102: val = (PerfEntry) down.get(key);
103: sb.append(key).append(':').append('\t').append(
104: val.printContents(detailed)).append('\n');
105: }
106: } else
107: for (Iterator it = down.keySet().iterator(); it.hasNext();) {
108: key = (String) it.next();
109: val = (PerfEntry) down.get(key);
110: sb.append(key).append(':').append('\t').append(
111: val.printContents(detailed)).append('\n');
112: }
113:
114: sb.append("\nUP\n-----\n");
115: if (prots != null) {
116: for (int i = prots.size() - 1; i >= 0; i--) {
117: p = (Protocol) prots.elementAt(i);
118: key = p.getName();
119: val = (PerfEntry) up.get(key);
120: sb.append(key).append(':').append('\t').append(
121: val.printContents(detailed)).append('\n');
122: }
123: } else
124: for (Iterator it = up.keySet().iterator(); it.hasNext();) {
125: key = (String) it.next();
126: val = (PerfEntry) up.get(key);
127: sb.append(key).append(':').append('\t').append(
128: val.printContents(detailed)).append('\n');
129: }
130:
131: return sb.toString();
132: }
133:
134: public void setEndTime() {
135: end_time = System.currentTimeMillis();
136: }
137:
138: public void setReceived(String prot_name, int type) {
139: PerfEntry entry = getEntry(prot_name, type);
140: long t = System.currentTimeMillis();
141: if (entry != null)
142: entry.setReceived(t);
143: }
144:
145: public void setDone(String prot_name, int type) {
146: PerfEntry entry = getEntry(prot_name, type);
147: long t = System.currentTimeMillis();
148: if (entry != null)
149: entry.setDone(t);
150: }
151:
152: public void setNetworkSent() {
153: network_send = System.currentTimeMillis();
154: }
155:
156: public void setNetworkReceived() {
157: network_recv = System.currentTimeMillis();
158: if (network_send > 0 && network_recv > network_send)
159: network_time = network_recv - network_send;
160: }
161:
162: /**
163: * Adds a new entry to both hashtables
164: */
165: public void addEntry(String prot_name) {
166: up.put(prot_name, new PerfEntry());
167: down.put(prot_name, new PerfEntry());
168: }
169:
170: public void writeExternal(ObjectOutput out) throws IOException {
171: out.writeObject(sender);
172: out.writeObject(receiver);
173: out.writeLong(start_time);
174: out.writeLong(end_time);
175: out.writeLong(network_send);
176: out.writeLong(network_recv);
177: out.writeLong(network_time);
178: writeHashtable(down, out);
179: writeHashtable(up, out);
180: }
181:
182: public void readExternal(ObjectInput in) throws IOException,
183: ClassNotFoundException {
184: sender = in.readObject();
185: receiver = in.readObject();
186: start_time = in.readLong();
187: end_time = in.readLong();
188: network_send = in.readLong();
189: network_recv = in.readLong();
190: network_time = in.readLong();
191: down = readHashtable(in);
192: up = readHashtable(in);
193: }
194:
195: public long size() {
196: return size;
197: }
198:
199: void writeHashtable(HashMap h, ObjectOutput out) {
200: String key;
201: PerfEntry val;
202:
203: try {
204: if (h == null) {
205: out.writeInt(0);
206: return;
207: }
208: out.writeInt(h.size());
209: for (Iterator it = h.keySet().iterator(); it.hasNext();) {
210: key = (String) it.next();
211: val = (PerfEntry) h.get(key);
212: if (key == null || val == null) {
213: System.err
214: .println("PerfHeader.writeHashtable(): key or val is null");
215: continue;
216: }
217: out.writeObject(key);
218: out.writeObject(val);
219: }
220: } catch (Exception ex) {
221: System.err.println("PerfHeader.writeHashtable(): " + ex);
222: }
223: }
224:
225: HashMap readHashtable(ObjectInput in) {
226: HashMap h = new HashMap();
227: int num = 0;
228: String key;
229: PerfEntry val;
230:
231: try {
232: num = in.readInt();
233: if (num == 0)
234: return h;
235: for (int i = 0; i < num; i++) {
236: key = (String) in.readObject();
237: val = (PerfEntry) in.readObject();
238: h.put(key, val);
239: }
240: } catch (Exception ex) {
241: System.err.println("PerfHeader.readHashtable(): " + ex);
242: }
243:
244: return h;
245: }
246:
247: PerfEntry getEntry(String prot_name, int type) {
248: HashMap tmp = null;
249: PerfEntry entry = null;
250:
251: if (prot_name == null)
252: return null;
253: if (type == UP)
254: tmp = up;
255: else if (type == DOWN)
256: tmp = down;
257: if (tmp == null)
258: return null;
259: entry = (PerfEntry) tmp.get(prot_name);
260: if (entry == null)
261: log.error("PerfHeader.getEntry(): protocol \"" + prot_name
262: + "\" not found");
263: return entry;
264: }
265:
266: public static void main(String[] args) {
267: PerfHeader hdr = new PerfHeader(), hdr2;
268: Message msg;
269: ByteArrayOutputStream out_stream;
270: ByteArrayInputStream in_stream;
271: ObjectOutputStream out;
272: ObjectInputStream in;
273: byte[] out_buf, in_buf;
274:
275: hdr.addEntry("GMS");
276: hdr.addEntry("GMS");
277: hdr.addEntry("FRAG");
278: hdr.addEntry("FRAG");
279: hdr.addEntry("UDP");
280: hdr.addEntry("UDP");
281:
282: msg = new Message();
283: msg.putHeader("PERF", hdr);
284:
285: hdr.setReceived("GMS", PerfHeader.DOWN);
286: Util.sleep(2);
287: hdr.setDone("GMS", PerfHeader.DOWN);
288:
289: hdr.setReceived("FRAG", PerfHeader.DOWN);
290: Util.sleep(20);
291: hdr.setDone("FRAG", PerfHeader.DOWN);
292:
293: long len = msg.size();
294: System.out.println("Size is " + len);
295:
296: hdr.setReceived("UDP", PerfHeader.DOWN);
297: Util.sleep(12);
298: hdr.setDone("UDP", PerfHeader.DOWN);
299:
300: Util.sleep(30);
301:
302: hdr.setReceived("UDP", PerfHeader.UP);
303: hdr.setDone("UDP", PerfHeader.UP);
304:
305: hdr.setReceived("FRAG", PerfHeader.UP);
306: Util.sleep(23);
307: hdr.setDone("FRAG", PerfHeader.UP);
308:
309: hdr.setReceived("GMS", PerfHeader.UP);
310: Util.sleep(3);
311: hdr.setDone("GMS", PerfHeader.UP);
312:
313: hdr.setEndTime();
314:
315: System.out.println(hdr.printContents(true));
316:
317: try {
318: System.out.println("Saving hdr to byte buffer");
319: out_stream = new ByteArrayOutputStream(256);
320: out = new ObjectOutputStream(out_stream);
321: out.writeObject(msg);
322: out_buf = out_stream.toByteArray();
323:
324: System.out.println("Constructing hdr2 from byte buffer");
325: in_buf = out_buf; // ref
326:
327: in_stream = new ByteArrayInputStream(in_buf);
328: in = new ObjectInputStream(in_stream);
329:
330: msg2 = (Message) in.readObject();
331: hdr2 = (PerfHeader) msg2.removeHeader("PERF");
332: System.out.println(hdr2.printContents(true));
333: } catch (Exception ex) {
334: log.error(ex);
335: }
336:
337: }
338:
339: }
340:
341: /**
342: * Entry specific for 1 protocol layer. Records time message was received by that layer and when message was passed on
343: */
344: class PerfEntry implements Externalizable {
345: long received = 0;
346: long done = 0;
347: long total = -1;
348:
349: // Needed for externalization
350: public PerfEntry() {
351:
352: }
353:
354: public long getReceived() {
355: return received;
356: }
357:
358: public long getDone() {
359: return done;
360: }
361:
362: public long getTotal() {
363: return total;
364: }
365:
366: public void setReceived(long r) {
367: received = r;
368: }
369:
370: public void setDone(long d) {
371: done = d;
372: if (received > 0 && done > 0 && done >= received)
373: total = done - received;
374: }
375:
376: public String toString() {
377: if (total >= 0)
378: return "time: " + total;
379: else
380: return "time: n/a";
381: }
382:
383: public String printContents(boolean detailed) {
384: StringBuffer sb = new StringBuffer();
385: if (detailed) {
386: if (received > 0)
387: sb.append("received=").append(received);
388: if (done > 0) {
389: if (received > 0)
390: sb.append(", ");
391: sb.append("done=").append(done);
392: }
393: }
394: if (detailed && (received > 0 || done > 0))
395: sb.append(", ");
396: sb.append(toString());
397: return sb.toString();
398: }
399:
400: public void writeExternal(ObjectOutput out) throws IOException {
401: out.writeLong(received);
402: out.writeLong(done);
403: out.writeLong(total);
404: }
405:
406: public void readExternal(ObjectInput in) throws IOException,
407: ClassNotFoundException {
408: received = in.readLong();
409: done = in.readLong();
410: total = in.readLong();
411: }
412:
413: }
|