/* Copyright (C) 2021-2024 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 <stdio.h>

#include "IndexMap2D.h"
#include "DbeSession.h"
#include "FilterExp.h"
#include "Table.h"
#include "util.h"
#include "i18n.h"

char *
get_prof_data_type_name (int t)
{
  switch (t)
    {
    case DATA_SAMPLE:   return NTXT("PROFDATA_TYPE_SAMPLE");
    case DATA_GCEVENT:  return NTXT("PROFDATA_TYPE_GCEVENT");
    case DATA_HEAPSZ:   return NTXT("PROFDATA_TYPE_HEAPSZ");
    case DATA_CLOCK:    return NTXT("PROFDATA_TYPE_CLOCK");
    case DATA_HWC:      return NTXT("PROFDATA_TYPE_HWC");
    case DATA_SYNCH:    return NTXT("PROFDATA_TYPE_SYNCH");
    case DATA_HEAP:     return NTXT("PROFDATA_TYPE_HEAP");
    case DATA_OMP:      return NTXT("PROFDATA_TYPE_OMP");
    case DATA_OMP2:     return NTXT("PROFDATA_TYPE_OMP2");
    case DATA_OMP3:     return NTXT("PROFDATA_TYPE_OMP3");
    case DATA_OMP4:     return NTXT("PROFDATA_TYPE_OMP4");
    case DATA_OMP5:     return NTXT("PROFDATA_TYPE_OMP5");
    case DATA_IOTRACE:  return NTXT("PROFDATA_TYPE_IOTRACE");
    default: abort ();
      return NTXT ("PROFDATA_TYPE_ERROR");
    }
}

char *
get_prof_data_type_uname (int t)
{
  switch (t)
    {
    case DATA_SAMPLE:   return GTXT("Process-wide Resource Utilization");
    case DATA_GCEVENT:  return GTXT("Java Garbage Collection Events");
    case DATA_HEAPSZ:   return GTXT("Heap Size");
    case DATA_CLOCK:    return GTXT("Clock Profiling");
    case DATA_HWC:      return GTXT("HW Counter Profiling");
    case DATA_SYNCH:    return GTXT("Synchronization Tracing");
    case DATA_HEAP:     return GTXT("Heap Tracing");
    case DATA_OMP:      return GTXT("OpenMP Profiling");
    case DATA_OMP2:     return GTXT("OpenMP Profiling");
    case DATA_OMP3:     return GTXT("OpenMP Profiling");
    case DATA_OMP4:     return GTXT("OpenMP Profiling");
    case DATA_OMP5:     return GTXT("OpenMP Profiling");
    case DATA_IOTRACE:  return GTXT("IO Tracing");
    default: abort ();
      return NTXT ("PROFDATA_TYPE_ERROR");
    }
}

int assert_level = 0; // set to 1 to bypass problematic asserts

#define ASSERT_SKIP (assert_level)

/*
 *    class PropDescr
 */

PropDescr::PropDescr (int _propID, const char *_name)
{
  propID = _propID;
  name = xstrdup (_name ? _name : NTXT (""));
  uname = NULL;
  vtype = TYPE_NONE;
  flags = 0;
  stateNames = NULL;
  stateUNames = NULL;
}

PropDescr::~PropDescr ()
{
  free (name);
  free (uname);
  if (stateNames)
    {
      stateNames->destroy ();
      delete stateNames;
    }
  if (stateUNames)
    {
      stateUNames->destroy ();
      delete stateUNames;
    }
}

void
PropDescr::addState (int value, const char *stname, const char *stuname)
{
  if (value < 0 || stname == NULL)
    return;
  if (stateNames == NULL)
    stateNames = new Vector<char*>;
  stateNames->store (value, xstrdup (stname));
  if (stateUNames == NULL)
    stateUNames = new Vector<char*>;
  stateUNames->store (value, xstrdup (stuname));
}

char *
PropDescr::getStateName (int value)
{
  if (stateNames && value >= 0 && value < stateNames->size ())
    return stateNames->fetch (value);
  return NULL;
}

char *
PropDescr::getStateUName (int value)
{
  if (stateUNames && value >= 0 && value < stateUNames->size ())
    return stateUNames->fetch (value);
  return NULL;
}

/*
 *    class FieldDescr
 */

FieldDescr::FieldDescr (int _propID, const char *_name)
{
  propID = _propID;
  name = _name ? xstrdup (_name) : NULL;
  offset = 0;
  vtype = TYPE_NONE;
  format = NULL;
}

FieldDescr::~FieldDescr ()
{
  free (name);
  free (format);
}

/*
 *    class PacketDescriptor
 */

PacketDescriptor::PacketDescriptor (DataDescriptor *_ddscr)
{
  ddscr = _ddscr;
  fields = new Vector<FieldDescr*>;
}

PacketDescriptor::~PacketDescriptor ()
{
  fields->destroy ();
  delete fields;
}

void
PacketDescriptor::addField (FieldDescr *fldDscr)
{
  if (fldDscr == NULL)
    return;
  fields->append (fldDscr);
}

/*
 *    class Data
 */

/* Check compatibility between Datum and Data */
static void
checkCompatibility (VType_type v1, VType_type v2)
{
  switch (v1)
    {
    case TYPE_NONE:
    case TYPE_STRING:
    case TYPE_DOUBLE:
    case TYPE_OBJ:
    case TYPE_DATE:
      assert (v1 == v2);
      break;
    case TYPE_INT32:
    case TYPE_UINT32:
      assert (v2 == TYPE_INT32 ||
	      v2 == TYPE_UINT32);
      break;
    case TYPE_INT64:
    case TYPE_UINT64:
      assert (v2 == TYPE_INT64 ||
	      v2 == TYPE_UINT64);
      break;
    default:
      assert (0);
    }
}

class DataINT32 : public Data
{
public:

  DataINT32 ()
  {
    data = new Vector<int32_t>;
  }

  virtual
  ~DataINT32 ()
  {
    delete data;
  }

  virtual VType_type
  type ()
  {
    return TYPE_INT32;
  }

  virtual void
  reset ()
  {
    data->reset ();
  }

  virtual long
  getSize ()
  {
    return data->size ();
  }

  virtual int
  fetchInt (long i)
  {
    return (int) data->fetch (i);
  }

  virtual unsigned long long
  fetchULong (long i)
  {
    return (unsigned long long) data->fetch (i);
  }

  virtual long long
  fetchLong (long i)
  {
    return (long long) data->fetch (i);
  }

  virtual char *
  fetchString (long i)
  {
    return dbe_sprintf (NTXT ("%d"), data->fetch (i));
  }

  virtual double
  fetchDouble (long i)
  {
    return (double) data->fetch (i);
  }

  virtual void *
  fetchObject (long)
  {
    assert (ASSERT_SKIP);
    return NULL;
  }

  virtual void
  setDatumValue (long idx, const Datum *val)
  {
    data->store (idx, val->i);
  }

  virtual void
  setValue (long idx, uint64_t val)
  {
    data->store (idx, (int32_t) val);
  }

  virtual void
  setObjValue (long, void*)
  {
    assert (ASSERT_SKIP);
    return;
  }

  virtual int
  cmpValues (long idx1, long idx2)
  {
    int32_t i1 = data->fetch (idx1);
    int32_t i2 = data->fetch (idx2);
    return i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
  }

  virtual int
  cmpDatumValue (long idx, const Datum *val)
  {
    int32_t i1 = data->fetch (idx);
    int32_t i2 = val->i;
    return i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
  }

private:
  Vector<int32_t> *data;
};

class DataUINT32 : public Data
{
public:

  DataUINT32 ()
  {
    data = new Vector<uint32_t>;
  }

  virtual
  ~DataUINT32 ()
  {
    delete data;
  }

  virtual VType_type
  type ()
  {
    return TYPE_UINT32;
  }

  virtual void
  reset ()
  {
    data->reset ();
  }

  virtual long
  getSize ()
  {
    return data->size ();
  }

  virtual int
  fetchInt (long i)
  {
    return (int) data->fetch (i);
  }

  virtual unsigned long long
  fetchULong (long i)
  {
    return (unsigned long long) data->fetch (i);
  }

  virtual long long
  fetchLong (long i)
  {
    return (long long) data->fetch (i);
  }

  virtual char *
  fetchString (long i)
  {
    return dbe_sprintf (NTXT ("%u"), data->fetch (i));
  }

  virtual double
  fetchDouble (long i)
  {
    return (double) data->fetch (i);
  }

  virtual void *
  fetchObject (long)
  {
    assert (ASSERT_SKIP);
    return NULL;
  }

  virtual void
  setDatumValue (long idx, const Datum *val)
  {
    data->store (idx, val->i);
  }

  virtual void
  setValue (long idx, uint64_t val)
  {
    data->store (idx, (uint32_t) val);
  }

  virtual void
  setObjValue (long, void*)
  {
    assert (ASSERT_SKIP);
    return;
  }

  virtual int
  cmpValues (long idx1, long idx2)
  {
    uint32_t u1 = data->fetch (idx1);
    uint32_t u2 = data->fetch (idx2);
    return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
  }

