All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.counters.render.TabDelimitedPivotTableRenderer Maven / Gradle / Ivy

package com.bigdata.counters.render;

import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;

import com.bigdata.counters.ICounter;
import com.bigdata.counters.IHistoryEntry;
import com.bigdata.counters.query.CSet;
import com.bigdata.counters.query.HistoryTable;
import com.bigdata.counters.query.PivotTable;

/**
 * 
 * @author Bryan Thompson
 * @version $Id$
 */
public class TabDelimitedPivotTableRenderer extends
        PivotTableRenderer {

    public TabDelimitedPivotTableRenderer(PivotTable pt,
            ValueFormatter formatter) {

        super(pt, formatter);
        
    }

    /**
     * Generate the table.
     */
    public void render(final Writer w) throws IOException {

        final HistoryTable t = pt.src;
        
        // the header rows.
        {

            // timestamp column headers.
            w.write(t.units + "\t");
            w.write("timestamp\t");
            for (String s : pt.cnames) {
                // category column headers.
                w.write(s + "\t");
            }
            for (String s : pt.vcols) {
                // performance counter column headers.
                w.write(s + "\t");
            }
            w.write("\n");

        }

        /*
         * FIXME Refactor to use PivotTable and an iterator construct that
         * visits rows.
         */
        
        // for each row in the HistoryTable.
        for (int row = 0; row < t.nrows; row++) {

            /*
             * The time will be zero for the first row and a delta (expressed in
             * the units of the history) for the remaining rows.
             * 
             * Note: The time units are computed using floating point math and
             * then converted to a display form using formatting in order to be
             * able to accurately convey where a sample falls within the
             * granularity of the unit (e.g., early or late in the day).
             */
            final long timestamp = t.getTimestamp(row);

            final String unitStr = XHTMLRenderer.cdata(formatter.unitsFormat
                    .format(((double) timestamp - t
                            .getTimestamp(0/* row */))
                            / t.period));

            final String timeStr = XHTMLRenderer.cdata(formatter.date(timestamp));
            
            /*
             * The set of distinct ordered matched category values in the
             * current row of the history table.
             */
            for(CSet cset : pt.csets) {

                assert cset.cats.length == pt.cnames.length : "cset categories="
                        + Arrays.toString(cset.cats) + " vs "
                        + "category names: " + Arrays.toString(pt.cnames);
                
                /*
                 * Aggregate values for counters in this cset having a value for
                 * each value column in turn.
                 * 
                 * If none of the counters in the cset have a value for the row
                 * in the data table then we will not display a row in the
                 * output table for this cset. However, there can still be other
                 * csets which do select counters in the data table for which
                 * there are samples and that would be displayed under the
                 * output for for their cset.
                 */
                
                final Double[] vals = new Double[pt.vcols.size()];
                
                // #of value columns having a value.
                int ndefined = 0;
                
                // index of the current value column.
                int valueColumnIndex = 0;
                
                // for each value column.
                for (String vcol : pt.vcols) {

                    // #of values aggregated for this value column.
                    int valueCountForColumn = 0;
                    
                    // The aggregated value for this value column.
                    double val = 0d;

                    // consider each counter in the cset for this output row.
                    for (ICounter c : cset.counters) {

                        if (!c.getName().equals(vcol)) {

                            // not for this value column (skip over).
                            continue;

                        }

                        // find the index for that counter in the data table.
                        for (int col = 0; col < t.a.length; col++) {

                            if (c != t.a[col])
                                continue;

                            // get the sample from the data table.
                            final IHistoryEntry e = t.data[row][col];

                            if (e == null) {

                                // no sampled value.
                                continue;
                                
                            }

                            // @todo catch class cast problems and ignore
                            // val.  @todo protected against overflow of
                            // double.
                            val += ((Number) e.getValue()).doubleValue();

                            valueCountForColumn++;
                            
                            /*
                             * The counter appears just once in the data table
                             * so we can stop once we find its index.
                             */
                            break;

                        }

                    } // next counter in CSet.

                    if (valueCountForColumn > 0) {

                        /*
                         * There was at least one sample for the current value
                         * column.
                         */
                        
                        // save the value.
                        vals[valueColumnIndex] = val;

                        // #of non-empty values in this row.
                        ndefined++;

                    }

                    if (log.isDebugEnabled() && valueCountForColumn > 0)
                        log.debug("vcol=" + vcol + ", vcol#="
                                + valueColumnIndex + ", #values="
                                + valueCountForColumn + ", val=" + val);
                    
                    valueColumnIndex++;

                } // next value column.

                if (ndefined == 0) {
                 
                    // no data for this row.
                    continue;
                    
                }

                w.write(unitStr+"\t");

                w.write(timeStr + "\t");

                for (int j = 0; j < pt.cnames.length; j++) {

                    w.write(cset.cats[j] + "\t");

                }

                for (int j = 0; j < vals.length; j++) {

                    final String s = vals[j] == null ? "" : Double
                            .toString(vals[j]);

                    w.write(s + "\t");

                }
                
                w.write("\n");
                
            }

        } // next row.
       
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy