/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include "util.h"
#include "Application.h"
#include "DbeSession.h"
#include "CallStack.h"
#include "Command.h"
#include "DataObject.h"
#include "Experiment.h"
#include "ExpGroup.h"
#include "FilterExp.h"
#include "FilterSet.h"
#include "Function.h"
#include "DbeView.h"
#include "PathTree.h"
#include "DataSpace.h"
#include "MemorySpace.h"
#include "IOActivity.h"
#include "HeapActivity.h"
#include "Print.h"
#include "MetricList.h"
#include "Module.h"
#include "Filter.h"
#include "LoadObject.h"
#include "dbe_types.h"
#include "StringBuilder.h"

DbeView::DbeView (Application *_app, Settings *_settings, int _vindex)
{
  init ();
  phaseIdx = 0;
  settings = new Settings (_settings);
  ptree = new PathTree (this);
  dspace = new DataSpace (this);
  memspaces = new Vector<MemorySpace*>;
  iospace = new IOActivity (this);
  heapspace = new HeapActivity (this);
  filters = new Vector<FilterSet*>;
  lo_expands = new Vector<enum LibExpand>;
  cur_filter_str = NULL;
  prev_filter_str = NULL;
  cur_filter_expr = NULL;
  filter_active = false;
  noParFilter = false;
  dataViews = new Vector<Vector<DataView*>*>;
  names_src[0] = NULL;
  names_src[1] = NULL;
  names_src[2] = NULL;
  names_dis[0] = NULL;
  names_dis[1] = NULL;
  names_dis[2] = NULL;
  marks = new Vector<int>;
  marks2dsrc = new Vector<int_pair_t>;
  marks2dsrc_inc = new Vector<int_pair_t>;
  marks2ddis = new Vector<int_pair_t>;
  marks2ddis_inc = new Vector<int_pair_t>;
  app = _app;

  // set the view's index
  vindex = _vindex;

  // clear the precomputed data
  func_data = NULL;
  line_data = NULL;
  pc_data = NULL;
  src_data = NULL;
  dis_data = NULL;
  fitem_data = NULL;
  callers = NULL;
  callees = NULL;
  dobj_data = NULL;
  dlay_data = NULL;
  iofile_data = NULL;
  iovfd_data = NULL;
  iocs_data = NULL;
  heapcs_data = NULL;

  // and clear the selections
  sel_obj = NULL;
  sel_dobj = NULL;
  sel_binctx = NULL;
  func_scope = false;
  lastSelInstr = NULL;
  lastSelFunc = NULL;

  // Initialize index spaces
  int sz = settings->get_IndxTabState ()->size ();
  indxspaces = new Vector<PathTree*>(sz);
  indx_data = new Vector<Hist_data*>(sz);
  sel_idxobj = new Vector<Histable*>(sz);
  for (int i = 0; i < sz; i++)
    {
      PathTree *is = new PathTree (this, i);
      indxspaces->store (i, is);
      indx_data->store (i, NULL);
      sel_idxobj->store (i, NULL);
    }
  reset ();

  lobjectsNoJava = NULL;

  // set lo_expands for already existing LoadObjects
  int idx;
  LoadObject *lo;
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  Vec_loop (LoadObject*, lobjs, idx, lo)
  {
    lo_expands->store (lo->seg_idx, LIBEX_SHOW);
    set_lo_expand (lo->seg_idx, LIBEX_SHOW);
  }
  delete lobjs;
}

DbeView::DbeView (DbeView *dbev, int _vindex)
{
  init ();
  phaseIdx = 0;
  settings = new Settings (dbev->settings);
  ptree = new PathTree (this);
  dspace = new DataSpace (this);
  iospace = new IOActivity (this);
  heapspace = new HeapActivity (this);
  memspaces = new Vector<MemorySpace*>;
  filters = new Vector<FilterSet*>;
  lo_expands = new Vector<enum LibExpand>;
  cur_filter_str = NULL;
  prev_filter_str = NULL;
  cur_filter_expr = NULL;
  noParFilter = false;
  dataViews = new Vector<Vector<DataView*>*>;
  names_src[0] = NULL;
  names_src[1] = NULL;
  names_src[2] = NULL;
  names_dis[0] = NULL;
  names_dis[1] = NULL;
  names_dis[2] = NULL;
  marks = new Vector<int>;
  marks2dsrc = new Vector<int_pair_t>;
  marks2dsrc_inc = new Vector<int_pair_t>;
  marks2ddis = new Vector<int_pair_t>;
  marks2ddis_inc = new Vector<int_pair_t>;
  app = dbev->app;

  // set the view's index
  vindex = _vindex;

  // clear the precomputed data
  func_data = NULL;
  line_data = NULL;
  pc_data = NULL;
  src_data = NULL;
  dis_data = NULL;
  fitem_data = NULL;
  callers = NULL;
  callees = NULL;
  dobj_data = NULL;
  dlay_data = NULL;
  iofile_data = NULL;
  iovfd_data = NULL;
  iocs_data = NULL;
  heapcs_data = NULL;

  // and clear the selections
  sel_obj = NULL;
  sel_dobj = NULL;
  sel_binctx = NULL;
  func_scope = false;
  lastSelInstr = NULL;
  lastSelFunc = NULL;

  // create the vector of IndexSpaces
  int sz = dbev->indxspaces->size ();
  indxspaces = new Vector<PathTree*>(sz);
  indx_data = new Vector<Hist_data*>(sz);
  sel_idxobj = new Vector<Histable*>(sz);
  for (int i = 0; i < sz; i++)
    {
      PathTree *is = new PathTree (this, i);
      indxspaces->store (i, is);
      indx_data->store (i, NULL);
      sel_idxobj->store (i, NULL);
    }
  reset ();

  // now copy the relevant information from the original view
  for (int i = 0; i < dbeSession->nexps (); i++)
    add_experiment (i, dbev->get_exp_enable (i));
  update_advanced_filter ();
  delete lo_expands;
  lo_expands = dbev->lo_expands->copy ();
  lobjectsNoJava = NULL;
}

DbeView::~DbeView ()
{
  delete settings;
  delete ptree;
  delete dspace;
  delete iospace;
  delete heapspace;
  Destroy (memspaces);
  Destroy (filters);
  delete lo_expands;
  free (cur_filter_str);
  free (prev_filter_str);
  delete cur_filter_expr;
  for (int exp_id = 0; exp_id < dataViews->size (); ++exp_id)
    {
      Vector<DataView*> *expDataViewList = dataViews->fetch (exp_id);
      Destroy (expDataViewList);
    }
  delete dataViews;
  delete reg_metrics;
  metrics_lists->destroy ();
  delete metrics_lists;
  metrics_ref_lists->destroy ();
  delete metrics_ref_lists;
  delete derived_metrics;
  delete marks;
  delete marks2dsrc;
  delete marks2dsrc_inc;
  delete marks2ddis;
  delete marks2ddis_inc;

  // Index spaces
  indxspaces->destroy ();
  delete indxspaces;

  indx_data->destroy ();
  delete indx_data;
  delete sel_idxobj;
  delete lobjectsNoJava;
}

void
DbeView::init ()
{
  phaseIdx = 0;
  reg_metrics = new Vector<BaseMetric*>;
  metrics_lists = new Vector<MetricList*>;
  metrics_ref_lists = new Vector<MetricList*>;
  for (int i = 0; i <= MET_HEAP; i++)
    {
      metrics_lists->append (NULL);
      metrics_ref_lists->append (NULL);
    }
  derived_metrics = new DerivedMetrics;
  derived_metrics->add_definition (GTXT ("CPI"), GTXT ("Cycles Per Instruction"), GTXT ("cycles/insts"));
  derived_metrics->add_definition (GTXT ("IPC"), GTXT ("Instructions Per Cycle"), GTXT ("insts/cycles"));
  derived_metrics->add_definition (GTXT ("K_CPI"), GTXT ("Kernel Cycles Per Instruction"), GTXT ("K_cycles/K_insts"));
  derived_metrics->add_definition (GTXT ("K_IPC"), GTXT ("Kernel Instructions Per Cycle"), GTXT ("K_insts/K_cycles"));
}

bool
DbeView::set_libexpand (char *liblist, enum LibExpand flag)
{
  bool changed = settings->set_libexpand (liblist, flag, false);
  // Show/hide performance optimization:
  // No need to call update_lo_expand for every library because dbev->set_libexpand()
  // is called from a loop in Dbe.cc SetLoadObjectState for every load object.
  // It is sufficient to call update_lo_expand() just once at the end of the loop.
  //  At all other places such as er_print.cc which calls specific set_libexpand()
  //  explicitly call update_lo_expands();
  return changed;
}

bool
DbeView::set_libdefaults ()
{
  bool changed = settings->set_libdefaults ();
  if (changed == true)
    update_lo_expands ();
  return changed;
}

void
DbeView::update_lo_expands ()
{
  int index;
  LoadObject *lo;

  // search all load objects
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    // now search the settings list for this one
    enum LibExpand flag = settings->get_lo_setting (lo->get_pathname ());
    set_lo_expand (lo->seg_idx, flag);
  }
  delete lobjs;
}

enum LibExpand
DbeView::get_lo_expand (int idx)
{
  if (idx < lo_expands->size ())
    return lo_expands->get (idx);
  return LIBEX_SHOW;
}

bool
DbeView::set_lo_expand (int idx, enum LibExpand flag)
{
  // LIBRARY_VISIBILITY
  if (flag == LIBEX_HIDE)
    {
      resetShowAll ();
      dbeSession->set_lib_visibility_used ();
    }
  // if no change
  if (idx < lo_expands->size () && flag == get_lo_expand (idx))
    return false;
  setShowHideChanged (); // this is necessary if called from er_print

  // change the flag
  lo_expands->store (idx, flag);

  // and reset the data
  fflush (stderr);
  purge_events ();
  reset_data (true);
  return true;
}

void
DbeView::reset ()
{
  phaseIdx++;

  // reset all the per-experiment arrays
  filters->destroy ();
  lo_expands->reset ();
  free (cur_filter_str);
  cur_filter_str = NULL;
  free (prev_filter_str);
  prev_filter_str = NULL;
  delete cur_filter_expr;
  cur_filter_expr = NULL;
  noParFilter = false;
  for (int exp_id = 0; exp_id < dataViews->size (); ++exp_id)
    {
      Vector<DataView*> *expDataViewList = dataViews->fetch (exp_id);
      if (expDataViewList)
	expDataViewList->destroy ();
    }
  dataViews->destroy ();
  reset_metrics ();

  // now reset any cached data
  reset_data (true);
  ompDisMode = false;
  showAll = true;
  showHideChanged = false;
  newViewMode = false;
}

void
DbeView::reset_data (bool all)
{
  // clear the precomputed data
  if (func_data != NULL)
    {
      delete func_data;
      func_data = NULL;
    }
  if (line_data != NULL)
    {
      delete line_data;
      line_data = NULL;
    }
  if (pc_data != NULL)
    {
      delete pc_data;
      pc_data = NULL;
    }
  if (src_data != NULL)
    {
      delete src_data;
      src_data = NULL;
    }
  if (dis_data != NULL)
    {
      delete dis_data;
      dis_data = NULL;
    }
  if (fitem_data != NULL)
    {
      delete fitem_data;
      fitem_data = NULL;
    }
  if (callers != NULL)
    {
      delete callers;
      callers = NULL;
    }
  if (callees != NULL)
    {
      delete callees;
      callees = NULL;
    }
  if (dobj_data != NULL)
    {
      delete dobj_data;
      dobj_data = NULL;
    }
  if (dlay_data != NULL)
    {
      delete dlay_data;
      dlay_data = NULL;
    }
  if (iofile_data != NULL)
    {
      delete iofile_data;
      iofile_data = NULL;
    }
  if (iovfd_data != NULL)
    {
      delete iovfd_data;
      iovfd_data = NULL;
    }
  if (iocs_data != NULL)
    {
      delete iocs_data;
      iocs_data = NULL;
    }
  if (heapcs_data != NULL)
    {
      delete heapcs_data;
      heapcs_data = NULL;
    }

  // and reset the selections
  if (all)
    {
      sel_obj = NULL;
      sel_dobj = NULL;
      lastSelInstr = NULL;
      lastSelFunc = NULL;
      // Set selected object <Total> if possible
      Function * ft = dbeSession->get_Total_Function ();
      set_sel_obj (ft);
    }
  sel_binctx = NULL;

  dspace->reset ();
  iospace->reset ();
  heapspace->reset ();

  // loop over MemorySpaces, resetting each one
  for (long i = 0, sz = VecSize (memspaces); i < sz; i++)
    {
      MemorySpace *ms = memspaces->get (i);
      ms->reset ();
    }

  // loop over IndexSpaces, resetting cached data
  indx_data->destroy ();
  for (long i = 0, sz = VecSize (indxspaces); i < sz; i++)
    {
      indx_data->store (i, NULL);
      sel_idxobj->store (i, NULL);
    }
}