  virtual int
  cmpDatumValue (long idx, const Datum *val)
  {
    uint32_t u1 = data->fetch (idx);
    uint32_t u2 = (uint32_t) val->i;
    return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
  }

private:
  Vector<uint32_t> *data;
};

class DataINT64 : public Data
{
public:

  DataINT64 ()
  {
    data = new Vector<int64_t>;
  }

  virtual
  ~DataINT64 ()
  {
    delete data;
  }

  virtual VType_type
  type ()
  {
    return TYPE_INT64;
  }

  virtual void
  reset ()
  {
    data->reset ();
  }

  virtual long
  getSize ()
  {
    return data->size ();
  }

  virtual int
  fetchInt (long i)
  {
    return (int) data->fetch (i);
  }

  virtual unsigned long long
  fetchULong (long i)
  {
    return (unsigned long long) data->fetch (i);
  }

  virtual long long
  fetchLong (long i)
  {
    return (long long) data->fetch (i);
  }

  virtual char *
  fetchString (long i)
  {
    return dbe_sprintf (NTXT ("%lld"), (long long) data->fetch (i));
  }

  virtual double
  fetchDouble (long i)
  {
    return (double) data->fetch (i);
  }

  virtual void *
  fetchObject (long)
  {
    assert (ASSERT_SKIP);
    return NULL;
  }

  virtual void
  setDatumValue (long idx, const Datum *val)
  {
    data->store (idx, val->ll);
  }

  virtual void
  setValue (long idx, uint64_t val)
  {
    data->store (idx, (int64_t) val);
  }

  virtual void
  setObjValue (long, void*)
  {
    assert (ASSERT_SKIP);
    return;
  }

  virtual int
  cmpValues (long idx1, long idx2)
  {
    int64_t i1 = data->fetch (idx1);
    int64_t i2 = data->fetch (idx2);
    return i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
  }

  virtual int
  cmpDatumValue (long idx, const Datum *val)
  {
    int64_t i1 = data->fetch (idx);
    int64_t i2 = val->ll;
    return i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
  }

private:
  Vector<int64_t> *data;
};

class DataUINT64 : public Data
{
public:

  DataUINT64 ()
  {
    data = new Vector<uint64_t>;
  }

  virtual
  ~DataUINT64 ()
  {
    delete data;
  }

  virtual VType_type
  type ()
  {
    return TYPE_UINT64;
  }

  virtual void
  reset ()
  {
    data->reset ();
  }

  virtual long
  getSize ()
  {
    return data->size ();
  }

  virtual int
  fetchInt (long i)
  {
    return (int) data->fetch (i);
  }

  virtual unsigned long long
  fetchULong (long i)
  {
    return (unsigned long long) data->fetch (i);
  }

  virtual long long
  fetchLong (long i)
  {
    return (long long) data->fetch (i);
  }

  virtual char *
  fetchString (long i)
  {
    return dbe_sprintf (NTXT ("%llu"), (long long) data->fetch (i));
  }

  virtual double
  fetchDouble (long i)
  {
    return (double) data->fetch (i);
  }

  virtual void *
  fetchObject (long)
  {
    assert (ASSERT_SKIP);
    return NULL;
  }

  virtual void
  setDatumValue (long idx, const Datum *val)
  {
    data->store (idx, val->ll);
  }

  virtual void
  setValue (long idx, uint64_t val)
  {
    data->store (idx, val);
  }

  virtual void
  setObjValue (long, void*)
  {
    assert (ASSERT_SKIP);
    return;
  }

  virtual int
  cmpValues (long idx1, long idx2)
  {
    uint64_t u1 = data->fetch (idx1);
    uint64_t u2 = data->fetch (idx2);
    return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
  }

  virtual int
  cmpDatumValue (long idx, const Datum *val)
  {
    uint64_t u1 = data->fetch (idx);
    uint64_t u2 = (uint64_t) val->ll;
    return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
  }

private:
  Vector<uint64_t> *data;
};

class DataOBJECT : public Data
{
public:

  DataOBJECT ()
  {
    dtype = TYPE_OBJ;
    data = new Vector<void*>;
  }

  DataOBJECT (VType_type _dtype)
  {
    dtype = _dtype;
    data = new Vector<void*>;
  }

  virtual
  ~DataOBJECT ()
  {
    delete data;
  }

  virtual VType_type
  type ()
  {
    return dtype;
  }

  virtual void
  reset ()
  {
    data->reset ();
  }

