FileDocCategorySizeDatePackage
Points.javaAPI DocApache Lucene 2.1.011877Wed Feb 14 10:46:16 GMT 2007org.apache.lucene.benchmark.byTask.stats

Points.java

package org.apache.lucene.benchmark.byTask.stats;

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;

import org.apache.lucene.benchmark.byTask.tasks.PerfTask;
import org.apache.lucene.benchmark.byTask.utils.Config;
import org.apache.lucene.benchmark.byTask.utils.Format;


/**
 * Test run data points collected as the test proceeds.
 */
public class Points {

  private Config config;
  
  private static final String newline = System.getProperty("line.separator");
  
  // stat points ordered by their start time. 
  // for now we collect points as TaskStats objects.
  // later might optimize to collect only native data.
  private ArrayList points = new ArrayList();

  private int nextTaskRunNum = 0;

  /**
   * Get a textual summary of the benchmark results, average from all test runs.
   */
  static final String OP =          "Operation  ";
  static final String ROUND =       " round";
  static final String RUNCNT =      "   runCnt";
  static final String RECCNT =      "   recsPerRun";
  static final String RECSEC =      "        rec/s";
  static final String ELAPSED =     "  elapsedSec";
  static final String USEDMEM =     "    avgUsedMem";
  static final String TOTMEM =      "    avgTotalMem";
  static final String COLS[] = {
      RUNCNT,
      RECCNT,
      RECSEC,
      ELAPSED,
      USEDMEM,
      TOTMEM
  };

  /**
   * Create a Points statistics object. 
   */
  public Points (Config config) {
    this.config = config;
  }

  private String tableTitle (String longestOp) {
    StringBuffer sb = new StringBuffer();
    sb.append(Format.format(OP,longestOp));
    sb.append(ROUND);
    sb.append(config.getColsNamesForValsByRound());
    for (int i = 0; i < COLS.length; i++) {
      sb.append(COLS[i]);
    }
    return sb.toString(); 
  }
  
  /**
   * Report detailed statistics as a string
   * @return the report
   */
  public Report reportAll() {
    String longestOp = longestOp(points);
    boolean first = true;
    StringBuffer sb = new StringBuffer();
    sb.append(tableTitle(longestOp));
    sb.append(newline);
    int reported = 0;
    for (Iterator it = points.iterator(); it.hasNext();) {
      TaskStats stat = (TaskStats) it.next();
      if (stat.getElapsed()>=0) { // consider only tasks that ended
        if (!first) {
          sb.append(newline);
        }
        first = false;
        String line = taskReportLine(longestOp, stat);
        reported++;
        if (points.size()>2&& reported%2==0) {
          line = line.replaceAll("   "," - ");
        }
        sb.append(line);
      }
    }
    String reptxt = (reported==0 ? "No Matching Entries Were Found!" : sb.toString());
    return new Report(reptxt,reported,reported,points.size());
  }