Vector<BaseMetric*> *
DbeView::get_all_reg_metrics ()
{
  Vector<BaseMetric*> *mlist = dbeSession->get_all_reg_metrics ();
  return mlist;
}

BaseMetric *
DbeView::register_metric_expr (BaseMetric::Type type, char *cmd, char *expr_spec)
{
  BaseMetric *bm = dbeSession->register_metric_expr (type, cmd, expr_spec);
  return bm;
}

Metric *
DbeView::get_compare_metric (Metric *mtr, int groupNum)
{
  if (groupNum == 0 || !mtr->comparable ())
    return new Metric (*mtr);
  ExpGroup *gr = dbeSession->expGroups->get (groupNum - 1);
  char buf[128];
  snprintf (buf, sizeof (buf), NTXT ("EXPGRID==%d"), gr->groupId);
  BaseMetric *bm = register_metric_expr (mtr->get_type (), mtr->get_cmd (), buf);
  Metric *m = new Metric (bm, mtr->get_subtype ());
  m->set_raw_visbits (mtr->get_visbits ());
  if (m->legend == NULL)
    m->legend = dbe_strdup (get_basename (gr->name));
  return m;
}

MetricList *
DbeView::get_metric_ref (MetricType mtype)
{
  if (metrics_ref_lists->fetch (MET_COMMON) == NULL)
    {
      Vector<BaseMetric*> *base_metrics = dbeSession->get_base_reg_metrics ();
      metrics_ref_lists->store (MET_SRCDIS, new MetricList (base_metrics, MET_SRCDIS));
      metrics_ref_lists->store (MET_COMMON, new MetricList (base_metrics, MET_COMMON));
      metrics_ref_lists->store (MET_NORMAL, new MetricList (base_metrics, MET_NORMAL));
      metrics_ref_lists->store (MET_CALL, new MetricList (base_metrics, MET_CALL));
      metrics_ref_lists->store (MET_CALL_AGR, new MetricList (base_metrics, MET_CALL_AGR));
      metrics_ref_lists->store (MET_DATA, new MetricList (base_metrics, MET_DATA));
      metrics_ref_lists->store (MET_INDX, new MetricList (base_metrics, MET_INDX));
      metrics_ref_lists->store (MET_IO, new MetricList (base_metrics, MET_IO));
      metrics_ref_lists->store (MET_HEAP, new MetricList (base_metrics, MET_HEAP));
      delete base_metrics;
    }
  return metrics_ref_lists->fetch (mtype);
}

// logically, the function list must be created first, and it
//	will create the other two;
MetricList *
DbeView::get_metric_list (MetricType mtype)
{
  if (metrics_lists->fetch (MET_COMMON) == NULL)
    {
      Vector<BaseMetric*> *base_metrics = dbeSession->get_base_reg_metrics ();
      metrics_lists->store (MET_SRCDIS, new MetricList (base_metrics, MET_SRCDIS));
      metrics_lists->store (MET_COMMON, new MetricList (base_metrics, MET_COMMON));
      metrics_lists->store (MET_NORMAL, new MetricList (base_metrics, MET_NORMAL));
      metrics_lists->store (MET_CALL, new MetricList (base_metrics, MET_CALL));
      metrics_lists->store (MET_CALL_AGR, new MetricList (base_metrics, MET_CALL_AGR));
      metrics_lists->store (MET_DATA, new MetricList (base_metrics, MET_DATA));
      metrics_lists->store (MET_INDX, new MetricList (base_metrics, MET_INDX));
      metrics_lists->store (MET_IO, new MetricList (base_metrics, MET_IO));
      metrics_lists->store (MET_HEAP, new MetricList (base_metrics, MET_HEAP));
      delete base_metrics;

      // set the defaults
      if (settings->str_dmetrics == NULL)
	settings->str_dmetrics = strdup (Command::DEFAULT_METRICS);
      char *status = setMetrics (settings->str_dmetrics, true);
      if (status != NULL)
	{
	  fprintf (stderr, "XXX setMetrics(\"%s\") failed: %s\n", settings->str_dmetrics, status);
	  abort ();
	}

      // set the default sort
      setSort (settings->str_dsort, MET_NORMAL, true);
    }
  return metrics_lists->fetch (mtype);
}

MetricList *
DbeView::get_metric_list (int dsptype, int subtype)
{
  MetricList *mlist;
  switch (dsptype)
    {
    case DSP_DISASM:
    case DSP_SOURCE:
    case DSP_SOURCE_DISASM:
      mlist = get_metric_list (MET_COMMON);
      mlist = new MetricList (mlist);
      if (subtype != 0)
	{
	  for (long i = 0, sz = mlist->size (); i < sz; i++)
	    {
	      Metric *m = mlist->get (i);
	      if (m->comparable ())
		{
		  Metric *m1 = get_compare_metric (m, subtype);
		  mlist->put (i, m1);
		  delete m;
		}
	    }
	}
      break;
    default:
      mlist = get_metric_list (MET_NORMAL);
      mlist = new MetricList (mlist);
      break;
    }
  return mlist;
}

void
DbeView::reset_metrics ()
{
  for (int i = 0, sz = metrics_lists->size (); i < sz; i++)
    {
      delete metrics_lists->fetch (i);
      metrics_lists->store (i, NULL);
    }
  for (int i = 0, sz = metrics_ref_lists->size (); i < sz; i++)
    {
      delete metrics_ref_lists->fetch (i);
      metrics_ref_lists->store (i, NULL);
    }
}

bool
DbeView::comparingExperiments ()
{
  if (dbeSession->expGroups->size () <= 1)
    return false;
  return 0 != (settings->get_compare_mode () & (CMP_DELTA | CMP_ENABLE | CMP_RATIO));
}