  virtual long
  getSize ()
  {
    return data->size ();
  }

  virtual int
  fetchInt (long)
  {
    assert (ASSERT_SKIP);
    return 0;
  }

  virtual unsigned long long
  fetchULong (long)
  {
    assert (ASSERT_SKIP);
    return 0LL;
  }

  virtual long long
  fetchLong (long)
  {
    assert (ASSERT_SKIP);
    return 0LL;
  }

  virtual char *
  fetchString (long i)
  {
    return dbe_sprintf (NTXT ("%lu"), (unsigned long) data->fetch (i));
  }

  virtual double
  fetchDouble (long)
  {
    assert (ASSERT_SKIP);
    return 0.0;
  }

  virtual void *
  fetchObject (long i)
  {
    return data->fetch (i);
  }

  virtual void
  setDatumValue (long idx, const Datum *val)
  {
    data->store (idx, val->p);
  }

  virtual void
  setValue (long, uint64_t)
  {
    assert (ASSERT_SKIP);
    return;
  }

  virtual void
  setObjValue (long idx, void *p)
  {
    data->store (idx, p);
  }

  virtual int
  cmpValues (long, long)
  {
    return 0;
  }

  virtual int
  cmpDatumValue (long, const Datum *)
  {
    return 0;
  }

private:
  VType_type dtype;
  Vector<void*> *data;
};

class DataSTRING : public Data
{
public:

  DataSTRING ()
  {
    data = new Vector<char*>;
  }

  virtual
  ~DataSTRING ()
  {
    data->destroy ();
    delete data;
  }

  virtual VType_type
  type ()
  {
    return TYPE_STRING;
  }

  virtual void
  reset ()
  {
    data->reset ();
  }

  virtual long
  getSize ()
  {
    return data->size ();
  }

  virtual int
  fetchInt (long)
  {
    return 0;
  }

  virtual unsigned long long
  fetchULong (long)
  {
    return 0LL;
  }

  virtual long long
  fetchLong (long)
  {
    return 0LL;
  }

  virtual char *
  fetchString (long i)
  {
    return xstrdup (data->fetch (i));
  }

  virtual double
  fetchDouble (long)
  {
    return 0.0;
  }

  virtual void *
  fetchObject (long i)
  {
    return data->fetch (i);
  }

  virtual void
  setDatumValue (long idx, const Datum *val)
  {
    data->store (idx, val->l);
  }

  virtual void
  setValue (long, uint64_t)
  {
    return;
  }

  virtual void
  setObjValue (long idx, void *p)
  {
    data->store (idx, (char*) p);
  }

  virtual int
  cmpValues (long, long)
  {
    return 0;
  }

  virtual int
  cmpDatumValue (long, const Datum *)
  {
    return 0;
  }

private:
  Vector<char*> *data;
};

class DataDOUBLE : public Data
{
public:

  DataDOUBLE ()
  {
    data = new Vector<double>;
  }

  virtual
  ~DataDOUBLE ()
  {
    delete data;
  }

  virtual VType_type
  type ()
  {
    return TYPE_DOUBLE;
  }

  virtual void
  reset ()
  {
    data->reset ();
  }

  virtual long
  getSize ()
  {
    return data->size ();
  }

  virtual int
  fetchInt (long i)
  {
    return (int) data->fetch (i);
  }

  virtual unsigned long long
  fetchULong (long i)
  {
    return (unsigned long long) data->fetch (i);
  }

  virtual long long
  fetchLong (long i)
  {
    return (long long) data->fetch (i);
  }

  virtual char *
  fetchString (long i)
  {
    return dbe_sprintf (NTXT ("%f"), data->fetch (i));
  }

  virtual double
  fetchDouble (long i)
  {
    return data->fetch (i);
  }

  virtual void
  setDatumValue (long idx, const Datum *val)
  {
    data->store (idx, val->d);
  }

  virtual void
  setValue (long idx, uint64_t val)
  {
    data->store (idx, (double) val);
  }

  virtual void
  setObjValue (long, void*)
  {
    return;
  }

  virtual void *
  fetchObject (long)
  {
    return NULL;
  }

  virtual int
  cmpValues (long idx1, long idx2)
  {
    double d1 = data->fetch (idx1);
    double d2 = data->fetch (idx2);
    return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
  }

  virtual int
  cmpDatumValue (long idx, const Datum *val)
  {
    double d1 = data->fetch (idx);
    double d2 = val->d;
    return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
  }

private:
  Vector<double> *data;
};