  /**
   * Report statistics as a string, aggregate for tasks named the same.
   * @return the report
   */
  public Report reportSumByName() {
    // aggregate by task name
    int reported = 0;
    LinkedHashMap p2 = new LinkedHashMap();
    for (Iterator it = points.iterator(); it.hasNext();) {
      TaskStats stat1 = (TaskStats) it.next();
      if (stat1.getElapsed()>=0) { // consider only tasks that ended
        reported++;
        String name = stat1.getTask().getName();
        TaskStats stat2 = (TaskStats) p2.get(name);
        if (stat2 == null) {
          try {
            stat2 = (TaskStats) stat1.clone();
          } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
          }
          p2.put(name,stat2);
        } else {
          stat2.add(stat1);
        }
      }
    }
    // now generate report from secondary list p2    
    return genReportFromList(reported, p2);
  }

  /**
   * Report statistics as a string, aggregate for tasks named the same, and from the same round.
   * @return the report
   */
  public Report reportSumByNameRound() {
    // aggregate by task name and round
    LinkedHashMap p2 = new LinkedHashMap();
    int reported = 0;
    for (Iterator it = points.iterator(); it.hasNext();) {
      TaskStats stat1 = (TaskStats) it.next();
      if (stat1.getElapsed()>=0) { // consider only tasks that ended
        reported++;
        String name = stat1.getTask().getName();
        String rname = stat1.getRound()+"."+name; // group by round
        TaskStats stat2 = (TaskStats) p2.get(rname);
        if (stat2 == null) {
          try {
            stat2 = (TaskStats) stat1.clone();
          } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
          }
          p2.put(rname,stat2);
        } else {
          stat2.add(stat1);
        }
      }
    }
    // now generate report from secondary list p2    
    return genReportFromList(reported, p2);
  }
  
  private String longestOp(Collection c) {
    String longest = OP;
    for (Iterator it = c.iterator(); it.hasNext();) {
      TaskStats stat = (TaskStats) it.next();
      if (stat.getElapsed()>=0) { // consider only tasks that ended
        String name = stat.getTask().getName();
        if (name.length() > longest.length()) {
          longest = name;
        }
      }
    }
    return longest;
  }

  private String taskReportLine(String longestOp, TaskStats stat) {
    PerfTask task = stat.getTask();
    StringBuffer sb = new StringBuffer();
    sb.append(Format.format(task.getName(), longestOp));
    String round = (stat.getRound()>=0 ? ""+stat.getRound() : "-");
    sb.append(Format.formatPaddLeft(round, ROUND));
    sb.append(config.getColsValuesForValsByRound(stat.getRound()));
    sb.append(Format.format(stat.getNumRuns(), RUNCNT)); 
    sb.append(Format.format(stat.getCount() / stat.getNumRuns(), RECCNT));
    long elapsed = (stat.getElapsed()>0 ? stat.getElapsed() : 1); // assume at least 1ms
    sb.append(Format.format(1,(float) (stat.getCount() * 1000.0 / elapsed), RECSEC));
    sb.append(Format.format(2, (float) stat.getElapsed() / 1000, ELAPSED));
    sb.append(Format.format(0, (float) stat.getMaxUsedMem() / stat.getNumRuns(), USEDMEM)); 
    sb.append(Format.format(0, (float) stat.getMaxTotMem() / stat.getNumRuns(), TOTMEM));
    return sb.toString();
  }

  public Report reportSumByPrefix(String prefix) {
    // aggregate by task name
    int reported = 0;
    LinkedHashMap p2 = new LinkedHashMap();
    for (Iterator it = points.iterator(); it.hasNext();) {
      TaskStats stat1 = (TaskStats) it.next();
      if (stat1.getElapsed()>=0 && stat1.getTask().getName().startsWith(prefix)) { // only ended tasks with proper name
        reported++;
        String name = stat1.getTask().getName();
        TaskStats stat2 = (TaskStats) p2.get(name);
        if (stat2 == null) {
          try {
            stat2 = (TaskStats) stat1.clone();
          } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
          }
          p2.put(name,stat2);
        } else {
          stat2.add(stat1);
        }
      }
    }
    // now generate report from secondary list p2    
    return genReportFromList(reported, p2);
  }
  
  public Report reportSumByPrefixRound(String prefix) {
    // aggregate by task name and by round
    int reported = 0;
    LinkedHashMap p2 = new LinkedHashMap();
    for (Iterator it = points.iterator(); it.hasNext();) {
      TaskStats stat1 = (TaskStats) it.next();
      if (stat1.getElapsed()>=0 && stat1.getTask().getName().startsWith(prefix)) { // only ended tasks with proper name
        reported++;
        String name = stat1.getTask().getName();
        String rname = stat1.getRound()+"."+name; // group by round
        TaskStats stat2 = (TaskStats) p2.get(rname);
        if (stat2 == null) {
          try {
            stat2 = (TaskStats) stat1.clone();
          } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
          }
          p2.put(rname,stat2);
        } else {
          stat2.add(stat1);
        }
      }
    }
    // now generate report from secondary list p2    
    return genReportFromList(reported, p2);
  }

  private Report genReportFromList(int reported, LinkedHashMap p2) {
    String longetOp = longestOp(p2.values());
    boolean first = true;
    StringBuffer sb = new StringBuffer();
    sb.append(tableTitle(longetOp));
    sb.append(newline);
    int lineNum = 0;
    for (Iterator it = p2.values().iterator(); it.hasNext();) {
      TaskStats stat = (TaskStats) it.next();
      if (!first) {
        sb.append(newline);
      }
      first = false;
      String line = taskReportLine(longetOp,stat);
      lineNum++;
      if (p2.size()>2&& lineNum%2==0) {
        line = line.replaceAll("   "," - ");
      }
      sb.append(line);
    }
    String reptxt = (reported==0 ? "No Matching Entries Were Found!" : sb.toString());
    return new Report(reptxt,p2.size(),reported,points.size());
  }

  public Report reportSelectByPrefix(String prefix) {
    String longestOp = longestOp(points);
    boolean first = true;
    StringBuffer sb = new StringBuffer();
    sb.append(tableTitle(longestOp));
    sb.append(newline);
    int reported = 0;
    for (Iterator it = points.iterator(); it.hasNext();) {
      TaskStats stat = (TaskStats) it.next();
      if (stat.getElapsed()>=0 && stat.getTask().getName().startsWith(prefix)) { // only ended tasks with proper name
        reported++;
        if (!first) {
          sb.append(newline);
        }
        first = false;
        String line = taskReportLine(longestOp,stat);
        if (points.size()>2&& reported%2==0) {
          line = line.replaceAll("   "," - ");
        }
        sb.append(line);
      }
    }
    String reptxt = (reported==0 ? "No Matching Entries Were Found!" : sb.toString());
    return new Report(reptxt,reported,reported, points.size());
  }

  /**
   * Mark that a task is starting. 
   * Create a task stats for it and store it as a point.
   * @param task the starting task.
   * @return the new task stats created for the starting task.
   */
  public synchronized TaskStats markTaskStart (PerfTask task, int round) {
    TaskStats stats = new TaskStats(task, nextTaskRunNum(), round);
    points.add(stats);
    return stats;
  }
  
  // return next task num
  private synchronized int nextTaskRunNum() {
    return nextTaskRunNum++;
  }
  
  /**
   * mark the end of a task
   */
  public synchronized void markTaskEnd (TaskStats stats, int count) {
    int numParallelTasks = nextTaskRunNum - 1 - stats.getTaskRunNum();
    // note: if the stats were cleared, might be that this stats object is 
    // no longer in points, but this is just ok.
    stats.markEnd(numParallelTasks, count);
  }

  /**
   * Clear all data, prepare for more tests.
   */
  public void clearData() {
    points.clear();
  }

}