/*
* omeis.providers.re.RenderingStats
*
* Copyright 2006 University of Dundee. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package omeis.providers.re;
import java.util.HashMap;
import java.util.Map;
import omeis.providers.re.data.PlaneDef;
/**
* Exposes methods to time the various steps in the rendering process and
* provides a stats report. Every time the
* {@link Renderer#render(PlaneDef) render} method is invoked a new
* <code>RenderingStats</code> object is created that can then be accessed by
* the current {@link RenderingStrategy} to notify start/end times of memory
* allocation, IO, and rendering time.
*
* @author Jean-Marie Burel <a
* href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author <br>
* Andrea Falconi <a
* href="mailto:a.falconi@dundee.ac.uk"> a.falconi@dundee.ac.uk</a>
* @version 2.2 <small> (<b>Internal version:</b> $Revision$ $Date:
* 2005/06/20 11:00:11 $) </small>
* @since OME2.2
*/
public class RenderingStats
{
/** The object whose <code>render</code> method is being timed. */
private Renderer context;
/** Defines the plane that the <code>render</code> is processing. */
private PlaneDef plane;
/** The time that it took to allocate rendering buffers in memory. */
private long mallocTime;
/**
* The time that it took to retrieve the pixels data. This is a map that
* contains an I/O measurement for each wavelength that is being rendered.
* (The key is the wavelength index.)
*/
private Map<Integer, Long> ioTime;
/** The time that it took to transform the pixels data into an image. */
private long renderingTime;
/** The total time a call to the <code>render</code> method takes. */
private long totalTime;
/**
* Helper method to build a string containing the I/O stats.
*
* @return See above.
*/
private String getIoTimeString() {
StringBuffer buf = new StringBuffer();
long total = 0;
Long t;
for (Integer key : ioTime.keySet())
{
t = ioTime.get(key);
total += t;
buf.append("c=");
buf.append(key);
buf.append(";");
buf.append(t);
buf.append(" ");
}
return total + " -> " + buf.toString();
}
/**
* Creates a new instance. This constructor takes the current time, which is
* then used to calculate the total time the <code>render</code> method
* took to execute. The {@link Renderer} takes care of creating this object
* right before the rendering process starts and then calls the
* {@link #stop() stop} method just after the rendering process ends.
*
* @param context
* The object whose <code>render</code> method is being timed.
* Assumed not to be <code>null</code>.
* @param plane
* Defines the plane that the <code>render</code> is
* processing. Assumed not to be <code>null</code>.
*/
public RenderingStats(Renderer context, PlaneDef plane) {
this.context = context;
this.plane = plane;
ioTime = new HashMap<Integer, Long>();
totalTime = System.currentTimeMillis();
mallocTime = 0;
}
/**
* Notifies the start of the allocation of an RGB memory buffer for the
* rendering process.
*
* @see #endMalloc()
*/
public void startMalloc() {
mallocTime -= System.currentTimeMillis();
}
/**
* Notifies the end of the allocation of an RGB memory buffers for the
* rendering process.
*
* @see #startMalloc()
*/
public void endMalloc() {
mallocTime += System.currentTimeMillis();
}
// NOTE: The startMalloc/endMalloc can be called multiple times in the
// HSBStrategy -- if several RGB buffers are allocated.
// So we're tracking the series:
// m0=0, m1=m0-s1, m2=m1+e1, m3=m2-s2, m4=m3+e2, ...
// Where s[i] is the time taken by startMalloc upon allocation of the
// i-th buffer and e[i] is the time taken by endMalloc when allocation
// has completed. So after n allocations, the value of mallocTime is:
// (e1-s1)+(e2-s2)+...+(e[n]-s[n])
/**
* Notifies the start of pixels data retrieval for the specified wavelength
* (channel).
*
* @param c
* The wavelength (channel) index.
* @see #endIO(int)
*/
public void startIO(int c) {
ioTime.put(new Integer(c), new Long(System.currentTimeMillis()));
}
/**
* Notifies the end of pixels data retrieval for the specified wavelength
* (channel).
*
* @param c
* The wavelength (channel) index.
* @see #startIO(int)
*/
public void endIO(int c) {
Integer channel = new Integer(c);
long start = ((Long) ioTime.get(channel)).longValue();
ioTime.put(channel, new Long(System.currentTimeMillis() - start));
}
/**
* Notifies the start of the trasnformation of the raw pixels data.
*
* @see #endRendering()
*/
public void startRendering() {
renderingTime = System.currentTimeMillis();
}
/**
* Notifies the end of the trasnformation of the raw pixels data.
*
* @see #startRendering()
*/
public void endRendering() {
renderingTime = System.currentTimeMillis() - renderingTime;
}
/**
* Notifies this object that the rendering process has finished. The total
* rendering time is computed. That is, the time the <code>render</code>
* method took to execute. The {@link #getStats() getStats} method can now
* be invoked to retrieve the stats report.
*/
public void stop() {
totalTime = System.currentTimeMillis() - totalTime;
}
/**
* Returns a stats report ready to be written to the log file. The report
* includes memory allocation, IO, and rendering times as well as a summary
* of the rendering context in which the call to the <code>
* render</code>
* method took place. This method only provides a meaningful report if it is
* called <i>after </i> the {@link #stop() stop} method.
*
* @return A log message embedding the stats report.
*/
public String getStats()
{
String a = "--------------- RENDERING STATS ---------------\n";
a += String.format(
"CONTEXT ---- OMEIS Pixels ID: %d Plane: %s Type: %s " +
"PlaneData: %s Channels: %d Renderered Image: %s " +
"Color Model: %s Maps: %s\n",
context.getMetadata().getId(),
plane,
context.getPlaneDimsAsString(plane),
context.getPixelsType(),
ioTime.keySet().size(),
context.getImageSize(plane),
context.getRenderingDef().getModel().getValue(),
context.getCodomainChain());
a += String.format(
"TIMES (ms) ---- Memory Allocation: %d I/O: %s " +
"Rendering: %d Total: %d\n",
mallocTime,
getIoTimeString(),
renderingTime,
totalTime);
a += "-----------------------------------------------";
return a;
}
}