Data *
Data::newData (VType_type vtype)
{
  switch (vtype)
    {
    case TYPE_INT32:
      return new DataINT32;
    case TYPE_UINT32:
      return new DataUINT32;
    case TYPE_INT64:
      return new DataINT64;
    case TYPE_UINT64:
      return new DataUINT64;
    case TYPE_OBJ:
      return new DataOBJECT;
    case TYPE_STRING:
      return new DataSTRING;
    case TYPE_DOUBLE:
      return new DataDOUBLE;
    default:
      return NULL;
    }
}

/*
 *    class DataDescriptor
 */
DataDescriptor::DataDescriptor (int _id, const char *_name, const char *_uname,
				int _flags)
{
  isMaster = true;
  id = _id;
  name = _name ? xstrdup (_name) : xstrdup (NTXT (""));
  uname = _uname ? xstrdup (_uname) : xstrdup (NTXT (""));
  flags = _flags;

  // master data, shared with reference copies:
  master_size = 0;
  master_resolveFrameInfoDone = false;
  props = new Vector<PropDescr*>;
  data = new Vector<Data*>;
  setsTBR = new Vector<Vector<long long>*>;

  // master references point to self:
  ref_size = &master_size;
  ref_resolveFrameInfoDone = &master_resolveFrameInfoDone;
}

DataDescriptor::DataDescriptor (int _id, const char *_name, const char *_uname,
				DataDescriptor* dDscr)
{
  isMaster = false;
  id = _id;
  name = _name ? xstrdup (_name) : xstrdup (NTXT (""));
  uname = _uname ? xstrdup (_uname) : xstrdup (NTXT (""));
  flags = dDscr->flags;

  // references point to master DataDescriptor
  ref_size = &dDscr->master_size;
  ref_resolveFrameInfoDone = &dDscr->master_resolveFrameInfoDone;
  props = dDscr->props;
  data = dDscr->data;
  setsTBR = dDscr->setsTBR;

  // data that should never be accessed in reference copy
  master_size = -1;
  master_resolveFrameInfoDone = false;
}

DataDescriptor::~DataDescriptor ()
{
  free (name);
  free (uname);
  if (!isMaster)
    return;
  props->destroy ();
  delete props;
  data->destroy ();
  delete data;
  setsTBR->destroy ();
  delete setsTBR;
}

void
DataDescriptor::reset ()
{
  if (!isMaster)
    return;
  for (int i = 0; i < data->size (); i++)
    {
      Data *d = data->fetch (i);
      if (d != NULL)
	d->reset ();
      Vector<long long> *set = setsTBR->fetch (i);
      if (set != NULL)
	set->reset ();
    }
  master_size = 0;
}

PropDescr *
DataDescriptor::getProp (int prop_id)
{
  for (int i = 0; i < props->size (); i++)
    {
      PropDescr *propDscr = props->fetch (i);
      if (propDscr->propID == prop_id)
	return propDscr;
    }
  return NULL;
}

Data *
DataDescriptor::getData (int prop_id)
{
  if (prop_id < 0 || prop_id >= data->size ())
    return NULL;
  return data->fetch (prop_id);
}

void
DataDescriptor::addProperty (PropDescr *propDscr)
{
  if (propDscr == NULL)
    return;
  if (propDscr->propID < 0)
    return;
  PropDescr *oldProp = getProp (propDscr->propID);
  if (oldProp != NULL)
    {
      checkCompatibility (propDscr->vtype, oldProp->vtype); //YXXX depends on experiment correctness
      delete propDscr;
      return;
    }
  props->append (propDscr);
  data->store (propDscr->propID, Data::newData (propDscr->vtype));
  setsTBR->store (propDscr->propID, NULL);
}

long
DataDescriptor::addRecord ()
{
  if (!isMaster)
    return -1;
  return master_size++;
}

static void
checkEntity (Vector<long long> *set, long long val)
{
  // Binary search
  int lo = 0;
  int hi = set->size () - 1;
  while (lo <= hi)
    {
      int md = (lo + hi) / 2;
      long long ent = set->fetch (md);
      if (ent < val)
	lo = md + 1;
      else if (ent > val)
	hi = md - 1;
      else
	return;
    }
  set->insert (lo, val);
}

void
DataDescriptor::setDatumValue (int prop_id, long idx, const Datum *val)
{
  if (idx >= *ref_size)
    return;
  Data *d = getData (prop_id);
  if (d != NULL)
    {
      VType_type datum_type = val->type;
      VType_type data_type = d->type ();
      checkCompatibility (datum_type, data_type);
      d->setDatumValue (idx, val);
      Vector<long long> *set = setsTBR->fetch (prop_id);
      if (set != NULL)// Sets are maintained
	checkEntity (set, d->fetchLong (idx));
    }
}