void
DbeView::set_compare_mode (int mode)
{
  if (mode == get_compare_mode ())
    return;
  settings->set_compare_mode (mode);
  if (comparingExperiments ())
    {
      Vector<BaseMetric*> *bm_list = dbeSession->get_base_reg_metrics ();
      for (int i = 0, sz = bm_list->size (); i < sz; i++)
	{
	  BaseMetric *m = bm_list->fetch (i);
	  if (m->get_expr_spec () || !m->comparable ())
	    continue;
	  for (int i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
	    {
	      ExpGroup *gr = dbeSession->expGroups->fetch (i1);
	      char buf[128];
	      snprintf (buf, sizeof (buf), NTXT ("EXPGRID==%d"), gr->groupId);
	      register_metric_expr (m->get_type (), m->get_cmd (), buf);
	    }
	}
    }
  MetricList *mlist = get_metric_list (MET_NORMAL);
  MetricList *gmlist = get_metric_list (MET_CALL);
  MetricList *dmlist = get_metric_list (MET_DATA);
  MetricList *imlist = get_metric_list (MET_INDX);
  if (comparingExperiments ())
    {
      add_compare_metrics (mlist);
      add_compare_metrics (gmlist);
      add_compare_metrics (dmlist);
      add_compare_metrics (imlist);
    }
  else
    {
      remove_compare_metrics (mlist);
      remove_compare_metrics (gmlist);
      remove_compare_metrics (dmlist);
      remove_compare_metrics (imlist);
    }
}

void
DbeView::ifreq (FILE *outfile)
{
  if (!dbeSession->is_ifreq_available ())
    {
      fprintf (outfile, GTXT ("No instruction frequency data available\n"));
      return;
    }
  for (int index = 0; index < filters->size (); index++)
    {
      Experiment *exp = dbeSession->get_exp (index);
      if (exp->broken || !get_exp_enable (index) || !exp->ifreqavail)
	continue;

      // this experiment has the data; print it
      fprintf (outfile,
	       GTXT ("Instruction frequency data from experiment %s\n\n"),
	       exp->get_expt_name ());
      fprintf (outfile, NTXT ("%s"), pr_mesgs (exp->fetch_ifreq (), "", ""));
    }
}

// When adding multiple sub-experiments of an experiment, it is
// not necessary to do the following every-time. It is sufficient to call reset_metrics()
// and call get_metric_ref() and get_metric_list() in the end after all the sub-experiments
// have been added
void
DbeView::add_experiment_epilogue ()
{
  bool flag_LIBEX_HIDE = false;
  bool flag_ShowHideChanged = false;
  Vector<LoadObject*> *lobjs = dbeSession->get_LoadObjects ();
  for (long i = lo_expands->size (), sz = lobjs ? lobjs->size () : 0; i < sz; i++)
    {
      flag_ShowHideChanged = true;
      LoadObject *lo = lobjs->get (i);
      enum LibExpand flag = settings->get_lo_setting (lo->get_pathname ());
      if (flag == LIBEX_HIDE)
	flag_LIBEX_HIDE = true;
      lo_expands->store (lo->seg_idx, flag);
    }
  if (flag_LIBEX_HIDE)
    {
      resetShowAll ();
      dbeSession->set_lib_visibility_used ();
    }
  if (flag_ShowHideChanged)
    {
      setShowHideChanged (); // this is necessary if called from er_print
      purge_events ();
      reset_data (true);
    }
  reset_metrics ();
  (void) get_metric_ref (MET_NORMAL);
  (void) get_metric_ref (MET_CALL);
  (void) get_metric_ref (MET_CALL_AGR);
  (void) get_metric_ref (MET_DATA);
  (void) get_metric_ref (MET_INDX);
  (void) get_metric_ref (MET_IO);
  (void) get_metric_ref (MET_HEAP);
  (void) get_metric_list (MET_NORMAL);
  (void) get_metric_list (MET_CALL);
  (void) get_metric_list (MET_CALL_AGR);
  (void) get_metric_list (MET_DATA);
  (void) get_metric_list (MET_INDX);
  (void) get_metric_list (MET_IO);
  (void) get_metric_list (MET_HEAP);
}

// When adding multiple sub-experiments of an experiment, avoid invoking the steps in
// add_experiment_epilogue() every time and instead call it separately in the end
// after all sub-experiments have been added
void
DbeView::add_subexperiment (int index, bool enabled)
{
  // phaseIdx doesn't change, PathTree can handle adding
  // new experiments without reset

  // Set up the FilterSet for the experiments
  Experiment *exp = dbeSession->get_exp (index);
  FilterSet *filterset = new FilterSet (this, exp);
  filterset->set_enabled (enabled);
  filters->store (index, filterset);

  assert (index == dataViews->size ());
  Vector<DataView*> *expDataViewList = new Vector<DataView*>;
  for (int data_id = 0; data_id < DATA_LAST; ++data_id)
    expDataViewList->append (NULL); //experiment data_id's are not known yet
  dataViews->store (index, expDataViewList);
}

void
DbeView::add_experiment (int index, bool enabled)
{
  // phaseIdx doesn't change, PathTree can handle adding
  // new experiments without reset

  // delete any cached data
  reset_data (true);

  // Set up the FilterSet for the experiments
  Experiment *exp = dbeSession->get_exp (index);
  FilterSet *filterset = new FilterSet (this, exp);
  filterset->set_enabled (enabled);
  filters->store (index, filterset);

  assert (index == dataViews->size ());
  Vector<DataView*> *expDataViewList = new Vector<DataView*>;
  for (int data_id = 0; data_id < DATA_LAST; ++data_id)
    expDataViewList->append (NULL); //experiment data_id's are not known yet
  dataViews->store (index, expDataViewList);

  reset_metrics ();
  (void) get_metric_ref (MET_NORMAL);
  (void) get_metric_ref (MET_CALL);
  (void) get_metric_ref (MET_CALL_AGR);
  (void) get_metric_ref (MET_DATA);
  (void) get_metric_ref (MET_INDX);
  (void) get_metric_ref (MET_IO);
  (void) get_metric_ref (MET_HEAP);
  (void) get_metric_list (MET_NORMAL);
  (void) get_metric_list (MET_CALL);
  (void) get_metric_list (MET_CALL_AGR);
  (void) get_metric_list (MET_DATA);
  (void) get_metric_list (MET_INDX);
  (void) get_metric_list (MET_IO);
  (void) get_metric_list (MET_HEAP);
}

void
DbeView::drop_experiment (int index)
{
  phaseIdx++;
  filters->remove (index);

  // reset any cached data
  reset_data (true);

  Vector<DataView*> *expDataViewList = dataViews->remove (index);
  if (expDataViewList)
    {
      expDataViewList->destroy ();
      delete expDataViewList;
    }
}

bool
DbeView::get_exp_enable (int n)
{
  return filters ? filters->fetch (n)->get_enabled () : true;
}

void
DbeView::set_exp_enable (int n, bool e)
{
  FilterSet *fs = filters->fetch (n);
  if (fs->get_enabled () != e)
    {
      fs->set_enabled (e);
      purge_events (n);
      phaseIdx++;
    }
}

void
DbeView::reset_metric_list (MetricList *mlist, int cmp_mode)
{
  MetricType mtype = mlist->get_type ();
  switch (mtype)
    {
    case MET_NORMAL:
    case MET_COMMON:
      delete metrics_lists->fetch (MET_COMMON);
      metrics_lists->store (MET_COMMON, new MetricList (mlist));
      remove_compare_metrics (metrics_lists->fetch (MET_COMMON));
      break;
      // ignoring the following cases (why?)
    case MET_SRCDIS:
    case MET_CALL:
    case MET_DATA:
    case MET_INDX:
    case MET_CALL_AGR:
    case MET_IO:
    case MET_HEAP:
      break;
    }

  if (cmp_mode != -1)
    {
      settings->set_compare_mode (cmp_mode);
      if (comparingExperiments ())
	add_compare_metrics (mlist);
    }

  switch (mtype)
    {
    case MET_NORMAL:
      delete metrics_lists->fetch (mtype);
      metrics_lists->store (mtype, mlist);
      // fall through to next case
    case MET_COMMON:
      metrics_lists->fetch (MET_SRCDIS)->set_metrics (mlist);
      metrics_lists->fetch (MET_CALL)->set_metrics (mlist);
      metrics_lists->fetch (MET_CALL_AGR)->set_metrics (mlist);
      remove_compare_metrics (metrics_lists->fetch (MET_CALL_AGR));
      metrics_lists->fetch (MET_DATA)->set_metrics (mlist);
      metrics_lists->fetch (MET_INDX)->set_metrics (mlist);
      metrics_lists->fetch (MET_IO)->set_metrics (mlist);
      metrics_lists->fetch (MET_HEAP)->set_metrics (mlist);
      break;
    case MET_CALL_AGR:
      delete metrics_lists->fetch (MET_CALL_AGR);
      metrics_lists->store (MET_CALL_AGR, mlist);
      remove_compare_metrics (mlist);
      break;
    case MET_SRCDIS:
    case MET_CALL:
    case MET_DATA:
    case MET_INDX:
    case MET_IO:
    case MET_HEAP:
      delete metrics_lists->fetch (mtype);
      metrics_lists->store (mtype, mlist);
      break;
    default:
      abort ();
    }
  reset_data (false);
}

void
DbeView::add_compare_metrics (MetricList *mlist)
{
  if (mlist == NULL || !comparingExperiments ())
    return;
  int sort_ref_index = mlist->get_sort_ref_index ();
  Vector<Metric*> *items = mlist->get_items ();
  Vector<Metric*> *newItems = new Vector<Metric*>();
  int mode = get_compare_mode ();
  int cmp_vbits = 0;
  if ((mode & CMP_DELTA) != 0)
    cmp_vbits = VAL_DELTA;
  else if ((mode & CMP_RATIO) != 0)
    cmp_vbits = VAL_RATIO;
  for (long i = 0, sz = items->size (); i < sz; i++)
    {
      Metric *mtr = items->get (i);
      if (sort_ref_index == i)
	mlist->set_sort_ref_index (newItems->size ());
      int vbits = mtr->get_visbits () & ~(VAL_DELTA | VAL_RATIO);
      mtr->set_raw_visbits (vbits);
      if (!mtr->comparable ())
	{
	  newItems->append (mtr);
	  continue;
	}
      if (mtr->get_expr_spec ())
	{
	  if (strcmp (mtr->get_expr_spec (), NTXT ("EXPGRID==1")) != 0)
	    {
	      if ((cmp_vbits & VAL_RATIO) != 0)
		// for ratios, make sure VAL_TIMEVAL is off and VAL_VALUE is on
		mtr->set_raw_visbits ((vbits | VAL_VALUE | cmp_vbits) & ~VAL_TIMEVAL);
	      else
		{
		  int ind = mlist->get_listorder (mtr->get_cmd (), mtr->get_subtype (), NTXT ("EXPGRID==1"));
		  if (ind >= 0)
		    // take VAL_VALUE and VAL_TIMEVAL from base experiment
		    mtr->set_raw_visbits (cmp_vbits
					  | (vbits & ~(VAL_VALUE | VAL_TIMEVAL))
					  | (mlist->get (ind)->get_visbits ()
					     & (VAL_VALUE | VAL_TIMEVAL)));
		  else
		    mtr->set_raw_visbits (cmp_vbits | vbits);
		}
	    }
	  newItems->append (mtr);
	  continue;
	}
      for (long i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
	{
	  Metric *m = get_compare_metric (mtr, i1 + 1);
	  switch (m->get_vtype ())
	    {
	    case VT_LABEL:
	    case VT_ADDRESS:
	    case VT_OFFSET:
	      m->set_raw_visbits (vbits);
	      break;
	    default:
	      if (i1 == 0)
		m->set_raw_visbits (vbits);
	      else if (cmp_vbits == VAL_RATIO
		       && ((vbits & (VAL_VALUE | VAL_TIMEVAL))
			   == (VAL_VALUE | VAL_TIMEVAL)))
		// make ratios for VAL_VALUE only
		m->set_raw_visbits ((vbits | VAL_VALUE | cmp_vbits) & ~VAL_TIMEVAL);
	      else
		m->set_raw_visbits (vbits | cmp_vbits);
	      break;
	    }
	  newItems->append (m);
	}
    }
  items->reset ();
  items->addAll (newItems);
  delete newItems;
  phaseIdx++;
  reset_data (false);
}

MetricList *
DbeView::get_compare_mlist (MetricList *met_list, int grInd)
{
  MetricList *mlist = new MetricList (met_list->get_type ());
  mlist->set_sort_ref_index (met_list->get_sort_ref_index ());
  mlist->set_sort_rev (met_list->get_sort_rev ());

  Vector<Metric*> *items_old = met_list->get_items ();
  for (int i = 0, sz = items_old->size (); i < sz; i++)
    {
      Metric *m = get_compare_metric (items_old->get (i), grInd + 1);
      mlist->append (m);
    }
  return mlist;
}

void
DbeView::remove_compare_metrics (MetricList *mlist)
{
  Vector<Metric*> *items = mlist->get_items ();
  Vector<Metric*> *items_old = items->copy ();
  items->reset ();
  int sort_index = mlist->get_sort_ref_index ();
  mlist->set_sort_ref_index (0);
  for (int i = 0, sz = items_old->size (); i < sz; i++)
    {
      Metric *m = items_old->fetch (i);
      if (m->get_expr_spec () == NULL)
	{
	  // this is a 'non-compare' metric; add it
	  items->append (m);
	  if (sort_index == i)
	    mlist->set_sort_ref_index (items->size () - 1);
	  continue;
	}
      // is the 'non-compare' version of the metric already in the list?
      int ind = mlist->get_listorder (m->get_cmd (), m->get_subtype ());
      if (ind == -1)
	{
	  // not in the list; add it
	  BaseMetric *bm = dbeSession->find_metric (m->get_type (), m->get_cmd (), NULL);
	  Metric *new_met = new Metric (bm, m->get_subtype ());
	  new_met->set_raw_visbits (m->get_visbits () & ~(CMP_DELTA | CMP_RATIO));
	  items->append (new_met);
	  if (sort_index == i)
	    mlist->set_sort_ref_index (items->size () - 1);
	}
      delete m;
    }
  delete items_old;
  reset_data (false);
}

// setMetrics -- set the metric list according to specification
//	The previous sort is preserved, if possible
//	Otherwise, the default sort setting is used
//	Returns NULL if OK, or an error string if not
//YXXX only MET_NORMAL appears to be used... code could be simplified
char *
DbeView::setMetrics (char *mspec, bool fromRcFile)
{
  char *ret;
  MetricType mtype = MET_NORMAL;
  // note that setting the default is done here, while all else is in MetricList
  if (mspec == NULL) abort ();
  if (strcasecmp (mspec, Command::DEFAULT_CMD) == 0)
    {
      mspec = settings->get_default_metrics ();
      fromRcFile = true;
    }
  MetricList *mlist = get_metric_list (mtype);
  mlist = new MetricList (mlist);
  ret = mlist->set_metrics (mspec, fromRcFile, derived_metrics);
  if (ret == NULL)
    {
      switch (mtype)
	{
	case MET_NORMAL:
	case MET_COMMON:
	  delete metrics_lists->fetch (MET_COMMON);
	  metrics_lists->store (MET_COMMON, new MetricList (mlist));
	  break;
	  // ignoring the following cases (why?)
	case MET_SRCDIS:
	case MET_CALL:
	case MET_DATA:
	case MET_INDX:
	case MET_CALL_AGR:
	case MET_IO:
	case MET_HEAP:
	  break;
	}
      add_compare_metrics (mlist);

      //YXXX looks like cut/paste code here, see reset_metric_list()
      switch (mtype)
	{
	case MET_NORMAL:
	  delete metrics_lists->fetch (mtype);
	  metrics_lists->store (mtype, mlist);
	  //YXXX is lack of break intentional?  If so, add comment...
	case MET_COMMON:
	  metrics_lists->fetch (MET_SRCDIS)->set_metrics (mlist);
	  metrics_lists->fetch (MET_CALL)->set_metrics (mlist);
	  metrics_lists->fetch (MET_CALL_AGR)->set_metrics (mlist);
	  remove_compare_metrics (metrics_lists->fetch (MET_CALL_AGR));
	  metrics_lists->fetch (MET_DATA)->set_metrics (mlist);
	  metrics_lists->fetch (MET_INDX)->set_metrics (mlist);
	  metrics_lists->fetch (MET_IO)->set_metrics (mlist);
	  metrics_lists->fetch (MET_HEAP)->set_metrics (mlist);
	  break;
	case MET_CALL_AGR:
	  delete metrics_lists->fetch (MET_CALL_AGR);
	  metrics_lists->store (MET_CALL_AGR, mlist);
	  remove_compare_metrics (mlist);
	  break;
	case MET_SRCDIS:
	case MET_CALL:
	case MET_DATA:
	case MET_INDX:
	case MET_IO:
	case MET_HEAP:
	  delete metrics_lists->fetch (mtype);
	  metrics_lists->store (mtype, mlist);
	  break;
	default:
	  abort ();
	}
      reset_data (false);
    }
  else
    delete mlist;
  return ret;
}


// Set Sort by name (er_print)
char *
DbeView::setSort (char * sort_list, MetricType mtype, bool fromRcFile)
{
  MetricList *mlist = NULL;

  // note that setting the default is done here, while all else is in MetricList
  if ((sort_list == NULL) || (strcmp (sort_list, Command::DEFAULT_CMD) == 0))
    {
      if (settings->str_dsort == NULL)
	settings->str_dsort = strdup (Command::DEFAULT_METRICS);
      sort_list = settings->get_default_sort ();
    }
  mlist = get_metric_list (mtype);

  if (mlist == NULL)
    abort ();

  // set the new sort
  char *ret = mlist->set_sort (sort_list, fromRcFile);
  if (ret != NULL)
    return ret;

  // now resort all cached data
  resortData (mtype);
  return NULL;
}

// Set sort from the visible index (Analyzer)
void
DbeView::setSort (int visindex, MetricType mtype, bool reverse)
{
  MetricList *mlist = get_metric_list (mtype);
  Vector<Metric*> *items = mlist->get_items ();
  if (visindex >= items->size ())
    return;
  mlist->set_sort (visindex, reverse);
  resortData (mtype);
  if (mtype == MET_NORMAL)
    {
      int idx_cc = -1;
      MetricList *mlist_cc = get_metric_list (MET_CALL);
      Vector<Metric*> *items_cc = mlist_cc->get_items ();
      for (int i = 0; i < items_cc->size (); i++)
	{
	  char * name_cc = items_cc->fetch (i)->get_username ();
	  char * name_normal = items->fetch (visindex)->get_username ();
	  if (0 == strncmp (name_cc, name_normal, strlen (name_cc)))
	    {
	      idx_cc = i;
	      break;
	    }
	}
      if (idx_cc != -1)
	{
	  mlist_cc->set_sort (idx_cc, reverse);
	  resortData (MET_CALL);
	  // Change a sort metric for MET_CALL_AGR
	  Metric *m = items_cc->fetch (idx_cc);
	  MetricList *cList = get_metric_list (MET_CALL_AGR);
	  Metric *m1 = cList->find_metric (m->get_cmd (), m->get_subtype ());
	  if (m1)
	    cList->set_sort_metric (m1->get_cmd (), m1->get_subtype (), reverse);
	}
    }
  if (mtype == MET_CALL)
    {
      int idx_norm = -1;
      MetricList *mlist_norm = get_metric_list (MET_NORMAL);
      Vector<Metric*> *items_norm = mlist_norm->get_items ();
      for (int i = 0; i < items_norm->size (); i++)
	{
	  char * name_norm = items_norm->fetch (i)->get_username ();
	  char * name_cc = items->fetch (visindex)->get_username ();
	  if (mlist_norm->get_sort_ref_index () == i
	      && 0 == strncmp (name_norm, name_cc, strlen (name_norm)))
	    {
	      idx_norm = i;
	      break;
	    }
	}
      if (idx_norm == -1)
	{
	  for (int i = 0; i < items_norm->size (); i++)
	    {
	      char * name_norm = items_norm->fetch (i)->get_username ();
	      char * name_cc = items->fetch (visindex)->get_username ();
	      if (0 == strncmp (name_norm, name_cc, strlen (name_norm)))
		{
		  idx_norm = i;
		  break;
		}
	    }
	}
      if (idx_norm != -1)
	{
	  mlist_norm->set_sort (idx_norm, reverse);
	  resortData (MET_NORMAL);
	}
      // Change a sort metric for MET_CALL_AGR
      Metric *m = items->fetch (visindex);
      MetricList *cList = get_metric_list (MET_CALL_AGR);
      Metric *m1 = cList->find_metric (m->get_cmd (), m->get_subtype ());
      if (m1)
	cList->set_sort_metric (m1->get_cmd (), m1->get_subtype (), reverse);
    }
}

void
DbeView::resortData (MetricType mtype)
{
  int idx;
  Hist_data *data;

  MetricList *mlist = get_metric_list (mtype);
  switch (mtype)
    {
    case MET_NORMAL:
      if (func_data != NULL)
	func_data->resort (mlist);
      if (line_data != NULL)
	line_data->resort (mlist);
      if (pc_data != NULL)
	pc_data->resort (mlist);
      break;
    case MET_CALL:
    case MET_CALL_AGR:
      if (fitem_data != NULL)
	fitem_data->resort (mlist);
      if (callers != NULL)
	  callers->resort (mlist);
      if (callees != NULL)
	callees->resort (mlist);
      break;
    case MET_DATA:
      if (dobj_data != NULL)
	dobj_data->resort (mlist);
      if (dlay_data != NULL)
	{
	  delete dlay_data;
	  dlay_data = NULL;
	}
      break;
    case MET_INDX:
      Vec_loop (Hist_data*, indx_data, idx, data)
      {
	if (data)
	  data->resort (mlist);
      }
      break;
    case MET_IO:
      if (iofile_data != NULL)
	iofile_data->resort (mlist);
      if (iovfd_data != NULL)
	iovfd_data->resort (mlist);
      if (iocs_data != NULL)
	  iocs_data->resort (mlist);
      break;
    case MET_HEAP:
      if (heapcs_data != NULL)
	heapcs_data->resort (mlist);
      break;
    case MET_COMMON:
    case MET_SRCDIS:
      break;
    }
}

// Get the sort metric name
char *
DbeView::getSort (MetricType mtype)
{
  MetricList *mlist = get_metric_list (mtype);
  return mlist->get_sort_name ();
}

// Get the sort command (to use for resetting)
char *
DbeView::getSortCmd (MetricType mtype)
{
  MetricList *mlist = get_metric_list (mtype);
  return mlist->get_sort_cmd ();
}

int
DbeView::get_sel_ind (Histable *selObj, int type, int subtype)
{
  Hist_data *data;
  switch (type)
    {
    case DSP_FUNCTION:
      data = func_data;
      break;
    case DSP_LINE:
      data = line_data;
      break;
    case DSP_PC:
      data = pc_data;
      break;
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      data = src_data;
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      data = dis_data;
      break;
    case DSP_DLAYOUT:
      data = dlay_data;
      break;
    case DSP_DATAOBJ:
      data = dobj_data;
      break;
    case DSP_IOACTIVITY:
      data = iofile_data;
      break;
    case DSP_IOVFD:
      data = iovfd_data;
      break;
    case DSP_IOCALLSTACK:
      data = iocs_data;
      break;
    case DSP_HEAPCALLSTACK:
      data = heapcs_data;
      break;
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
      data = get_indxobj_data (subtype);
      break;
    default:
      data = NULL;
      break;
    }
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return -1;
  Vector<Hist_data::HistItem*> *hi_data = data->get_hist_items ();
  for (int i = 0, sz = hi_data->size (); i < sz; i++)
    {
      Hist_data::HistItem *hi = hi_data->fetch (i);
      if (hi->obj == selObj)
	return i;
    }
  return -1;
}

MetricList *
DbeView::get_metric_list (MetricType mtype, bool compare, int gr_num)
{
  MetricList *mlist;
  switch (mtype)
    {
    case MET_COMMON:// comparison mode, src & disasm views
      if (gr_num == 0)
	{// signifies same src file (or load obj) used by all groups
	  // show compare metrics in columns (not in separate source panels)
	  mlist = get_metric_list (MET_NORMAL);
	  break;
	}
      // once source panel per group; get metrics for this group
      mlist = get_metric_list (mtype);
      if (compare)
	{
	  mlist = get_compare_mlist (mlist, gr_num - 1);
	  int mode = get_compare_mode ();
	  if ((mode & (CMP_DELTA | CMP_RATIO)) != 0)
	    {
	      for (long i = 0, sz = mlist->size (); i < sz; i++)
		{
		  Metric *m = mlist->get (i);
		  char *expr_spec = m->get_expr_spec ();
		  if (expr_spec && (strcmp (expr_spec, NTXT ("EXPGRID==1")) != 0))
		    {
		      int vbits = m->get_visbits () & ~(VAL_DELTA | VAL_RATIO);
		      if ((mode & CMP_RATIO) != 0)
			vbits |= VAL_RATIO;
		      else if ((mode & CMP_DELTA) != 0)
			vbits |= VAL_DELTA;
		      m->set_raw_visbits (vbits);
		    }
		}
	    }
	}
      break;
    default:
      mlist = get_metric_list (mtype);
      break;
    }
  return mlist;
}

Hist_data *
DbeView::get_data (MetricList *mlist, Histable *selObj, int type, int subtype)
{
  Hist_data *data;
  switch (type)
    {
    case DSP_FUNCTION:
      delete func_data;
      mlist = new MetricList (mlist);
      func_data = get_hist_data (mlist, Histable::FUNCTION, subtype, Hist_data::ALL);
      return func_data;
    case DSP_LINE:
      delete line_data;
      mlist = new MetricList (mlist);
      line_data = get_hist_data (mlist, Histable::LINE, subtype, Hist_data::ALL);
      return line_data;
    case DSP_PC:
      delete pc_data;
      mlist = new MetricList (mlist);
      pc_data = get_hist_data (mlist, Histable::INSTR, subtype, Hist_data::ALL);
      return pc_data;
    case DSP_DATAOBJ:
      delete dobj_data;
      dobj_data = get_hist_data (mlist, Histable::DOBJECT, subtype,
				 Hist_data::ALL);
      break;
    case DSP_MEMOBJ:
      return get_hist_data (mlist, Histable::MEMOBJ, subtype, Hist_data::ALL);
    case DSP_INDXOBJ:
      data = get_hist_data (mlist, Histable::INDEXOBJ, subtype, Hist_data::ALL);
      indx_data->store (subtype, data);
      return data;
    case DSP_DLAYOUT:
      delete dlay_data;
      marks->reset ();
      data = get_hist_data (mlist, Histable::DOBJECT, subtype,
			    Hist_data::LAYOUT);
      // .. provides metric data for layout
      dlay_data = get_data_space ()->get_layout_data (data, marks,
						      get_thresh_dis ());
      return dlay_data;
    case DSP_CALLER:
      delete callers;
      callers = get_hist_data (mlist, Histable::FUNCTION, subtype,
			       Hist_data::CALLERS, selObj);
      return callers;
    case DSP_CALLEE:
      delete callees;
      callees = get_hist_data (mlist, Histable::FUNCTION, subtype,
			       Hist_data::CALLEES, selObj);
      return callees;
    case DSP_SELF:
      // Center Function item
      delete fitem_data;
      fitem_data = get_hist_data (mlist, Histable::FUNCTION, subtype,
				  Hist_data::SELF, selObj);
      return fitem_data;
    case DSP_SOURCE_V2:
    case DSP_DISASM_V2:
    case DSP_SOURCE:
    case DSP_DISASM:
      {
	// Source or disassembly
	if (selObj == NULL)
	  {
	    error_msg = status_str (DBEVIEW_NO_SEL_OBJ);
	    return NULL;
	  }
	Function *func = (Function *) selObj->convertto (Histable::FUNCTION);
	if (func == NULL)
	  {
	    error_msg = dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
	    return NULL;
	  }
	if (func->flags & FUNC_FLAG_SIMULATED)
	  {
	    error_msg = dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
	    return NULL;
	  }
	if (func->get_name () == NULL)
	  {
	    error_msg = dbe_strdup (GTXT ("Source location not recorded in experiment"));
	    return NULL;
	  }
	Module *module = func->module;
	if (module == NULL || module->get_name () == NULL)
	  {
	    error_msg = dbe_strdup (GTXT ("Object name not recorded in experiment"));
	    return NULL;
	  }
	marks->reset ();
	SourceFile *srcContext = (SourceFile *) selObj->convertto (Histable::SOURCEFILE);
	sel_binctx = func;

	if (func_data == NULL)
	  func_data = get_hist_data (mlist, Histable::FUNCTION, subtype, Hist_data::ALL);

	// for source and disassembly the name needs to be invisible,
	//	but that's handled in the module code
	if (type == DSP_SOURCE || type == DSP_SOURCE_V2)
	  {
	    marks2dsrc->reset ();
	    marks2dsrc_inc->reset ();
	    delete src_data;
	    data = src_data = module->get_data (this, mlist, Histable::LINE,
			      func_data->get_totals ()->value, srcContext, func,
			      marks, get_thresh_src (), get_src_compcom (),
			      get_src_visible (), get_hex_visible (),
			      false, false, marks2dsrc, marks2dsrc_inc);
	  }
	else
	  { /* type == DSP_DISASM */
	    marks2ddis->reset ();
	    marks2ddis_inc->reset ();
	    delete dis_data;
	    data = dis_data = module->get_data (this, mlist, Histable::INSTR,
			      func_data->get_totals ()->value, srcContext, func,
			      marks, get_thresh_dis (), get_dis_compcom (),
			      get_src_visible (), get_hex_visible (),
			      get_func_scope (), false, marks2ddis,
			      marks2ddis_inc);
	  }
	return data;
      }
    default:
      abort ();
    }
  return NULL;
}

Histable *
DbeView::get_compare_obj (Histable *obj)
{
  char *nm;
  switch (obj->get_type ())
    {
    case Histable::LINE:
      nm = obj->get_name ();
      if (nm == NULL)
	break;
      if (dbeSession->comp_dbelines == NULL)
	dbeSession->comp_dbelines = new HashMap<char*, DbeLine*>;
      return dbeSession->comp_dbelines->get (nm, (DbeLine*) obj);
    case Histable::SOURCEFILE:
      nm = obj->get_name ();
      if (nm == NULL)
	break;
      nm = get_basename (nm);
      if (dbeSession->comp_sources == NULL)
	dbeSession->comp_sources = new HashMap<char*, SourceFile*>;
      return dbeSession->comp_sources->get (nm, (SourceFile*) obj);
    default:
      return obj->get_compare_obj ();
    }
  return obj;
}

//
//   get_hist_data() creates a new Hist_data object;
//   it's caller's responsibility to delete it.
Hist_data *
DbeView::get_hist_data (MetricList *mlist_orig, Histable::Type type,
			int subtype, Hist_data::Mode mode, Histable *obj,
			Histable *context, Vector<Histable*> *sel_objs,
			PathTree::PtreeComputeOption flag)
{
  Vector<Histable*> *objs = NULL;
  if (obj != NULL)
    {
      objs = new Vector<Histable*>();
      objs->append (obj);
    }
  Hist_data *res = get_hist_data (mlist_orig, type, subtype, mode, objs, context, sel_objs, flag);
  delete objs;
  return res;
}

Hist_data *
DbeView::get_hist_data (MetricList *mlist_orig, Histable::Type type,
			int subtype, Hist_data::Mode mode,
			Vector<Histable*> *objs,
			Histable *context, Vector<Histable*> *sel_objs,
			PathTree::PtreeComputeOption flag)
{
  MetricList *mlist = new MetricList (mlist_orig);
  /*
   * mlist differs from mlist_orig in two ways:
   * - extra metrics have been added as needed to compute derived metrics
   * - extra metrics have been added as needed to compute time for HWC (time converted) metrics
   *     (We don't drop those extra metrics but we don't display they to user.)
   * - visibility bits have been added for compare mode (e.g., VAL_DELTA or VAL_RATIO)
   *     (We want to preserve those visbits.)
   */
  // loop over mlist to add missing dependencies for derived metrics
  for (long i = 0, sz = mlist->get_items ()->size (); i < sz; i++)
    {
      Metric *m = mlist->get_items ()->fetch (i);
      char *expr_spec = m->get_expr_spec ();
      if (expr_spec && (strcmp (expr_spec, NTXT ("EXPGRID==1")) != 0))
	{
	  int ind = mlist->get_listorder (m->get_cmd (), m->get_subtype (), NTXT ("EXPGRID==1"));
	  if (ind < 0)
	    {
	      BaseMetric *bm1 = dbeSession->find_metric (m->get_type (), m->get_cmd (), NTXT ("EXPGRID==1"));
	      Metric *m1 = new Metric (bm1, m->get_subtype ());
	      m1->set_dmetrics_visbits (VAL_VALUE);
	      mlist->append (m1);
	    }
	}
    }

  for (long i = 0, sz = mlist->get_items ()->size (); i < sz; i++)
    {
      Metric *m = mlist->get_items ()->fetch (i);
      if (m->get_type () == BaseMetric::DERIVED)
	{
	  Definition *def = m->get_definition ();
	  Vector<BaseMetric*> *dependencies = def->get_dependencies ();
	  long *map = def->get_map ();
	  for (long i1 = 0, sz1 = dependencies ? dependencies->size () : 0; i1 < sz1; i1++)
	    {
	      BaseMetric *bm = dependencies->fetch (i1);
	      int ind = mlist->get_listorder (bm->get_cmd (), m->get_subtype (), m->get_expr_spec ());
	      if (ind < 0)
		{
		  BaseMetric *bm1 = dbeSession->find_metric (bm->get_type (), bm->get_cmd (), m->get_expr_spec ());
		  assert (bm1 != NULL);
		  Metric *m1 = new Metric (bm1, m->get_subtype ());
		  m1->set_dmetrics_visbits (VAL_VALUE);
		  ind = mlist->size ();
		  mlist->append (m1);
		}
	      map[i1] = ind;
	    }
	}
      else if (m->get_type () == BaseMetric::HWCNTR)
	{
	  if (m->is_tvisible () && m->get_dependent_bm ())
	    {
	      int ii = mlist->get_listorder (m->get_dependent_bm ()->get_cmd (),
					m->get_subtype (), m->get_expr_spec ());
	      if (ii < 0)
		{
		  BaseMetric *bm1 = dbeSession->find_metric (m->get_type (),
					     m->get_dependent_bm ()->get_cmd (),
					     m->get_expr_spec ());
		  assert (bm1 != NULL);
		  Metric *m1 = new Metric (bm1, m->get_subtype ());
		  m1->set_dmetrics_visbits ((m->get_visbits ()
					     & ~VAL_VALUE) | VAL_TIMEVAL);
		  mlist->append (m1);
		}
	    }
	}
    }

  // compute Hist_data
  Hist_data *data;
  switch (type)
    {
    case Histable::INSTR:
    case Histable::LINE:
      data = ptree->compute_metrics (mlist, type, mode, objs, context, sel_objs);
      break;
    case Histable::FUNCTION:
    case Histable::MODULE:
    case Histable::LOADOBJECT:
      data = ptree->compute_metrics (mlist, type, mode, objs, NULL,
				     sel_objs, flag);
      break;
    case Histable::DOBJECT:
      data = dspace->compute_metrics (mlist, type, mode,
				      objs ? objs->fetch (0) : NULL);
      break;
    case Histable::MEMOBJ:
    case Histable::INDEXOBJ:
      data = indxspaces->get (subtype)->compute_metrics (mlist, type, mode,
							 objs, NULL);
      break;
    case Histable::IOACTFILE:
      if (objs == NULL)
	{
	  data = iofile_data = iospace->compute_metrics (mlist, type, mode,
							 NULL);
	  break;
	}
      else
	{
	  data = iospace->compute_metrics (mlist, type, mode, objs->fetch (0));
	  break;
	}
    case Histable::IOACTVFD:
      if (objs == NULL)
	data = iovfd_data = iospace->compute_metrics (mlist, type, mode, NULL);
      else
	data = iospace->compute_metrics (mlist, type, mode, objs->fetch (0));
      break;
    case Histable::IOCALLSTACK:
      if (objs == NULL)
	data = iocs_data = iospace->compute_metrics (mlist, type, mode, NULL);
      else
	data = iospace->compute_metrics (mlist, type, mode, objs->fetch (0));
      break;
    case Histable::HEAPCALLSTACK:
      if (objs == NULL)
	data = heapcs_data = heapspace->compute_metrics (mlist, type, mode, NULL);
      else
	data = heapspace->compute_metrics (mlist, type, mode, objs->fetch (0));
      break;
    default:
      data = NULL;
      break;
    }
  for (long i = mlist_orig->get_items ()->size (),
	  sz = mlist->get_items ()->size (); i < sz; i++)
    {
      Metric *m = mlist->get_items ()->get (i);
      m->set_dmetrics_visbits (VAL_HIDE_ALL | m->get_visbits ());
    }
  if (data)
    data->nmetrics = mlist_orig->size ();
  return data;
}

char *
DbeView::get_mobj_name (int subtype)
{
  MemorySpace *ms = getMemorySpace (subtype);
  if (ms == NULL)
    ms = addMemorySpace (subtype);
  return ms->getMemObjTypeName ();
}

MemorySpace *
DbeView::getMemorySpace (int subtype)
{
  for (long i = 0, sz = VecSize (memspaces); i < sz; i++)
    {
      MemorySpace *ms = memspaces->get (i);
      if (subtype == ms->getMemObjType ())
	return ms;
    }
  return NULL;
}

MemorySpace *
DbeView::addMemorySpace (int subtype)
{
  MemorySpace *ms = new MemorySpace (this, subtype);
  memspaces->append (ms);
  return ms;
}

Hist_data *
DbeView::get_indxobj_data (int subtype)
{
  if (subtype < 0 || subtype >= indx_data->size ())
    return NULL;
  return indx_data->fetch (subtype);
}

void
DbeView::set_indxobj_sel (int subtype, int sel_ind)
{
  Hist_data *data = get_indxobj_data (subtype);
  if (data == NULL)
    return;
  if (sel_ind >= 0 && sel_ind < data->size ())
    {
      Histable *obj = data->fetch (sel_ind)->obj;
      sel_idxobj->store (subtype, obj);
    }
}

Histable *
DbeView::get_indxobj_sel (int subtype)
{
  return sel_idxobj->fetch (subtype);
}

void
DbeView::addIndexSpace (int subtype)
{
  PathTree *is = new PathTree (this, subtype);
  indxspaces->store (subtype, is);
  indx_data->store (subtype, NULL);
  sel_idxobj->store (subtype, NULL);
  settings->indxobj_define (subtype, false);
}

Histable *
DbeView::get_sel_obj_io (uint64_t id, Histable::Type type)
{
  if (iospace == NULL)
    return NULL;
  Histable *obj = NULL;
  Hist_data *data = NULL;
  switch (type)
    {
    case Histable::IOACTFILE:
      data = iofile_data;
      break;
    case Histable::IOACTVFD:
      data = iovfd_data;
      break;
    case Histable::IOCALLSTACK:
      data = iocs_data;
      break;
    default:
      break;
    }
  if (data == NULL)
    return NULL;

  Vector<Hist_data::HistItem*> *hi_data = data->get_hist_items ();
  int size = hi_data->size ();
  for (int i = 0; i < size; i++)
    {
      Hist_data::HistItem *hi = hi_data->fetch (i);
      if (hi->obj != NULL && (uint64_t) hi->obj->id == id)
	{
	  obj = hi->obj;
	  break;
	}
    }
  return obj;
}

Histable *
DbeView::get_sel_obj_heap (uint64_t id)
{
  if (heapspace == NULL || heapcs_data == NULL)
    return NULL;
  Histable *obj = NULL;
  Hist_data *data = heapcs_data;
  Vector<Hist_data::HistItem*> *hi_data = data->get_hist_items ();
  int size = hi_data->size ();
  for (int i = 0; i < size; i++)
    {
      Hist_data::HistItem *hi = hi_data->fetch (i);
      if ((hi->obj != NULL) && ((uint64_t) hi->obj->id) == id)
	{
	  obj = hi->obj;
	  break;
	}
    }
  return obj;
}

CStack_data *
DbeView::get_cstack_data (MetricList *mlist)
{
  return ptree->get_cstack_data (mlist);
}

Stats_data *
DbeView::get_stats_data (int index)
{
  DataView *packets = get_filtered_events (index, DATA_SAMPLE);
  if (packets == NULL)
    return NULL;
  return new Stats_data (packets);
}

Ovw_data *
DbeView::get_ovw_data (int index)
{
  DataView *packets = get_filtered_events (index, DATA_SAMPLE);
  Experiment* exp = dbeSession->get_exp (index);
  hrtime_t starttime = 0;
  if (exp != NULL)
    starttime = exp->getStartTime ();
  if (packets == NULL)
    return NULL;
  return new Ovw_data (packets, starttime);
}

char *
DbeView::set_filter (const char *filter_spec)
{
  if (dbe_strcmp (filter_spec, cur_filter_str) == 0)  // Nothing was changed
    return NULL;

  // if string is NULL, delete the filter
  if (filter_spec == NULL)
    {
      if (cur_filter_str)
	{
	  free (cur_filter_str);
	  cur_filter_str = NULL;
	}
      if (cur_filter_expr)
	{
	  delete cur_filter_expr;
	  cur_filter_expr = NULL;
	}
      noParFilter = false;
      purge_events ();
      reset_data (false);
      return NULL;
    }

  // process the filter
  Expression *expr = dbeSession->ql_parse (filter_spec);
  if (expr == NULL)
    return dbe_sprintf (GTXT ("Invalid filter specification `%s'\n"), filter_spec);

  if (dbe_strcmp (filter_spec, "1") == 0)
    noParFilter = false;
  else if (sel_obj != NULL)
    if (sel_obj->get_type () == Histable::LINE)
      if (expr->verifyObjectInExpr (sel_obj))
	noParFilter = true;

  // valid new filter
  if (cur_filter_str != NULL)
    {
      free (prev_filter_str);
      prev_filter_str = dbe_strdup (cur_filter_str);
    }
  free (cur_filter_str);
  cur_filter_str = dbe_strdup (filter_spec);
  delete cur_filter_expr;
  cur_filter_expr = expr;
  purge_events ();
  reset_data (false);
  return NULL;
}

FilterExp *
DbeView::get_FilterExp (Experiment *exp)
{
  if (cur_filter_expr == NULL)
    return NULL;
  Expression::Context *ctx = new Expression::Context (this, exp);
  return new FilterExp (cur_filter_expr, ctx, noParFilter);
}

char *
DbeView::get_filter ()
{
  return dbe_strdup (cur_filter_str);
}

FilterSet *
DbeView::get_filter_set (int n)
{
  fflush (stderr);
  if (n >= filters->size ())
    return NULL;
  return ( filters->fetch (n));
}

Vector<FilterNumeric*> *
DbeView::get_all_filters (int nexp)
{
  FilterSet *fs = get_filter_set (nexp);
  return fs ? fs->get_all_filters () : NULL;
}

FilterNumeric *
DbeView::get_FilterNumeric (int nexp, int idx)
{
  FilterSet *fs = get_filter_set (nexp);
  return fs ? fs->get_filter (idx) : NULL;
}

void
DbeView::backtrack_filter()
{
    if (prev_filter_str != NULL)
       set_filter(prev_filter_str);
    else set_filter("1"); // reset

}

void
DbeView::update_advanced_filter ()
{
  char *s = get_advanced_filter ();
  if (dbe_strcmp (s, cur_filter_str))
    {
      phaseIdx++;
      char *err_msg = set_filter (s);
      if (err_msg)
	{
#ifdef DEBUG
	  fprintf (stderr, NTXT ("ERROR: Advanced Filter: '%s'\n"), err_msg);
#endif
	}
    }
  free (s);
}

bool
DbeView::set_pattern (int n, Vector<char *> *pattern_str, bool *error)
{
  Vector<FilterNumeric*> *filts = get_all_filters (n);

  bool ret = false;
  *error = false;
  int imax = pattern_str->size ();
  if (imax > filts->size ())
    imax = filts->size ();
  for (int i = 0; i < imax; i++)
    {
      FilterNumeric *f = filts->fetch (i);
      char *s = pattern_str->fetch (i);
      if (s == NULL)
	continue;
      if (f->set_pattern (s, error))
	ret = true;
    }

  if (ret || cur_filter_expr)
    {
      update_advanced_filter ();
      filter_active = true;
    }
  return ret;
}

static void
append_experiments (StringBuilder *sb, int first, int last)
{
  if (first == -1)
    return;
  if (sb->length () != 0)
    sb->append (NTXT (" || "));
  sb->append ('(');
  if (first == last)
    {
      sb->append (NTXT ("EXPID=="));
      sb->append (first);
    }
  else
    {
      sb->append (NTXT ("EXPID>="));
      sb->append (first);
      sb->append (NTXT (" && EXPID<="));
      sb->append (last);
    }
  sb->append (')');
}

char *
DbeView::get_advanced_filter ()
{
  StringBuilder sb;
  bool wasFalse = false;
  int first = -1, last = -1;
  for (int n = 0, nexps = dbeSession->nexps (); n < nexps; n++)
    {
      FilterSet *fs = get_filter_set (n);
      char *s = fs->get_advanced_filter ();
      if (s)
	{
	  if (streq (s, NTXT ("1")))
	    {
	      last = n + 1;
	      if (first == -1)
		first = last;
	      continue;
	    }
	  append_experiments (&sb, first, last);
	  first = -1;
	  if (streq (s, NTXT ("0")))
	    {
	      wasFalse = true;
	      continue;
	    }
	  if (sb.length () != 0)
	    sb.append (NTXT (" || "));
	  sb.append (NTXT ("(EXPID=="));
	  sb.append (n + 1);
	  sb.append (NTXT (" && ("));
	  sb.append (s);
	  free (s);
	  sb.append (NTXT ("))"));
	}
      else
	{
	  last = n + 1;
	  if (first == -1)
	    first = last;
	}
    }
  if (first != 1)
    {
      append_experiments (&sb, first, last);
      first = -1;
    }
  if (sb.length () == 0)
    sb.append (wasFalse ? '0' : '1');
  else
    append_experiments (&sb, first, last);
  return sb.toString ();
}

bool
DbeView::set_pattern (int m, char *pattern)
{
  bool error = false;

  // Store original setting in case of error
  int nexps = dbeSession->nexps ();
  int orig_phaseIdx = phaseIdx;
  bool *orig_enable = new bool[nexps];
  char **orig_pattern = new char*[nexps];
  for (int i = 0; i < nexps; i++)
    {
      orig_pattern[i] = get_FilterNumeric (i, m)->get_pattern ();
      orig_enable[i] = get_exp_enable (i);
      set_exp_enable (i, false);
    }

  // Copy the pattern so that we could safely modify it
  char *buf = dbe_strdup (pattern);
  FilterNumeric *fexp = NULL;
  char *pb, *pe;
  pb = pe = buf;
  for (bool done = false; !done; pe++)
    {
      if (*pe == ':')
	{
	  // experiment filter;
	  *pe = '\0';
	  fexp = new FilterNumeric (NULL, NULL, NULL);
	  fexp->set_range (1, nexps, nexps);
	  fexp->set_pattern (pb, &error);
	  if (error)
	    break;
	  pb = pe + 1;
	}
      else if (*pe == '+' || *pe == '\0')
	{
	  // entity filter
	  if (*pe == '\0')
	    done = true;
	  else
	    *pe = '\0';
	  for (int i = 0; i < nexps; i++)
	    {
	      if (!fexp || fexp->is_selected (i + 1))
		{
		  FilterNumeric *f = get_FilterNumeric (i, m);
		  f->set_pattern (pb, &error);
		  if (error)
		    break;
		  set_exp_enable (i, true);
		}
	    }
	  if (error)
	    break;
	  delete fexp;
	  fexp = NULL;
	  pb = pe + 1;
	}
    }

  if (error)
    {
      for (int i = 0; i < nexps; i++)
	{
	  bool err;
	  set_exp_enable (i, orig_enable[i]);
	  FilterNumeric *f = get_FilterNumeric (i, m);
	  f->set_pattern (orig_pattern[i], &err);
	  free (orig_pattern[i]);
	}
      phaseIdx = orig_phaseIdx;
    }
  else
    {
      update_advanced_filter ();
      filter_active = true;
    }
  delete[] orig_enable;
  delete[] orig_pattern;
  delete fexp;
  free (buf);
  return !error;
}

void
DbeView::set_view_mode (VMode newmode)
{
  if (newmode != settings->get_view_mode ())
    {

      // For OpenMP, the expert mode path-tree is already present with the user mode
      // No need to increase the phaseIdx to trigger recomputation of path-tree
      // if we toggle between user and expert modes
      if (!(dbeSession->is_omp_available ()
	    && ((newmode == VMODE_EXPERT
		 && settings->get_view_mode () == VMODE_USER)
		|| (newmode == VMODE_USER
		    && settings->get_view_mode () == VMODE_EXPERT))))
	phaseIdx++; // For all other cases
      setNewViewMode ();
      settings->set_view_mode (newmode);
    }
}

Cmd_status
DbeView::set_view_mode (char *str, bool fromRC)
{
  VMode old = settings->get_view_mode ();
  Cmd_status ret = settings->set_view_mode (str, fromRC);
  if (old != settings->get_view_mode ())
    phaseIdx++;
  return ret;
}

Cmd_status
DbeView::set_en_desc (char *str, bool fromRC)
{
  // Tell the session
  Settings *s = dbeSession->get_settings ();
  s->set_en_desc (str, fromRC);

  // and tell our settings
  return settings->set_en_desc (str, fromRC);
}

// Get processor stats messages
char *
DbeView::get_processor_msg (int type)
{
  if (ptree == NULL)  // if no PathTree, no messages
    return NULL;

  StringBuilder sb;
  Emsg *m = (type == PSTAT_MSG) ? ptree->fetch_stats () : ptree->fetch_warnings ();
  for (; m != NULL; m = m->next)
    {
      char* newmsg = m->get_msg ();
      sb.append (newmsg);
      sb.append ("\n");
    }

  if (type == PSTAT_MSG)
    ptree->delete_stats ();
  else
    ptree->delete_warnings ();
  return (sb.length () > 0) ? sb.toString () : NULL;
}

void
DbeView::dump_nodes (FILE *outfile)
{
  FILE *f = (outfile == NULL ? stderr : outfile);
  ptree->print (f);
}

// Dump the clock profile events
void
DbeView::dump_profile (FILE *out_file)
{
  for (int idx = 0; idx < dbeSession->nexps (); idx++)
    {
      Experiment *exp = dbeSession->get_exp (idx);
      VMode view_mode = get_view_mode ();
      char * stateNames [/*LMS_NUM_STATES*/] = LMS_STATE_STRINGS;

      // Process clock profile date
      DataView *packets = get_filtered_events (idx, DATA_CLOCK);
      if (packets && packets->getSize () != 0)
	{
	  hrtime_t start = exp->getStartTime ();
	  fprintf (out_file,
		   GTXT ("\nTotal Clock Profiling Packets:  %d Experiment:  %s\n"),
		   (int) packets->getSize (), exp->get_expt_name ());
	  for (long i = 0; i < packets->getSize (); i++)
	    {
	      hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
	      hrtime_t ts = expr_ts - start;

	      // get the properties from the packet
	      uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
	      uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
	      int mstate = (int) packets->getIntValue (PROP_MSTATE, i);
	      int nticks = (int) packets->getIntValue (PROP_NTICK, i);

	      char *sname;
	      char buf[1024];
	      if (mstate >= 0 && mstate < LMS_NUM_STATES)
		  sname = stateNames[mstate];
	      else
		{
		  snprintf (buf, sizeof (buf), NTXT ("Unexpected mstate = %d"), mstate);
		  sname = buf;
		}

	      // get the stack   IGNORE HIDE
	      Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
	      int stack_size = stack->size ();

	      // print the packet header with the count of stack frames
	      fprintf (out_file,
		       GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n"),
		       i, expr_ts, ts / NANOSEC, ts % NANOSEC,
		       expr_ts / NANOSEC, expr_ts % NANOSEC,
		       thrid, cpuid, stack_size);
	      fprintf (out_file,
		       GTXT ("    mstate = %d (%s), nticks = %d\n"),
		       mstate, sname, nticks);

	      // dump the callstack
	      for (int j = stack_size - 1; j >= 0; j--)
		{
		  Histable *frame = stack->fetch (j);
		  fprintf (out_file, GTXT ("          %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
		}
	      fprintf (out_file, "\n");
	    }
	}
      else
	fprintf (out_file,
		 GTXT ("\nNo Clock Profiling Packets in Experiment:  %s\n"),
		 exp->get_expt_name ());
    }
}

// Dump the sync trace events
void
DbeView::dump_sync (FILE *out_file)
{
  for (int idx = 0; idx < dbeSession->nexps (); idx++)
    {
      Experiment *exp = dbeSession->get_exp (idx);
      VMode view_mode = get_view_mode ();

      // Process heap trace date
      DataView *packets = get_filtered_events (idx, DATA_SYNCH);
      if (packets && packets->getSize () != 0)
	{
	  hrtime_t start = exp->getStartTime ();
	  fprintf (out_file,
		   GTXT ("\nTotal Synctrace Packets:  %d Experiment:  %s\n"),
		   (int) packets->getSize (), exp->get_expt_name ());

	  for (long i = 0; i < packets->getSize (); i++)
	    {
	      hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
	      hrtime_t ts = expr_ts - start;

	      // get the properties from the packet
	      uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
	      uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
	      uint64_t syncobj = (uint64_t) packets->getLongValue (PROP_SOBJ, i);
	      hrtime_t syncrtime = (uint64_t) packets->getLongValue (PROP_SRQST, i);
	      hrtime_t syncdelay = expr_ts - syncrtime;

	      // get the stack   IGNORE HIDE
	      Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
	      int stack_size = stack->size ();

	      // print the packet header with the count of stack frames
	      fprintf (out_file,
		       GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n"),
		       i, expr_ts, ts / NANOSEC, ts % NANOSEC,
		       expr_ts / NANOSEC, expr_ts % NANOSEC, thrid,
		       cpuid, stack_size);
	      fprintf (stderr,
		       GTXT ("       synchronization object @ 0x%016llx;  synchronization delay  %3lld.%09lld\n"),
		       (unsigned long long) syncobj, (long long) (syncdelay / NANOSEC), (long long) (syncdelay % NANOSEC));

	      // dump the callstack
	      for (int j = stack_size - 1; j >= 0; j--)
		{
		  Histable *frame = stack->fetch (j);
		  fprintf (out_file, GTXT ("          %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
		}
	      fprintf (out_file, "\n");
	    }
	}
      else
	fprintf (out_file, GTXT ("\nNo Synctrace Packets in Experiment:  %s\n"),
		 exp->get_expt_name ());
    }
}

// Dump the IO trace events
void
DbeView::dump_iotrace (FILE *out_file)
{
  for (int idx = 0; idx < dbeSession->nexps (); idx++)
    {
      Experiment *exp = dbeSession->get_exp (idx);
      VMode view_mode = get_view_mode ();

      // Process IO trace date
      DataView *packets = get_filtered_events (idx, DATA_IOTRACE);
      if (packets && packets->getSize () != 0)
	{
	  hrtime_t start = exp->getStartTime ();
	  fprintf (out_file,
		   GTXT ("\nTotal IO trace Packets:  %d Experiment:  %s\n"),
		   (int) packets->getSize (), exp->get_expt_name ());
	  for (long i = 0; i < packets->getSize (); i++)
	    {
	      hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
	      hrtime_t ts = expr_ts - start;

	      // get the properties from the packet
	      uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
	      uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
	      IOTrace_type iotrtype = (IOTrace_type) packets->getIntValue (PROP_IOTYPE, i);
	      uint32_t iofd = (uint32_t) packets->getIntValue (PROP_IOFD, i);
	      uint64_t ionbyte = (uint64_t) packets->getIntValue (PROP_IONBYTE, i);
	      hrtime_t iorqst = (hrtime_t) packets->getLongValue (PROP_IORQST, i);
	      uint32_t ioofd = (uint32_t) packets->getIntValue (PROP_IOOFD, i);
	      FileSystem_type iofstype = (FileSystem_type) packets->getIntValue (PROP_CPUID, i);
	      int64_t iovfd = (int64_t) packets->getIntValue (PROP_IOVFD, i);

	      char *fName = NULL;
	      StringBuilder *sb = (StringBuilder*) packets->getObjValue (PROP_IOFNAME, i);
	      if (sb != NULL && sb->length () > 0)
		fName = sb->toString ();

	      // get the stack  IGNORE HIDE
	      Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
	      int stack_size = stack->size ();
	      const char *iotrname;
	      switch (iotrtype)
		{
		case READ_TRACE:
		  iotrname = "ReadTrace";
		  break;
		case WRITE_TRACE:
		  iotrname = "WriteTrace";
		  break;
		case OPEN_TRACE:
		  iotrname = "OpenTrace";
		  break;
		case CLOSE_TRACE:
		  iotrname = "CloseTrace";
		  break;
		case OTHERIO_TRACE:
		  iotrname = "OtherIOTrace";
		  break;
		case READ_TRACE_ERROR:
		  iotrname = "ReadTraceError";
		  break;
		case WRITE_TRACE_ERROR:
		  iotrname = "WriteTraceError";
		  break;
		case OPEN_TRACE_ERROR:
		  iotrname = "OpenTraceError";
		  break;
		case CLOSE_TRACE_ERROR:
		  iotrname = "CloseTraceError";
		  break;
		case OTHERIO_TRACE_ERROR:
		  iotrname = "OtherIOTraceError";
		  break;
		default:
		  iotrname = "UnknownIOTraceType";
		  break;
		}

	      // print the packet header with the count of stack frames
	      fprintf (out_file,
		       GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n"),
		       i, expr_ts, ts / NANOSEC, ts % NANOSEC,
		       expr_ts / NANOSEC, expr_ts % NANOSEC,
		       thrid, cpuid, stack_size);
	      fprintf (out_file,
		       GTXT ("    %s: fd = %d, ofd = %d, vfd = %lld, fstype = %d, rqst =  %3lld.%09lld\n"),
		       iotrname, (int) iofd, (int) ioofd, (long long) iovfd,
		       (int) iofstype, (long long) (iorqst / NANOSEC),
		       (long long) (iorqst % NANOSEC));
	      fprintf (out_file, GTXT ("    filename = `%s', nbytes = %d\n"),
		       STR (fName), (int) ionbyte);
	      free (fName);

	      // dump the callstack
	      for (int j = stack_size - 1; j >= 0; j--)
		{
		  Histable *frame = stack->fetch (j);
		  fprintf (out_file, GTXT ("          %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
		}
	      fprintf (out_file, "\n");
	    }
	}
      else
	fprintf (out_file, GTXT ("\nNo IO trace Packets in Experiment:  %s\n"),
		 exp->get_expt_name ());
    }
}

// Dump the HWC Profiling events
void
DbeView::dump_hwc (FILE *out_file)
{
  for (int idx = 0; idx < dbeSession->nexps (); idx++)
    {
      Experiment *exp = dbeSession->get_exp (idx);
      VMode view_mode = get_view_mode ();

      // Dump HWC profiling data
      DataView *packets = get_filtered_events (idx, DATA_HWC);
      if (packets && packets->getSize () != 0)
	{
	  hrtime_t start = exp->getStartTime ();
	  fprintf (out_file,
		   GTXT ("\nTotal HW Counter Profiling Packets:  %d Experiment:  %s\n"),
		   (int) packets->getSize (), exp->get_expt_name ());
	  for (long i = 0; i < packets->getSize (); i++)
	    {
	      const char * hwc_name;
	      hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
	      hrtime_t ts = expr_ts - start;
	      uint32_t tag = (uint32_t) packets->getIntValue (PROP_HWCTAG, i);
	      uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
	      uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);

	      // This will work even with a different counter in every packet.
	      if (tag < 0 || tag >= MAX_HWCOUNT
		  || !exp->coll_params.hw_aux_name[tag])
		// if the packet has an invalid tag, use <invalid> as its name
		hwc_name = "<invalid>";
	      else
		hwc_name = exp->coll_params.hw_aux_name[tag];
	      int64_t mval = packets->getLongValue (PROP_HWCINT, i);
	      const char *err = HWCVAL_HAS_ERR (mval) ? " $$" : "";

	      // get the stack IGNORE HIDE
	      Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
	      int stack_size = stack->size ();

	      // print the packet header with the count of stack frames
	      fprintf (out_file,
		       GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n       count = %10lld (0x%016llx), tag = %d (%s)%s\n"),
		       (long) i, (long long) expr_ts,
		       (long long) (ts / NANOSEC), (long long) (ts % NANOSEC),
		       (long long) (expr_ts / NANOSEC), (long long) (expr_ts % NANOSEC),
		       (int) thrid, (int) cpuid, (int) stack_size,
		       (long long) (HWCVAL_CLR_ERR (mval)), (long long) mval,
		       (int) tag, hwc_name, err);

	      //  dump extended HWC packets values
	      uint64_t va = (uint64_t) packets->getLongValue (PROP_VADDR, i);
	      uint64_t pa = (uint64_t) packets->getLongValue (PROP_PADDR, i);
	      fprintf (out_file, GTXT ("       va = 0x%016llx, pa = 0x%016llx\n"),
		       (unsigned long long) va, (unsigned long long) pa);

	      // dump the callstack
	      for (int j = stack_size - 1; j >= 0; j--)
		{
		  Histable *frame = stack->fetch (j);
		  fprintf (out_file, GTXT ("          %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
		}
	      fprintf (out_file, "\n");
	    }
	}
      else
	fprintf (out_file,
		 GTXT ("\nNo HWC Profiling Packets in Experiment:  %s\n"),
		 exp->get_expt_name ());
    }
}

// Dump the Heap events
void
DbeView::dump_heap (FILE *out_file)
{
  char *heapstrings[] = HEAPTYPE_STATE_USTRINGS;
  for (int idx = 0; idx < dbeSession->nexps (); idx++)
    {
      Experiment *exp = dbeSession->get_exp (idx);
      VMode view_mode = get_view_mode ();

      // Process heap trace date
      DataView *packets = get_filtered_events (idx, DATA_HEAP);
      if (packets && packets->getSize () != 0)
	{
	  hrtime_t start = exp->getStartTime ();
	  fprintf (out_file, GTXT ("\nTotal Heaptrace Packets:  %d Experiment:  %s\n"),
		   (int) packets->getSize (), exp->get_expt_name ());
	  for (long i = 0; i < packets->getSize (); i++)
	    {
	      hrtime_t expr_ts = (hrtime_t) packets->getLongValue (PROP_TSTAMP, i);
	      hrtime_t ts = expr_ts - start;

	      // get the properties from the packet
	      uint32_t thrid = (uint32_t) packets->getIntValue (PROP_THRID, i);
	      uint32_t cpuid = (uint32_t) packets->getIntValue (PROP_CPUID, i);
	      uint32_t heaptype = (uint32_t) packets->getIntValue (PROP_HTYPE, i);
	      uint64_t heapsize = (uint64_t) packets->getULongValue (PROP_HSIZE, i);
	      uint64_t heapvaddr = (uint64_t) packets->getULongValue (PROP_HVADDR, i);
	      uint64_t heapovaddr = (uint64_t) packets->getULongValue (PROP_HOVADDR, i);
	      if (heaptype == MUNMAP_TRACE)
		{
		  heapsize = (uint64_t) packets->getULongValue (PROP_HOVADDR, i);
		  heapovaddr = 0;
		}

	      // get the stack  IGNORE HIDE
	      Vector<Histable*> *stack = getStackPCs (view_mode, packets, i);
	      int stack_size = stack->size ();

	      // print the packet header with the count of stack frames
	      fprintf (out_file,
		       GTXT ("#%6ld: %lld, %3lld.%09lld (%4lld.%09lld) t = %d, cpu = %d, frames = %d\n"),
		       i, expr_ts, ts / NANOSEC, ts % NANOSEC,
		       expr_ts / NANOSEC, expr_ts % NANOSEC,
		       thrid, cpuid, stack_size);
	      char *typestr = heapstrings[heaptype];
	      fprintf (out_file,
		       GTXT ("    type = %d (%s), size = %llu (0x%llx), VADDR = 0x%016llx, OVADDR = 0x%016llx\n"),
		       (int) heaptype, typestr, (long long unsigned int) heapsize,
		       (long long unsigned int) heapsize,
		       (long long unsigned int) heapvaddr,
		       (long long unsigned int) heapovaddr);

	      // dump the callstack
	      for (int j = stack_size - 1; j >= 0; j--)
		{
		  Histable *frame = stack->fetch (j);
		  fprintf (out_file, GTXT ("          %s [0x%016llx]\n"), frame->get_name (), (long long) frame);
		}
	      fprintf (out_file, "\n");
	    }
	}
      else
	fprintf (out_file, GTXT ("\nNo Heaptrace Packets in Experiment:  %s\n"),
		 exp->get_expt_name ());
    }
}

// Dump the Java garbage collector events
void
DbeView::dump_gc_events (FILE *out_file)
{
  for (int idx = 0; idx < dbeSession->nexps (); idx++)
    {
      Experiment *exp = dbeSession->get_exp (idx);
      if (!exp->has_java)
	fprintf (out_file,
		 GTXT ("# No GC events in experiment %d, %s (PID %d, %s)\n"),
		 idx, exp->get_expt_name (), exp->getPID (), exp->utargname);
      else
	{
	  Vector<GCEvent*> *gce = exp->get_gcevents ();
	  GCEvent *this_event;
	  int index;
	  fprintf (out_file,
		   GTXT ("# %li events in experiment %d: %s (PID %d, %s)\n"),
		   gce->size (), idx,
		   exp->get_expt_name (), exp->getPID (), exp->utargname);
	  fprintf (out_file,
	       GTXT ("# exp:idx     GC_start,        GC_end,   GC_duration\n"));
	  Vec_loop (GCEvent*, gce, index, this_event)
	  {
	    hrtime_t start = this_event->start - exp->getStartTime ();
	    hrtime_t end = this_event->end - exp->getStartTime ();
	    hrtime_t delta = this_event->end - this_event->start;
	    fprintf (out_file,
		     "%5d:%d, %3lld.%09lld, %3lld.%09lld, %3lld.%09lld\n",
		     idx, index,
		     (long long) (start / NANOSEC), (long long) (start % NANOSEC),
		     (long long) (end / NANOSEC), (long long) (end % NANOSEC),
		     (long long) (delta / NANOSEC), (long long) (delta % NANOSEC));
	  }
	}
    }
}

void
DbeView::purge_events (int n)
{
  phaseIdx++;
  int lst;
  if (n == -1)
    lst = filters->size ();
  else
    lst = n > filters->size () ? filters->size () : n + 1;
  for (int i = n == -1 ? 0 : n; i < lst; i++)
    {
      Vector<DataView*> *expDataViewList = dataViews->fetch (i);
      if (expDataViewList)
	{
	  // clear out all the data_ids, but don't change the vector size
	  for (int data_id = 0; data_id < expDataViewList->size (); ++data_id)
	    {
	      delete expDataViewList->fetch (data_id);
	      expDataViewList->store (data_id, NULL);
	    }
	}
    }
  filter_active = false;
}


// LIBRARY_VISIBILITY
void
DbeView::resetAndConstructShowHideStacks ()
{
  for (int n = 0, nexps = dbeSession->nexps (); n < nexps; n++)
    {
      Experiment *exp = dbeSession->get_exp (n);
      if (exp != NULL)
	resetAndConstructShowHideStack (exp);
    }
}

// LIBRARY_VISIBILITY
void
DbeView::resetAndConstructShowHideStack (Experiment *exp)
{
  exp->resetShowHideStack ();
  /*  Vector<DataDescriptor*> *dDscrs = */ exp->getDataDescriptors ();

  DataDescriptor *dd;
  // Construct show hide stack only for objects which have call stacks
  // list below similar to path tree. What about HEAP_SZ? (DBFIXME)
  dd = exp->get_raw_events (DATA_CLOCK);
  if (dd != NULL)
    constructShowHideStack (dd, exp);
  dd = exp->get_raw_events (DATA_SYNCH);
  if (dd != NULL)
    constructShowHideStack (dd, exp);
  dd = exp->get_raw_events (DATA_IOTRACE);
  if (dd != NULL)
    constructShowHideStack (dd, exp);
  dd = exp->get_raw_events (DATA_HWC);
  if (dd != NULL)
    constructShowHideStack (dd, exp);
  dd = exp->get_raw_events (DATA_HEAP);
  if (dd != NULL)
    constructShowHideStack (dd, exp);
  dd = exp->get_raw_events (DATA_RACE);
  if (dd != NULL)
    constructShowHideStack (dd, exp);
  dd = exp->get_raw_events (DATA_DLCK);
  if (dd != NULL)
    constructShowHideStack (dd, exp);
}

// LIBRARY_VISIBILITY
void
DbeView::constructShowHideStack (DataDescriptor *dDscr, Experiment *exp)
{
  if (dDscr == NULL)
    return;
  int stack_prop = PROP_NONE;
  VMode view_mode = get_view_mode ();
  if (view_mode == VMODE_MACHINE)
    stack_prop = PROP_MSTACK;
  else if (view_mode == VMODE_EXPERT)
    stack_prop = PROP_XSTACK;
  else if (view_mode == VMODE_USER)
    stack_prop = PROP_USTACK;

  for (long j = 0, sz = dDscr->getSize (); j < sz; j++)
    {
      void *stackId = dDscr->getObjValue (stack_prop, j);
      Vector<Histable*> *stack = (Vector<Histable*>*)CallStack::getStackPCs (stackId);
      int stack_size = stack->size ();
      bool hide_on = false;
      LoadObject *hide_lo = NULL;
      Histable *last_addr = NULL;
      Histable *api_addr = NULL;
      DbeInstr *h_instr;

      Vector<Histable*> *hidepcs = new Vector<Histable*>;
      for (int i = stack_size - 1; i >= 0; i--)
	{
	  bool leaf = (i == 0);
	  Histable *cur_addr = stack->fetch (i);
	  Function *func = (Function*) cur_addr->convertto (Histable::FUNCTION);
	  if (func != NULL)
	    {
	      Module *mod = func->module;
	      LoadObject *lo = mod->loadobject;
	      int segx = lo->seg_idx;
	      if ((get_lo_expand (segx) == LIBEX_API) && (i != (stack_size - 1)))
		{
		  leaf = true;
		  api_addr = cur_addr;
		}
	      else if (get_lo_expand (segx) == LIBEX_HIDE)
		{
		  if (hide_on)
		    {
		      if (lo != hide_lo)
			{
			  // Changed hidden loadobject
			  if (last_addr != NULL)
			    {
			      h_instr = hide_lo->get_hide_instr ((DbeInstr*) last_addr);
			      hidepcs->append (h_instr);
			      last_addr = cur_addr;
			    }
			  hide_lo = lo;
			}
		    }
		  else
		    {
		      // Start hide
		      hide_on = true;
		      last_addr = cur_addr;
		      hide_lo = lo;
		    }
		  if (!leaf)
		    continue;
		}
	      else
		{
		  hide_on = false;
		  if (last_addr != NULL)
		    {
		      h_instr = hide_lo->get_hide_instr ((DbeInstr*) last_addr);
		      hidepcs->append (h_instr);
		      last_addr = NULL;
		    }
		}
	    }
	  if (last_addr != NULL && leaf) cur_addr = last_addr;
	  if (hide_on)
	    {
	      h_instr = hide_lo->get_hide_instr ((DbeInstr*) cur_addr);
	      hidepcs->append (h_instr);
	      if (api_addr != NULL)
		hidepcs->append (api_addr);
	    }
	  else
	    hidepcs->append (cur_addr);
	  if (leaf)
	    break;
	}
      for (int i = 0, k = hidepcs->size () - 1; i < k; ++i, --k)
	hidepcs->swap (i, k);

      CallStack *cstkSH = exp->callTreeShowHide ();
      CallStackNode *hstack = (CallStackNode *) cstkSH->add_stack (hidepcs);
      dDscr->setObjValue (PROP_HSTACK, j, hstack);
      CallStack::setHideStack (stackId, hstack);
      delete hidepcs;
      delete stack;
    }
}

DataView *
DbeView::get_filtered_events (int idx, int data_id)
{
  if (idx < 0 || idx >= dataViews->size ())
    return NULL;
  Vector<DataView*> *expDataViewList = dataViews->fetch (idx);
  if (!expDataViewList)
    return NULL; // Weird

  DataView *dview = expDataViewList->fetch (data_id);
  Experiment *exp = dbeSession->get_exp (idx);
  if (dview)
    {
      // if show-hide is on force a reconstruction of hide stacks
      // LIBRARY_VISIBILITY
      if (!showAll && (showHideChanged || newViewMode))
	{
	  DataDescriptor *dDscr = exp->get_raw_events (data_id);
	  constructShowHideStack (dDscr, exp);
	}
      return dview;
    }

  int orig_data_id = data_id;
  data_id = exp->base_data_id (data_id);
  if (orig_data_id != data_id)
    // orig_data_id is a derived DataView.  Get the master DataView:
    dview = expDataViewList->fetch (data_id);
  if (dview == NULL)
    {
      Expression *saved = cur_filter_expr;
      if (!adjust_filter (exp))
	return NULL;

      DataDescriptor *dDscr = exp->get_raw_events (data_id);
      if (!showAll && (showHideChanged || newViewMode))
	constructShowHideStack (dDscr, exp);

      Emsg *m = exp->fetch_warnings ();
      if (m != NULL)
	this->warning_msg = m->get_msg ();

      if (dDscr != NULL)
	{
	  FilterExp *filter = get_FilterExp (exp);
	  dview = dDscr->createView ();
	  dview->setFilter (filter);
	  if (dview->getSize () < dDscr->getSize ())
	    filter_active = true;
	}
      expDataViewList->store (data_id, dview);

      if (saved)
	{
	  delete cur_filter_expr;
	  cur_filter_expr = saved;
	}
    }
  if (orig_data_id != data_id)
    {
      // create the derived DataView:
      dview = exp->create_derived_data_view (orig_data_id, dview);
      expDataViewList->store (orig_data_id, dview);
    }
  return dview;
}

DataView *
DbeView::get_filtered_events (int idx, int data_id,
			      const int sortprops[], int sortprop_count)
{
  DataView *packets = get_filtered_events (idx, data_id);
  if (packets)
    packets->sort (sortprops, sortprop_count);
  return packets;
}

bool
DbeView::adjust_filter (Experiment *exp)
{
  if (cur_filter_expr)
    {
      Expression::Context ctx (this, exp);
      resetFilterHideMode ();
      Expression *fltr = cur_filter_expr->pEval (&ctx);
      if (fltr->complete ())
	{ // Filter is a constant
	  if (fltr->eval (NULL) == 0)
	    return false;
	  delete fltr;
	  fltr = NULL;
	}
      cur_filter_expr = fltr;
    }
  return true;
}

// Moved from Cacheable.cc:
char *
DbeView::status_str (DbeView_status status)
{
  switch (status)
    {
    case DBEVIEW_SUCCESS:
      return NULL;
    case DBEVIEW_NO_DATA:
      return dbe_strdup (GTXT ("Data not available for this filter selection"));
    case DBEVIEW_IO_ERROR:
      return dbe_strdup (GTXT ("Unable to open file"));
    case DBEVIEW_BAD_DATA:
      return dbe_strdup (GTXT ("Data corrupted"));
    case DBEVIEW_BAD_SYMBOL_DATA:
      return dbe_strdup (GTXT ("Functions/Modules information corrupted"));
    case DBEVIEW_NO_SEL_OBJ:
      return dbe_strdup (GTXT ("No selected object, bring up Functions Tab"));
    }
  return NULL;
}

Histable *
DbeView::set_sel_obj (Histable *obj)
{
  if (obj)
    {
      switch (obj->get_type ())
	{
	case Histable::INSTR:
	  lastSelInstr = (DbeInstr *) obj;
	  lastSelFunc = lastSelInstr->func;
	  this->sel_binctx = lastSelFunc;
	  break;
	case Histable::FUNCTION:
	  if (lastSelInstr && lastSelInstr->func != obj)
	    lastSelInstr = NULL;
	  lastSelFunc = (Function *) obj;
	  break;
	case Histable::LINE:
	  {
	    DbeLine *dbeLine = (DbeLine *) obj;
	    if (dbeLine->func)
	      {
		// remember previous DbeInstr and DbeFunc
		lastSelFunc = dbeLine->func;
		if (lastSelInstr && lastSelInstr->func != lastSelFunc)
		  lastSelInstr = NULL;
		this->sel_binctx = lastSelFunc;
	      }
	    else
	      this->sel_binctx = dbeLine->convertto (Histable::FUNCTION);
	    break;
	  }
	case Histable::MODULE:
	case Histable::LOADOBJECT:
	case Histable::EADDR:
	case Histable::MEMOBJ:
	case Histable::INDEXOBJ:
	case Histable::PAGE:
	case Histable::DOBJECT:
	case Histable::SOURCEFILE:
	case Histable::IOACTFILE:
	case Histable::IOACTVFD:
	case Histable::IOCALLSTACK:
	case Histable::HEAPCALLSTACK:
	case Histable::EXPERIMENT:
	case Histable::OTHER:
	  break;
	}
    }
  sel_obj = obj;
  Dprintf (DEBUG_DBE, NTXT ("### set_sel_obj: DbeView.cc:%d obj %s\n"),
	   __LINE__, obj ? obj->dump () : "NULL");
  Dprintf (DEBUG_DBE, NTXT ("### set_sel_obj: DbeView.cc:%d sel_obj %s\n"),
	   __LINE__, sel_obj ? sel_obj->dump () : "NULL");
  Dprintf (DEBUG_DBE, NTXT ("### set_sel_obj: DbeView.cc:%d lastSelFunc %s\n"),
	   __LINE__, lastSelFunc ? lastSelFunc->dump () : "NULL");
  Dprintf (DEBUG_DBE, NTXT ("### set_sel_obj: DbeView.cc:%d lastSelInstr %s\n"),
	   __LINE__, lastSelInstr ? lastSelInstr->dump () : "NULL");
  return sel_obj;
}

DbeInstr *
DbeView::convert_line_to_instr (DbeLine *dbeLine)
{
  Dprintf (DEBUG_DBE, "### convert_line_to_instr DbeView::%d dbeLine=%s\n", __LINE__, dbeLine->dump ());
  Function *func = convert_line_to_func (dbeLine);
  if (func)
    {
      Dprintf (DEBUG_DBE, "### convert_line_to_instr DbeView::%d func=%s\n", __LINE__, func->dump ());
      DbeInstr *dbeInstr = func->mapLineToPc (dbeLine);
      Dprintf (DEBUG_DBE && dbeInstr, "### convert_line_to_instr DbeView::%d dbeInstr=%s\n", __LINE__, dbeInstr->dump ());
      return dbeInstr;
    }
  Dprintf (DEBUG_DBE && lastSelInstr, "### convert_line_to_instr DbeView::%d lastSelInstr=%s\n", __LINE__, lastSelInstr->dump ());
  return lastSelInstr;
}

DbeInstr *
DbeView::convert_func_to_instr (Function *func)
{
  return (lastSelInstr && lastSelInstr->func == func) ?
	  lastSelInstr : (DbeInstr *) func->convertto (Histable::INSTR);
}

Function *
DbeView::convert_line_to_func (DbeLine *dbeLine)
{
  Function *func = dbeLine->func;
  if (func)
    return func;
  if (lastSelFunc != NULL)
    // Can be mapped to the same function ?
    for (DbeLine *dl = dbeLine->dbeline_base; dl; dl = dl->dbeline_func_next)
      if (dl->func == lastSelFunc)
	return lastSelFunc;

  PathTree *pathTree = NULL;
  Function *firstFunc = NULL;
  for (DbeLine *dl = dbeLine->dbeline_base; dl; dl = dl->dbeline_func_next)
    {
      // Find a first function with non-zero metrics
      if (dl->func)
	{
	  if (pathTree == NULL)
	    pathTree = get_path_tree ();
	  if (pathTree->get_func_nodeidx (dl->func))
	    return dl->func;
	  if (firstFunc == NULL)
	    firstFunc = dl->func;
	}
    }
  // Take a first function
  return firstFunc;
}

Histable *
DbeView::get_sel_obj (Histable::Type type)
{
  Histable *lastSelObj = sel_obj;
  Dprintf (DEBUG_DBE, NTXT ("### get_sel_obj: DbeView.cc:%d type=%d sel_obj %s\n"),
	   __LINE__, type, lastSelObj ? lastSelObj->dump () : "NULL");
  if (lastSelObj == NULL)
    return NULL;
  switch (type)
    {
    case Histable::INSTR:
      if (!showAll)
	{
	  // DBFIXME LIBRARY VISIBILITY
	  // hack to get to the hide mode object for PCs when filtering
	  // with a PC in timeline
	  if (lastSelObj->get_type () == Histable::INSTR)
	    {
	      Function *func = (Function*) (lastSelObj->convertto (Histable::FUNCTION));
	      LoadObject *lo = func->module->loadobject;
	      if (get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
		return lo->get_hide_function ();
	    }
	}
      if (lastSelObj->get_type () == Histable::LINE)
	return convert_line_to_instr ((DbeLine*) lastSelObj);
      else if (lastSelObj->get_type () == Histable::FUNCTION)
	return convert_func_to_instr ((Function *) lastSelObj);
      return lastSelObj->convertto (type);
    case Histable::FUNCTION:
      if (lastSelObj->get_type () == Histable::LINE)
	{
	  Function *func = convert_line_to_func ((DbeLine*) lastSelObj);
	  if (func)
	    return func;
	  return NULL;
	}
      return lastSelObj->convertto (type);
    case Histable::LINE:
    default:
      return lastSelObj->convertto (type);
    }
}
