/*
  $Id: statsutil.h 4098 2008-11-07 21:33:53Z abehm $

  Copyright (C) 2007 by The Regents of the University of California
	
  Redistribution of this file is permitted under
  the terms of the BSD license
    
  Date: 07/08/2007
  Author: Alexander Behm <abehm (at) ics.uci.edu>
*/

#ifndef _statsutil_h_
#define _statsutil_h_

#include <iostream>
#include <fstream>
#include <sys/time.h>
#include <tr1/unordered_map>
#include <vector>
#include <set>
#include "util/array.h"
 
using namespace std;
using namespace tr1;

// enumerations for time formats
enum TimeFormat {
  TFSEC,
  TFMSEC,
  TFUSEC      
};

typedef struct {
  // valid for all trees
  unsigned dictionarySize;
  unsigned gramLength;
  unsigned maxStrLength;
  unsigned maxChildren;
  unsigned numberFilters;  
  unsigned numberNodes;
  unsigned numberLeafNodes;
  unsigned long treeBytes;
  unsigned long treeNodeBytes;
  unsigned long treeLeafBytes;
  unsigned long invertedListBytes;
  unsigned long totalBytes;
  double buildFilterTreeTime;
} FilterTreeStats;

typedef struct {
  double thresholdTime;
  double preprocessTime;
  double mergeTime;
  double postprocessTime;
  double panicTime;
  double totalSearchTime;
  double candidateStrings;  
  unsigned numberPanics;
  double threshold;  
} SearchStats;

class StatsUtil {
 private:
  // variables for time measurement
  struct timeval t1, t2;
  struct timezone tz;  
  TimeFormat tformat;

 public:
  StatsUtil(TimeFormat t = TFMSEC);

  // variables for storing statistical information
  FilterTreeStats filterTreeStats;
  SearchStats searchStats;
       
  void resetFilterTreeStats(FilterTreeStats* target);
  void resetSearchStats(SearchStats* target);

  void addSearchStats(SearchStats* target);
  void avgSearchStats(SearchStats* target, float n);

  void addFtStats(FilterTreeStats* target);
  void avgFtStats(FilterTreeStats* target, float n);

  // functions for writing stats to file
  void writeSearchStats(ofstream& fp_out, FilterTreeStats* fts, SearchStats* ss);

  // functions for time measurement
  void startTimeMeasurement() { gettimeofday(&t1, &tz); }
  void stopTimeMeasurement() { gettimeofday(&t2, &tz); }
  double getTimeMeasurement(TimeFormat t);
  double getTimeMeasurement();

};

#endif