void
DataDescriptor::setValue (int prop_id, long idx, uint64_t val)
{
  if (idx >= *ref_size)
    return;
  Data *d = getData (prop_id);
  if (d != NULL)
    {
      d->setValue (idx, val);
      Vector<long long> *set = setsTBR->fetch (prop_id);
      if (set != NULL)// Sets are maintained
	checkEntity (set, d->fetchLong (idx));
    }
}

void
DataDescriptor::setObjValue (int prop_id, long idx, void *val)
{
  if (idx >= *ref_size)
    return;
  Data *d = getData (prop_id);
  if (d != NULL)
    d->setObjValue (idx, val);
}

DataView *
DataDescriptor::createView ()
{
  return new DataView (this);
}

DataView *
DataDescriptor::createImmutableView ()
{
  return new DataView (this, DataView::DV_IMMUTABLE);
}

DataView *
DataDescriptor::createExtManagedView ()
{
  return new DataView (this, DataView::DV_EXT_MANAGED);
}

int
DataDescriptor::getIntValue (int prop_id, long idx)
{
  Data *d = getData (prop_id);
  if (d == NULL || idx >= d->getSize ())
    return 0;
  return d->fetchInt (idx);
}

unsigned long long
DataDescriptor::getULongValue (int prop_id, long idx)
{
  Data *d = getData (prop_id);
  if (d == NULL || idx >= d->getSize ())
    return 0L;
  return d->fetchULong (idx);
}

long long
DataDescriptor::getLongValue (int prop_id, long idx)
{
  Data *d = getData (prop_id);
  if (d == NULL || idx >= d->getSize ())
    return 0L;
  return d->fetchLong (idx);
}

void *
DataDescriptor::getObjValue (int prop_id, long idx)
{
  Data *d = getData (prop_id);
  if (d == NULL || idx >= d->getSize ())
    return NULL;
  return d->fetchObject (idx);
}

static int
pcmp (const void *p1, const void *p2, const void *arg)
{
  long idx1 = *(long*) p1; // index1 into Data
  long idx2 = *(long*) p2; // index2 into Data
  for (Data **dsorted = (Data**) arg; *dsorted != DATA_SORT_EOL; dsorted++)
    {
      Data *data = *dsorted;
      if (data == NULL)// sort property not in this data, skip this criteria
	continue;
      int res = data->cmpValues (idx1, idx2);
      if (res)
	return res;
    }
  // Provide stable sort
  return idx1 < idx2 ? -1 : idx1 > idx2 ? 1 : 0;
}

Vector<long long> *
DataDescriptor::getSet (int prop_id)
{
  if (prop_id < 0 || prop_id >= setsTBR->size ())
    return NULL;
  Vector<long long> *set = setsTBR->fetch (prop_id);
  if (set != NULL)
    return set;

  Data *d = getData (prop_id);
  if (d == NULL)
    return NULL;
  set = new Vector<long long>;
  for (long i = 0; i<*ref_size; ++i)
    checkEntity (set, d->fetchLong (i));
  setsTBR->store (prop_id, set);

  return set;
}

/*
 *    class DataView
 */
DataView::DataView (DataDescriptor *_ddscr)
{
  init (_ddscr, DV_NORMAL);
}

DataView::DataView (DataDescriptor *_ddscr, DataViewType _type)
{
  init (_ddscr, _type);
}

void
DataView::init (DataDescriptor *_ddscr, DataViewType _type)
{
  ddscr = _ddscr;
  type = _type;
  switch (type)
    {
    case DV_IMMUTABLE:
      ddsize = ddscr->getSize ();
      index = NULL;
      break;
    case DV_NORMAL:
    case DV_EXT_MANAGED:
      ddsize = 0;
      index = new Vector<long>;
      break;
    }
  for (int ii = 0; ii < (MAX_SORT_DIMENSIONS + 1); ii++)
    sortedBy[ii] = DATA_SORT_EOL;
  filter = NULL;
}

DataView::~DataView ()
{
  delete filter;
  delete index;
}

void
DataView::appendDataDescriptorId (long pkt_id /* ddscr index */)
{
  if (type != DV_EXT_MANAGED)
    return; // updates allowed only on externally managed DataViews
  long curr_ddsize = ddscr->getSize ();
  if (pkt_id < 0 || pkt_id >= curr_ddsize)
    return; // error!
  index->append (pkt_id);
}

void
DataView::setDataDescriptorValue (int prop_id, long pkt_id, uint64_t val)
{
  ddscr->setValue (prop_id, pkt_id, val);
}

long long
DataView::getDataDescriptorValue (int prop_id, long pkt_id)
{
  return ddscr->getLongValue (prop_id, pkt_id);
}

Vector<PropDescr*>*
DataView::getProps ()
{
  return ddscr->getProps ();
};

PropDescr*
DataView::getProp (int prop_id)
{
  return ddscr->getProp (prop_id);
};

void
DataView::filter_in_chunks (fltr_dbe_ctx *dctx)
{
  Expression::Context *e_ctx = new Expression::Context (dctx->fltr->ctx->dbev, dctx->fltr->ctx->exp);
  Expression *n_expr = dctx->fltr->expr->copy ();
  bool noParFilter = dctx->fltr->noParFilter;
  FilterExp *nFilter = new FilterExp (n_expr, e_ctx, noParFilter);
  long iter = dctx->begin;
  long end = dctx->end;
  long orig_ddsize = dctx->orig_ddsize;
  while (iter < end)
    {
      nFilter->put (dctx->tmpView, iter);
      if (nFilter->passes ())
	dctx->idxArr[iter - orig_ddsize] = 1;
      iter += 1;
    }
  delete nFilter;
}

bool
DataView::checkUpdate ()
{
  long newSize = ddscr->getSize ();
  if (ddsize == newSize)
    return false;
  if (index == NULL)
    return false;
  if (type == DV_EXT_MANAGED)
    return false;
  bool updated = false;
  if (filter)
    {
      DataView *tmpView = ddscr->createImmutableView ();
      assert (tmpView->getSize () == newSize);
      while (ddsize < newSize)
	{
	  filter->put (tmpView, ddsize);
	  if (filter->passes ())
	    index->append (ddsize);
	  ddsize += 1;
	}
      delete tmpView;
      return updated;
    }
  while (ddsize < newSize)
    {
      index->append (ddsize);
      updated = true;
      ddsize += 1;
    }
  return updated;
}

long
DataView::getSize ()
{
  if (checkUpdate () && sortedBy[0] != DATA_SORT_EOL)
    // note: after new filter is set, getSize() incurs cost of
    // sorting even if caller isn't interested in sort
    index->sort ((CompareFunc) pcmp, sortedBy);

  if (index == NULL)
    return ddscr->getSize ();
  return index->size ();
}

void
DataView::setDatumValue (int prop_id, long idx, const Datum *val)
{
  ddscr->setDatumValue (prop_id, getIdByIdx (idx), val);
}

void
DataView::setValue (int prop_id, long idx, uint64_t val)
{
  ddscr->setValue (prop_id, getIdByIdx (idx), val);
}

void
DataView::setObjValue (int prop_id, long idx, void *val)
{
  ddscr->setObjValue (prop_id, getIdByIdx (idx), val);
}

int
DataView::getIntValue (int prop_id, long idx)
{
  return ddscr->getIntValue (prop_id, getIdByIdx (idx));
}

unsigned long long
DataView::getULongValue (int prop_id, long idx)
{
  return ddscr->getULongValue (prop_id, getIdByIdx (idx));
}

long long
DataView::getLongValue (int prop_id, long idx)
{
  return ddscr->getLongValue (prop_id, getIdByIdx (idx));
}

void *
DataView::getObjValue (int prop_id, long idx)
{
  return ddscr->getObjValue (prop_id, getIdByIdx (idx));
}

void
DataView::sort (const int props[], int prop_count)
{
  if (index == NULL)
    {
      assert (ASSERT_SKIP);
      return;
    }
  assert (prop_count >= 0 && prop_count < MAX_SORT_DIMENSIONS);
  bool sort_changed = false; // see if sort has changed...
  for (int ii = 0; ii <= prop_count; ii++)
    { // sortedBy size is prop_count+1
      Data *data;
      if (ii == prop_count)
	data = DATA_SORT_EOL; // special end of array marker
      else
	data = ddscr->getData (props[ii]);
      if (sortedBy[ii] != data)
	{
	  sortedBy[ii] = data;
	  sort_changed = true;
	}
    }
  if (!checkUpdate () && !sort_changed)
    return;
  index->sort ((CompareFunc) pcmp, sortedBy);
}

void
DataView::sort (int prop0)
{
  sort (&prop0, 1);
}

void
DataView::sort (int prop0, int prop1)
{
  int props[2] = {prop0, prop1};
  sort (props, 2);
}

void
DataView::sort (int prop0, int prop1, int prop2)
{
  int props[3] = {prop0, prop1, prop2};
  sort (props, 3);
}

void
DataView::setFilter (FilterExp *f)
{
  if (index == NULL)
    {
      assert (ASSERT_SKIP);
      return;
    }
  delete filter;
  filter = f;
  index->reset ();
  ddsize = 0;
  checkUpdate ();
}

long
DataView::getIdByIdx (long idx)
{
  if (index == NULL)
    return idx;
  return index->fetch (idx);
}

static int
tvalcmp (long data_id, const Datum valColumns[], Data *sortedBy[])
{
  for (int ii = 0; ii < MAX_SORT_DIMENSIONS; ii++)
    {
      if (sortedBy[ii] == DATA_SORT_EOL)
	break;
      Data *d = sortedBy[ii];
      if (d == NULL)// property doesn't exist in data; compare always matches
	continue;
      const Datum *tvalue = &valColumns[ii];
      int res = d->cmpDatumValue (data_id, tvalue);
      if (res)
	return res;
    }
  return 0;
}

static void
checkSortTypes (const Datum valColumns[], Data *sortedBy[])
{
#ifndef NDEBUG
  for (int ii = 0; ii < MAX_SORT_DIMENSIONS; ii++)
    {
      if (sortedBy[ii] == DATA_SORT_EOL)
	break;
      Data *d = sortedBy[ii];
      if (d == NULL)// property doesn't exist in data; compare always matches
	continue;
      VType_type datum_type = valColumns[ii].type;
      VType_type data_type = d->type ();
      checkCompatibility (datum_type, data_type);
    }
#endif
}

bool
DataView::idxRootDimensionsMatch (long idx, const Datum valColumns[])
{
  // compares idx vs. valColumns[] - If all dimensions match
  // (except sort leaf), then the leaf value is valid => return true.
  // Otherwise, return false.
  checkSortTypes (valColumns, sortedBy);
  if (idx < 0 || idx >= index->size ()) // fell off end of array
    return false;
  long data_id = index->fetch (idx);

  // we will check all dimensions for a match except the "leaf" dimension
  for (int ii = 0; ii < (MAX_SORT_DIMENSIONS - 1); ii++)
    {
      if (sortedBy[ii + 1] == DATA_SORT_EOL)
	break; // we are at leaf dimension, don't care about it's value
      if (sortedBy[ii] == DATA_SORT_EOL)
	break; // end of list
      Data *d = sortedBy[ii];
      if (d == NULL) // property doesn't exist in data; compare always matches
	continue;
      const Datum *tvalue = &valColumns[ii];
      int res = d->cmpDatumValue (data_id, tvalue);
      if (res)
	return false;
    }
  return true;
}

long
DataView::getIdxByVals (const Datum valColumns[], Relation rel)
{
  // checks sortedBy[] columns for match; relation only used on last column
  return getIdxByVals (valColumns, rel, -1, -1);
}

long
DataView::getIdxByVals (const Datum valColumns[], Relation rel,
			long minIdx, long maxIdx)
{
  // checks sortedBy[] columns for match; relation only used on last column
  checkSortTypes (valColumns, sortedBy);
  if (index == NULL || sortedBy[0] == DATA_SORT_EOL)
    return -1;

  long lo;
  if (minIdx < 0)
    lo = 0;
  else
    lo = minIdx;

  long hi;
  if (maxIdx < 0 || maxIdx >= index->size ())
    hi = index->size () - 1;
  else
    hi = maxIdx;

  long md = -1;
  while (lo <= hi)
    {
      md = (lo + hi) / 2;
      int cmp = tvalcmp (index->fetch (md), valColumns, sortedBy);
      if (cmp < 0)
	{
	  lo = md + 1;
	  continue;
	}
      else if (cmp > 0)
	{
	  hi = md - 1;
	  continue;
	}

      // cmp == 0, we have an exact match
      switch (rel)
	{
	case REL_LT:
	  hi = md - 1; // continue searching
	  break;
	case REL_GT:
	  lo = md + 1; // continue searching
	  break;
	case REL_LTEQ:
	case REL_GTEQ:
	case REL_EQ:
	  // note: "md" may not be deterministic if multiple matches exist
	  return md; // a match => done.
	}
    }

  // no exact match found
  switch (rel)
    {
    case REL_LT:
    case REL_LTEQ:
      md = hi;
      break;
    case REL_GT:
    case REL_GTEQ:
      md = lo;
      break;
    case REL_EQ:
      return -1;
    }
  if (idxRootDimensionsMatch (md, valColumns))
    return md;
  return -1;
}

void
DataView::removeDbeViewIdx (long idx)
{
  index->remove (idx);
}

