<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH
#define DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH

#include <vector>
#include <type_traits>

#include <dune/stuff/common/memory.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>

#include <dune/gdt/space/interface.hh>
#include <dune/gdt/mapper/interface.hh>

namespace Dune {
namespace GDT {

template <class VectorImp>
class ConstLocalDoFVector
{
  static_assert(std::is_base_of<Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");

public:
  typedef VectorImp VectorType;
  typedef typename VectorType::ScalarType ScalarType;

  template <class M, class EntityType>
  ConstLocalDoFVector(const MapperInterface<M>& mapper, const EntityType& entity, const VectorType& vector)
    : vector_(vector)
    , indices_(mapper.numDofs(entity))
  {
    mapper.globalIndices(entity, indices_);
  }

  ~ConstLocalDoFVector()
  {
  }

  size_t size() const
  {
    return indices_.size();
  }

  ScalarType get(const size_t ii) const
  {
    assert(ii < indices_.size());
    return vector_.get_entry(indices_[ii]);
  }

private:
  const VectorType& vector_;

protected:
  mutable Dune::DynamicVector<size_t> indices_;
}; // class ConstLocalDoFVector

template <class VectorImp>
class LocalDoFVector : public ConstLocalDoFVector<VectorImp>
{
  typedef ConstLocalDoFVector<VectorImp> BaseType;

public:
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ScalarType ScalarType;

  template <class M, class EntityType>
  LocalDoFVector(const MapperInterface<M>& mapper, const EntityType& entity, VectorType& vector)
    : BaseType(mapper, entity, vector)
    , vector_(vector)
  {
  }

  ~LocalDoFVector()
  {
  }

  void set(const size_t ii, const ScalarType& val)
  {
    assert(ii < indices_.size());
    vector_.set_entry(indices_[ii], val);
  }

  void add(const size_t ii, const ScalarType& val)
  {
    assert(ii < indices_.size());
    vector_.add(indices_[ii], val);
  }

private:
  using BaseType::indices_;
  VectorType& vector_;
}; // class LocalDoFVector

template <class SpaceImp, class VectorImp>
class ConstLocalDiscreteFunction
    : public Stuff::LocalfunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                           SpaceImp::dimDomain, typename SpaceImp::RangeFieldType, SpaceImp::dimRange,
                                           SpaceImp::dimRangeCols>
{
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits>, SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");
  static_assert(std::is_base_of<Dune::Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_same<typename SpaceImp::RangeFieldType, typename VectorImp::ScalarType>::value,
                "Types do not match!");
  typedef Stuff::LocalfunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                        SpaceImp::dimDomain, typename SpaceImp::RangeFieldType, SpaceImp::dimRange,
                                        SpaceImp::dimRangeCols> BaseType;
  typedef ConstLocalDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef SpaceImp SpaceType;
  typedef VectorImp VectorType;
  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int dimRangeRows = BaseType::dimRangeCols;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;

public:
  typedef ConstLocalDoFVector<VectorType> ConstLocalDoFVectorType;

  ConstLocalDiscreteFunction(const SpaceType& space, const VectorType& globalVector, const EntityType& ent)
    : BaseType(ent)
    , space_(space)
    , base_(new BaseFunctionSetType(space_.base_function_set(this->entity())))
    , localVector_(new ConstLocalDoFVectorType(space_.mapper(), this->entity(), globalVector))
    , tmpBaseValues_(base_->size(), RangeType(0))
    , tmpBaseJacobianValues_(base_->size(), JacobianRangeType(0))
  {
    assert(localVector_->size() == base_->size());
  }

  ConstLocalDiscreteFunction(ThisType&& source)
    : BaseType(source.entity())
    , space_(source.space_)
    , base_(std::move(source.base_))
    , localVector_(std::move(source.localVector_))
    , tmpBaseValues_(std::move(source.tmpBaseValues_))
    , tmpBaseJacobianValues_(std::move(source.tmpBaseJacobianValues_))
  {
  }

  ConstLocalDiscreteFunction(const ThisType& other) = delete;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ~ConstLocalDiscreteFunction()
  {
  }

  const BaseFunctionSetType& base() const
  {
    return *base_;
  }

  const ConstLocalDoFVectorType& vector() const
  {
    return *localVector_;
  }

  virtual size_t order() const DS_OVERRIDE
  {
    return base_->order();
  }

  virtual void evaluate(const DomainType& xx, RangeType& ret) const DS_OVERRIDE
  {
    assert(this->is_a_valid_point(xx));
    Dune::Stuff::Common::clear(ret);
    assert(localVector_->size() == tmpBaseValues_.size());
    base_->evaluate(xx, tmpBaseValues_);
    for (size_t ii = 0; ii < localVector_->size(); ++ii) {
      tmpBaseValues_[ii] *= localVector_->get(ii);
      ret += tmpBaseValues_[ii];
    }
  } // ... evaluate(...)

  virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const DS_OVERRIDE
  {
    assert(this->is_a_valid_point(xx));
    ret *= RangeFieldType(0);
    assert(localVector_->size() == tmpBaseJacobianValues_.size());
    base_->jacobian(xx, tmpBaseJacobianValues_);
    for (size_t ii = 0; ii < localVector_->size(); ++ii) {
      tmpBaseJacobianValues_[ii] *= localVector_->get(ii);
      ret += tmpBaseJacobianValues_[ii];
    }
  } // ... jacobian(...)

  using BaseType::evaluate;
  using BaseType::jacobian;

protected:
  const SpaceType& space_;
  std::unique_ptr<const BaseFunctionSetType> base_;
  std::unique_ptr<const ConstLocalDoFVectorType> localVector_;

private:
  mutable std::vector<RangeType> tmpBaseValues_;
  mutable std::vector<JacobianRangeType> tmpBaseJacobianValues_;
}; // class ConstLocalDiscreteFunction

template <class SpaceImp, class VectorImp>
class LocalDiscreteFunction : public ConstLocalDiscreteFunction<SpaceImp, VectorImp>
{
  typedef ConstLocalDiscreteFunction<SpaceImp, VectorImp> BaseType;
  typedef LocalDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef typename BaseType::SpaceType SpaceType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int dimRangeRows = BaseType::dimRangeCols;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;

public:
  typedef LocalDoFVector<VectorType> LocalDoFVectorType;

  LocalDiscreteFunction(const SpaceType& space, VectorType& globalVector, const EntityType& ent)
    : BaseType(space, globalVector, ent)
    , localVector_(new LocalDoFVectorType(space_.mapper(), entity_, globalVector))
  {
    assert(localVector_->size() == base_->size());
  }

  LocalDiscreteFunction(ThisType&& source)
    : BaseType(std::move(source)) // <- because of this
    , localVector_(std::move(source.localVector_)) // <- I am not sure if this is valid -+^
  {
  }

  LocalDiscreteFunction(const ThisType& other) = delete;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ~LocalDiscreteFunction()
  {
  }

  LocalDoFVectorType& vector()
  {
    return *localVector_;
  }

private:
  using BaseType::space_;
  using BaseType::entity_;
  using BaseType::base_;
  std::unique_ptr<LocalDoFVectorType> localVector_;
}; // class LocalDiscreteFunction

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH
<commit_msg>[discretefunction.local] added operator<< to local DoF vector<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH
#define DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH

#include <vector>
#include <type_traits>

#include <dune/stuff/common/memory.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>

#include <dune/gdt/space/interface.hh>
#include <dune/gdt/mapper/interface.hh>

namespace Dune {
namespace GDT {

template <class VectorImp>
class ConstLocalDoFVector
{
  static_assert(std::is_base_of<Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");

public:
  typedef VectorImp VectorType;
  typedef typename VectorType::ScalarType ScalarType;

  template <class M, class EntityType>
  ConstLocalDoFVector(const MapperInterface<M>& mapper, const EntityType& entity, const VectorType& vector)
    : vector_(vector)
    , indices_(mapper.numDofs(entity))
  {
    mapper.globalIndices(entity, indices_);
  }

  ~ConstLocalDoFVector()
  {
  }

  size_t size() const
  {
    return indices_.size();
  }

  ScalarType get(const size_t ii) const
  {
    assert(ii < indices_.size());
    return vector_.get_entry(indices_[ii]);
  }

private:
  const VectorType& vector_;

protected:
  mutable Dune::DynamicVector<size_t> indices_;

private:
  template <class V>
  friend std::ostream& operator<<(std::ostream& /*out*/, const ConstLocalDoFVector<V>& /*vector*/);
}; // class ConstLocalDoFVector

template <class V>
std::ostream& operator<<(std::ostream& out, const ConstLocalDoFVector<V>& vector)
{
  out << "[";
  const size_t sz = vector.size();
  if (sz > 0) {
    out << vector.get(0);
    for (size_t ii = 1; ii < sz; ++ii)
      out << ", " << vector.get(ii);
  } else
    out << " ";
  out << "]";
  return out;
} // ... operator<<(...)

template <class VectorImp>
class LocalDoFVector : public ConstLocalDoFVector<VectorImp>
{
  typedef ConstLocalDoFVector<VectorImp> BaseType;

public:
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ScalarType ScalarType;

  template <class M, class EntityType>
  LocalDoFVector(const MapperInterface<M>& mapper, const EntityType& entity, VectorType& vector)
    : BaseType(mapper, entity, vector)
    , vector_(vector)
  {
  }

  ~LocalDoFVector()
  {
  }

  void set(const size_t ii, const ScalarType& val)
  {
    assert(ii < indices_.size());
    vector_.set_entry(indices_[ii], val);
  }

  void add(const size_t ii, const ScalarType& val)
  {
    assert(ii < indices_.size());
    vector_.add(indices_[ii], val);
  }

private:
  using BaseType::indices_;
  VectorType& vector_;
}; // class LocalDoFVector

template <class SpaceImp, class VectorImp>
class ConstLocalDiscreteFunction
    : public Stuff::LocalfunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                           SpaceImp::dimDomain, typename SpaceImp::RangeFieldType, SpaceImp::dimRange,
                                           SpaceImp::dimRangeCols>
{
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits>, SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");
  static_assert(std::is_base_of<Dune::Stuff::LA::VectorInterface<typename VectorImp::Traits>, VectorImp>::value,
                "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_same<typename SpaceImp::RangeFieldType, typename VectorImp::ScalarType>::value,
                "Types do not match!");
  typedef Stuff::LocalfunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                        SpaceImp::dimDomain, typename SpaceImp::RangeFieldType, SpaceImp::dimRange,
                                        SpaceImp::dimRangeCols> BaseType;
  typedef ConstLocalDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef SpaceImp SpaceType;
  typedef VectorImp VectorType;
  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int dimRangeRows = BaseType::dimRangeCols;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;

public:
  typedef ConstLocalDoFVector<VectorType> ConstLocalDoFVectorType;

  ConstLocalDiscreteFunction(const SpaceType& space, const VectorType& globalVector, const EntityType& ent)
    : BaseType(ent)
    , space_(space)
    , base_(new BaseFunctionSetType(space_.base_function_set(this->entity())))
    , localVector_(new ConstLocalDoFVectorType(space_.mapper(), this->entity(), globalVector))
    , tmpBaseValues_(base_->size(), RangeType(0))
    , tmpBaseJacobianValues_(base_->size(), JacobianRangeType(0))
  {
    assert(localVector_->size() == base_->size());
  }

  ConstLocalDiscreteFunction(ThisType&& source)
    : BaseType(source.entity())
    , space_(source.space_)
    , base_(std::move(source.base_))
    , localVector_(std::move(source.localVector_))
    , tmpBaseValues_(std::move(source.tmpBaseValues_))
    , tmpBaseJacobianValues_(std::move(source.tmpBaseJacobianValues_))
  {
  }

  ConstLocalDiscreteFunction(const ThisType& other) = delete;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ~ConstLocalDiscreteFunction()
  {
  }

  const BaseFunctionSetType& base() const
  {
    return *base_;
  }

  const ConstLocalDoFVectorType& vector() const
  {
    return *localVector_;
  }

  virtual size_t order() const DS_OVERRIDE
  {
    return base_->order();
  }

  virtual void evaluate(const DomainType& xx, RangeType& ret) const DS_OVERRIDE
  {
    assert(this->is_a_valid_point(xx));
    Dune::Stuff::Common::clear(ret);
    assert(localVector_->size() == tmpBaseValues_.size());
    base_->evaluate(xx, tmpBaseValues_);
    for (size_t ii = 0; ii < localVector_->size(); ++ii) {
      tmpBaseValues_[ii] *= localVector_->get(ii);
      ret += tmpBaseValues_[ii];
    }
  } // ... evaluate(...)

  virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const DS_OVERRIDE
  {
    assert(this->is_a_valid_point(xx));
    ret *= RangeFieldType(0);
    assert(localVector_->size() == tmpBaseJacobianValues_.size());
    base_->jacobian(xx, tmpBaseJacobianValues_);
    for (size_t ii = 0; ii < localVector_->size(); ++ii) {
      tmpBaseJacobianValues_[ii] *= localVector_->get(ii);
      ret += tmpBaseJacobianValues_[ii];
    }
  } // ... jacobian(...)

  using BaseType::evaluate;
  using BaseType::jacobian;

protected:
  const SpaceType& space_;
  std::unique_ptr<const BaseFunctionSetType> base_;
  std::unique_ptr<const ConstLocalDoFVectorType> localVector_;

private:
  mutable std::vector<RangeType> tmpBaseValues_;
  mutable std::vector<JacobianRangeType> tmpBaseJacobianValues_;
}; // class ConstLocalDiscreteFunction

template <class SpaceImp, class VectorImp>
class LocalDiscreteFunction : public ConstLocalDiscreteFunction<SpaceImp, VectorImp>
{
  typedef ConstLocalDiscreteFunction<SpaceImp, VectorImp> BaseType;
  typedef LocalDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef typename BaseType::SpaceType SpaceType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::DomainFieldType DomainFieldType;
  static const unsigned int dimDomain = BaseType::dimDomain;
  typedef typename BaseType::DomainType DomainType;

  typedef typename BaseType::RangeFieldType RangeFieldType;
  static const unsigned int dimRangeRows = BaseType::dimRangeCols;
  static const unsigned int dimRangeCols = BaseType::dimRangeCols;
  typedef typename BaseType::RangeType RangeType;

  typedef typename BaseType::JacobianRangeType JacobianRangeType;

private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;

public:
  typedef LocalDoFVector<VectorType> LocalDoFVectorType;

  LocalDiscreteFunction(const SpaceType& space, VectorType& globalVector, const EntityType& ent)
    : BaseType(space, globalVector, ent)
    , localVector_(new LocalDoFVectorType(space_.mapper(), entity_, globalVector))
  {
    assert(localVector_->size() == base_->size());
  }

  LocalDiscreteFunction(ThisType&& source)
    : BaseType(std::move(source)) // <- because of this
    , localVector_(std::move(source.localVector_)) // <- I am not sure if this is valid -+^
  {
  }

  LocalDiscreteFunction(const ThisType& other) = delete;

  ThisType& operator=(const ThisType& other) = delete;

  virtual ~LocalDiscreteFunction()
  {
  }

  LocalDoFVectorType& vector()
  {
    return *localVector_;
  }

private:
  using BaseType::space_;
  using BaseType::entity_;
  using BaseType::base_;
  std::unique_ptr<LocalDoFVectorType> localVector_;
}; // class LocalDiscreteFunction

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_LOCAL_HH
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 *
 * ddl_table.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/ddl_table.cpp
 *
 *-------------------------------------------------------------------------
 */

#include <cassert>
#include <iostream>
#include <vector>

#include "backend/bridge/ddl/ddl.h"
#include "backend/bridge/ddl/ddl_table.h"
#include "backend/bridge/ddl/ddl_database.h"
#include "backend/bridge/ddl/ddl_utils.h"
#include "backend/common/logger.h"
#include "backend/storage/backend_vm.h"
#include "backend/storage/table_factory.h"
#include "backend/storage/database.h"

#include "commands/dbcommands.h"
#include "nodes/pg_list.h"
#include "parser/parse_utilcmd.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// Table DDL
//===--------------------------------------------------------------------===//

/**
 * @brief Execute the create stmt.
 * @param the parse tree
 * @param query string
 * @return true if we handled it correctly, false otherwise
 */

bool DDLTable::ExecCreateStmt(Node* parsetree,
                              std::vector<Node*>& parsetree_stack,
                              Peloton_Status* status,
                              TransactionId txn_id) {

  List* stmts = ((CreateStmt*)parsetree)->stmts;

  /* ... and do it */
  ListCell* l;
  foreach (l, stmts) {
    Node* stmt = (Node*)lfirst(l);
    if (IsA(stmt, CreateStmt)) {
      CreateStmt* Cstmt = (CreateStmt*)stmt;
      List* schema = (List*)(Cstmt->tableElts);

      // Relation name and oid
      char* relation_name = Cstmt->relation->relname;
      Oid relation_oid = ((CreateStmt*)parsetree)->relation_id;

      assert(relation_oid);

      std::vector<catalog::Column> column_infos;
      std::vector<catalog::ForeignKey> foreign_keys;

      bool status;

      //===--------------------------------------------------------------------===//
      // CreateStmt --> ColumnInfo --> CreateTable
      //===--------------------------------------------------------------------===//
      if (schema != NULL) {
        DDLUtils::ParsingCreateStmt(Cstmt, column_infos, foreign_keys);

        DDLTable::CreateTable(relation_oid, relation_name, column_infos);
      }

      //===--------------------------------------------------------------------===//
      // Set Reference Tables
      //===--------------------------------------------------------------------===//
      status = DDLTable::SetReferenceTables(foreign_keys, relation_oid);
      if (status == false) {
        LOG_WARN("Failed to set reference tables");
      }
    }
  }

  //===--------------------------------------------------------------------===//
  // Rerun query
  //===--------------------------------------------------------------------===//
  for( auto parsetree : parsetree_stack ){
    DDL::ProcessUtility(parsetree,"rerun", status, txn_id);
  }
  parsetree_stack.clear();

  return true;
}
/**
 * @brief Execute the alter stmt.
 * @param the parsetree
 * @param the parsetree_stack store parsetree if the table is not created yet
 * @return true if we handled it correctly, false otherwise
 */
bool DDLTable::ExecAlterTableStmt(Node* parsetree,
                                  std::vector<Node*>& parsetree_stack) {
  AlterTableStmt* atstmt = (AlterTableStmt*)parsetree;

  Oid relation_oid = atstmt->relation_id;
  List* stmts = atstmt->stmts;

  // If table has not been created yet, store it into the parsetree stack
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(Bridge::GetCurrentDatabaseOid());
  if (nullptr == db->GetTableWithOid(relation_oid)){
    parsetree_stack.push_back(parsetree);
    return true;
  }

  ListCell* l;
  foreach (l, stmts) {
    Node* stmt = (Node*)lfirst(l);
    if (IsA(stmt, AlterTableStmt)) {
      DDLTable::AlterTable(relation_oid, (AlterTableStmt*)stmt);
    }
  }
  return true;
}

/**
 * @brief Execute the drop stmt.
 * @param the parse tree
 * @return true if we handled it correctly, false otherwise
 */
bool DDLTable::ExecDropStmt(Node* parsetree) {
  DropStmt* drop = (DropStmt*)parsetree;
  // TODO drop->behavior;   /* RESTRICT or CASCADE behavior */

  ListCell* cell;
  foreach (cell, drop->objects) {
    List* names = ((List*)lfirst(cell));

    switch (drop->removeType) {
      case OBJECT_DATABASE: {
        char* database_name = strVal(linitial(names));
        Oid database_oid = get_database_oid(database_name, true);

        DDLDatabase::DropDatabase(database_oid);
      } break;

      case OBJECT_TABLE: {
        char* table_name = strVal(linitial(names));

        auto& manager = catalog::Manager::GetInstance();
        storage::Database* db = manager.GetDatabaseWithOid(Bridge::GetCurrentDatabaseOid());
        auto table = db->GetTableWithName(table_name);

        // skip if no table
        if( table == nullptr) break;

        Oid table_oid = table->GetOid();
        DDLTable::DropTable(table_oid);
      } break;

      default: {
        LOG_WARN("Unsupported drop object %d ", drop->removeType);
      } break;
    }
  }
  return true;
}

/**
 * @brief Create table.
 * @param table_name Table name
 * @param column_infos Information about the columns
 * @param schema Schema for the table
 * @return true if we created a table, false otherwise
 */
bool DDLTable::CreateTable(Oid relation_oid, std::string table_name,
                           std::vector<catalog::Column> column_infos,
                           catalog::Schema* schema) {
  assert(!table_name.empty());

  Oid database_oid = Bridge::GetCurrentDatabaseOid();
  if (database_oid == INVALID_OID || relation_oid == INVALID_OID) return false;

  // Get db oid
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(database_oid);

  // Construct our schema from vector of ColumnInfo
  if (schema == NULL) schema = new catalog::Schema(column_infos);

  // Build a table from schema
  storage::DataTable* table = storage::TableFactory::GetDataTable(
      database_oid, relation_oid, schema, table_name);

  db->AddTable(table);

  if(table != nullptr) {
    LOG_INFO("Created table(%u)%s in database(%u) ", relation_oid, table_name.c_str(), database_oid);
    return true;
  }
  return false;
}

/**
 * @brief AlterTable with given AlterTableStmt
 * @param relation_oid relation oid
 * @param Astmt AlterTableStmt
 * @return true if we alter the table successfully, false otherwise
 */
bool DDLTable::AlterTable(Oid relation_oid, AlterTableStmt* Astmt) {
  ListCell* lcmd;
  foreach (lcmd, Astmt->cmds) {
  AlterTableCmd* cmd = (AlterTableCmd*)lfirst(lcmd);

    switch (cmd->subtype) {
      // case AT_AddColumn:  /* add column */
      // case AT_DropColumn:  /* drop column */

      case AT_AddConstraint: /* ADD CONSTRAINT */
        {
          bool status = AddConstraint(relation_oid, (Constraint*)cmd->def);

          if (status == false) {
            LOG_WARN("Failed to add constraint");
          }
          break;
        }
      default:
        break;
    }
  }

  LOG_INFO("Alter the table (%u)\n", relation_oid);
  return true;
}

/**
 * @brief Drop table.
 * @param table_oid Table id.
 * @return true if we dropped the table, false otherwise
 */
// FIXME :: Dependencies btw indexes and tables
bool DDLTable::DropTable(Oid table_oid) {
  oid_t database_oid = Bridge::GetCurrentDatabaseOid();

  if (database_oid == InvalidOid || table_oid == InvalidOid) {
    LOG_WARN("Could not drop table :: db oid : %u table oid : %u", database_oid,
             table_oid);
    return false;
  }

  // Get db with current database oid
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(database_oid);

  db->DropTableWithOid(table_oid);

  LOG_INFO("Dropped table with oid : %u\n", table_oid);

  return true;
}

/**
 * @brief Add new constraint to the table
 * @param relation_oid relation oid
 * @param constraint constraint
 * @return true if we add the constraint, false otherwise
 */
bool DDLTable::AddConstraint(Oid relation_oid, Constraint* constraint) {
  ConstraintType contype = PostgresConstraintTypeToPelotonConstraintType(
      (PostgresConstraintType)constraint->contype);
  std::vector<catalog::ForeignKey> foreign_keys;

  std::string conname;
  if (constraint->conname != NULL) {
    conname = constraint->conname;
  } else {
    conname = "";
  }

  // FIXME
  // Create a new constraint

  switch(contype){
    std::cout << "const type : " << ConstraintTypeToString(contype) << std::endl;

    case CONSTRAINT_TYPE_FOREIGN: {
      oid_t database_oid = Bridge::GetCurrentDatabaseOid();
      assert(database_oid);

      auto& manager = catalog::Manager::GetInstance();
      storage::Database* db = manager.GetDatabaseWithOid(database_oid);

      // PrimaryKey Table
      oid_t PrimaryKeyTableId =
          db->GetTableWithName(constraint->pktable->relname)->GetOid();

      // Each table column names
      std::vector<std::string> pk_column_names;
      std::vector<std::string> fk_column_names;

      ListCell* column;
      if (constraint->pk_attrs != NULL && constraint->pk_attrs->length > 0) {
        foreach (column, constraint->pk_attrs) {
          char* attname = strVal(lfirst(column));
          pk_column_names.push_back(attname);
        }
      }
      if (constraint->fk_attrs != NULL && constraint->fk_attrs->length > 0) {
        foreach (column, constraint->fk_attrs) {
          char* attname = strVal(lfirst(column));
          fk_column_names.push_back(attname);
        }
      }

      catalog::ForeignKey* foreign_key = new catalog::ForeignKey(
          PrimaryKeyTableId, pk_column_names, fk_column_names,
          constraint->fk_upd_action, constraint->fk_del_action, conname);
      // new_constraint  = new catalog::Constraint(contype, conname);
      foreign_keys.push_back(*foreign_key);

    } break;
    default:
      LOG_WARN("Unrecognized constraint type %d\n", (int)contype);
      break;
  }

  // FIXME :
  bool status = SetReferenceTables(foreign_keys, relation_oid);
  if (status == false) {
    LOG_WARN("Failed to set reference tables");
  }

  return true;
}

/**
 * @brief Set Reference Tables
 * @param reference table namees  reference table names
 * @param relation_oid relation oid
 * @return true if we set the reference tables, false otherwise
 */
bool DDLTable::SetReferenceTables(
    std::vector<catalog::ForeignKey>& foreign_keys, oid_t relation_oid) {
  assert(relation_oid);
  oid_t database_oid = Bridge::GetCurrentDatabaseOid();
  assert(database_oid);

  storage::DataTable* current_table =
      (storage::DataTable*)catalog::Manager::GetInstance().GetTableWithOid(
          database_oid, relation_oid);

  for (auto foreign_key : foreign_keys) {
    current_table->AddForeignKey(&foreign_key);
  }

  return true;
}

}  // namespace bridge
}  // namespace peloton
<commit_msg>Minor fix<commit_after>/*-------------------------------------------------------------------------
 *
 * ddl_table.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/ddl_table.cpp
 *
 *-------------------------------------------------------------------------
 */

#include <cassert>
#include <iostream>
#include <vector>

#include "backend/bridge/ddl/ddl.h"
#include "backend/bridge/ddl/ddl_table.h"
#include "backend/bridge/ddl/ddl_database.h"
#include "backend/bridge/ddl/ddl_utils.h"
#include "backend/common/logger.h"
#include "backend/storage/backend_vm.h"
#include "backend/storage/table_factory.h"
#include "backend/storage/database.h"

#include "commands/dbcommands.h"
#include "nodes/pg_list.h"
#include "parser/parse_utilcmd.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// Table DDL
//===--------------------------------------------------------------------===//

/**
 * @brief Execute the create stmt.
 * @param the parse tree
 * @param query string
 * @return true if we handled it correctly, false otherwise
 */

bool DDLTable::ExecCreateStmt(Node* parsetree,
                              std::vector<Node*>& parsetree_stack,
                              Peloton_Status* status,
                              TransactionId txn_id) {

  List* stmts = ((CreateStmt*)parsetree)->stmts;

  /* ... and do it */
  ListCell* l;
  foreach (l, stmts) {
    Node* stmt = (Node*)lfirst(l);
    if (IsA(stmt, CreateStmt)) {
      CreateStmt* Cstmt = (CreateStmt*)stmt;
      List* schema = (List*)(Cstmt->tableElts);

      // Relation name and oid
      char* relation_name = Cstmt->relation->relname;
      Oid relation_oid = ((CreateStmt*)parsetree)->relation_id;

      assert(relation_oid);

      std::vector<catalog::Column> column_infos;
      std::vector<catalog::ForeignKey> foreign_keys;

      bool status;

      //===--------------------------------------------------------------------===//
      // CreateStmt --> ColumnInfo --> CreateTable
      //===--------------------------------------------------------------------===//
      if (schema != NULL) {
        DDLUtils::ParsingCreateStmt(Cstmt, column_infos, foreign_keys);

        DDLTable::CreateTable(relation_oid, relation_name, column_infos);
      }

      //===--------------------------------------------------------------------===//
      // Set Reference Tables
      //===--------------------------------------------------------------------===//
      status = DDLTable::SetReferenceTables(foreign_keys, relation_oid);
      if (status == false) {
        LOG_WARN("Failed to set reference tables");
      }
    }
  }

  //===--------------------------------------------------------------------===//
  // Rerun query
  //===--------------------------------------------------------------------===//
  for( auto parsetree : parsetree_stack ){
    DDL::ProcessUtility(parsetree,"rerun", status, txn_id);
  }
  parsetree_stack.clear();

  return true;
}
/**
 * @brief Execute the alter stmt.
 * @param the parsetree
 * @param the parsetree_stack store parsetree if the table is not created yet
 * @return true if we handled it correctly, false otherwise
 */
bool DDLTable::ExecAlterTableStmt(Node* parsetree,
                                  std::vector<Node*>& parsetree_stack) {
  AlterTableStmt* atstmt = (AlterTableStmt*)parsetree;

  Oid relation_oid = atstmt->relation_id;
  List* stmts = atstmt->stmts;

  // If table has not been created yet, store it into the parsetree stack
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(Bridge::GetCurrentDatabaseOid());
  if (nullptr == db->GetTableWithOid(relation_oid)){
    parsetree_stack.push_back(parsetree);
    return true;
  }

  ListCell* l;
  foreach (l, stmts) {
    Node* stmt = (Node*)lfirst(l);
    if (IsA(stmt, AlterTableStmt)) {
      DDLTable::AlterTable(relation_oid, (AlterTableStmt*)stmt);
    }
  }
  return true;
}

/**
 * @brief Execute the drop stmt.
 * @param the parse tree
 * @return true if we handled it correctly, false otherwise
 */
bool DDLTable::ExecDropStmt(Node* parsetree) {
  DropStmt* drop = (DropStmt*)parsetree;
  // TODO drop->behavior;   /* RESTRICT or CASCADE behavior */

  ListCell* cell;
  foreach (cell, drop->objects) {
    List* names = ((List*)lfirst(cell));

    switch (drop->removeType) {
      case OBJECT_DATABASE: {
        char* database_name = strVal(linitial(names));
        Oid database_oid = get_database_oid(database_name, true);

        DDLDatabase::DropDatabase(database_oid);
      } break;

      case OBJECT_TABLE: {
        char* table_name = strVal(linitial(names));

        auto& manager = catalog::Manager::GetInstance();
        storage::Database* db = manager.GetDatabaseWithOid(Bridge::GetCurrentDatabaseOid());
        auto table = db->GetTableWithName(table_name);

        // skip if no table
        if( table == nullptr) break;

        Oid table_oid = table->GetOid();
        DDLTable::DropTable(table_oid);
      } break;

      default: {
        LOG_WARN("Unsupported drop object %d ", drop->removeType);
      } break;
    }
  }
  return true;
}

/**
 * @brief Create table.
 * @param table_name Table name
 * @param column_infos Information about the columns
 * @param schema Schema for the table
 * @return true if we created a table, false otherwise
 */
bool DDLTable::CreateTable(Oid relation_oid, std::string table_name,
                           std::vector<catalog::Column> column_infos,
                           catalog::Schema* schema) {
  assert(!table_name.empty());

  Oid database_oid = Bridge::GetCurrentDatabaseOid();
  if (database_oid == INVALID_OID || relation_oid == INVALID_OID) return false;

  // Get db oid
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(database_oid);

  // Construct our schema from vector of ColumnInfo
  if (schema == NULL) schema = new catalog::Schema(column_infos);

  // Build a table from schema
  storage::DataTable* table = storage::TableFactory::GetDataTable(
      database_oid, relation_oid, schema, table_name);

  db->AddTable(table);

  if(table != nullptr) {
    LOG_INFO("Created table(%u)%s in database(%u) ", relation_oid, table_name.c_str(), database_oid);
    return true;
  }
  return false;
}

/**
 * @brief AlterTable with given AlterTableStmt
 * @param relation_oid relation oid
 * @param Astmt AlterTableStmt
 * @return true if we alter the table successfully, false otherwise
 */
bool DDLTable::AlterTable(Oid relation_oid, AlterTableStmt* Astmt) {
  ListCell* lcmd;
  foreach (lcmd, Astmt->cmds) {
  AlterTableCmd* cmd = (AlterTableCmd*)lfirst(lcmd);

    switch (cmd->subtype) {
      // case AT_AddColumn:  /* add column */
      // case AT_DropColumn:  /* drop column */

      case AT_AddConstraint: /* ADD CONSTRAINT */
        {
          bool status = AddConstraint(relation_oid, (Constraint*)cmd->def);

          if (status == false) {
            LOG_WARN("Failed to add constraint");
          }
          break;
        }
      default:
        break;
    }
  }

  LOG_INFO("Alter the table (%u)\n", relation_oid);
  return true;
}

/**
 * @brief Drop table.
 * @param table_oid Table id.
 * @return true if we dropped the table, false otherwise
 */
// FIXME :: Dependencies btw indexes and tables
bool DDLTable::DropTable(Oid table_oid) {
  oid_t database_oid = Bridge::GetCurrentDatabaseOid();

  if (database_oid == InvalidOid || table_oid == InvalidOid) {
    LOG_WARN("Could not drop table :: db oid : %u table oid : %u", database_oid,
             table_oid);
    return false;
  }

  // Get db with current database oid
  auto& manager = catalog::Manager::GetInstance();
  storage::Database* db = manager.GetDatabaseWithOid(database_oid);

  db->DropTableWithOid(table_oid);

  LOG_INFO("Dropped table with oid : %u\n", table_oid);

  return true;
}

/**
 * @brief Add new constraint to the table
 * @param relation_oid relation oid
 * @param constraint constraint
 * @return true if we add the constraint, false otherwise
 */
bool DDLTable::AddConstraint(Oid relation_oid, Constraint* constraint) {
  ConstraintType contype = PostgresConstraintTypeToPelotonConstraintType(
      (PostgresConstraintType)constraint->contype);
  std::vector<catalog::ForeignKey> foreign_keys;
  std::string conname;

  if (constraint->conname != NULL) {
    conname = constraint->conname;
  } else {
    conname = "";
  }

  switch(contype){
    case CONSTRAINT_TYPE_FOREIGN: {
      oid_t database_oid = Bridge::GetCurrentDatabaseOid();
      assert(database_oid);

      auto& manager = catalog::Manager::GetInstance();
      storage::Database* db = manager.GetDatabaseWithOid(database_oid);

      // PrimaryKey Table
      oid_t PrimaryKeyTableId =
          db->GetTableWithName(constraint->pktable->relname)->GetOid();

      // Each table column names
      std::vector<std::string> pk_column_names;
      std::vector<std::string> fk_column_names;

      ListCell* column;
      if (constraint->pk_attrs != NULL && constraint->pk_attrs->length > 0) {
        foreach (column, constraint->pk_attrs) {
          char* attname = strVal(lfirst(column));
          pk_column_names.push_back(attname);
        }
      }
      if (constraint->fk_attrs != NULL && constraint->fk_attrs->length > 0) {
        foreach (column, constraint->fk_attrs) {
          char* attname = strVal(lfirst(column));
          fk_column_names.push_back(attname);
        }
      }

      catalog::ForeignKey* foreign_key = new catalog::ForeignKey(
          PrimaryKeyTableId, pk_column_names, fk_column_names,
          constraint->fk_upd_action, constraint->fk_del_action, conname);
      foreign_keys.push_back(*foreign_key);

    } break;
    default:
      LOG_WARN("Unrecognized constraint type %d\n", (int)contype);
      break;
  }

  // FIXME :
  bool status = SetReferenceTables(foreign_keys, relation_oid);
  if (status == false) {
    LOG_WARN("Failed to set reference tables");
  }

  return true;
}

/**
 * @brief Set Reference Tables
 * @param reference table namees  reference table names
 * @param relation_oid relation oid
 * @return true if we set the reference tables, false otherwise
 */
bool DDLTable::SetReferenceTables(
    std::vector<catalog::ForeignKey>& foreign_keys, oid_t relation_oid) {
  assert(relation_oid);
  oid_t database_oid = Bridge::GetCurrentDatabaseOid();
  assert(database_oid);

  storage::DataTable* current_table =
      (storage::DataTable*)catalog::Manager::GetInstance().GetTableWithOid(
          database_oid, relation_oid);

  for (auto foreign_key : foreign_keys) {
    current_table->AddForeignKey(&foreign_key);
  }

  return true;
}

}  // namespace bridge
}  // namespace peloton
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 *
 * ddl_utilities.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/ddl_utilities.cpp
 *
 *-------------------------------------------------------------------------
 */

#include <cassert>
#include <iostream>

#include "backend/bridge/ddl/ddl_utils.h"
#include "backend/common/logger.h"
#include "backend/storage/database.h"

#include "miscadmin.h"
#include "parser/parse_utilcmd.h"
#include "parser/parse_type.h"
#include "access/htup_details.h"
#include "utils/resowner.h"
#include "utils/syscache.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// DDL Utils
//===--------------------------------------------------------------------===//

/**
 * @brief parsing create statement
 * @param Cstmt a create statement
 * @param column_infos to create a table
 * @param refernce_table_infos to store reference table to the table
 */
void DDLUtils::ParsingCreateStmt(CreateStmt* Cstmt,
                                 std::vector<catalog::Column>& column_infos,
                                 std::vector<catalog::ForeignKey>& foreign_keys
) {
  assert(Cstmt);

  //===--------------------------------------------------------------------===//
  // Column Infomation
  //===--------------------------------------------------------------------===//

  // Get the column list from the create statement
  List* ColumnList = (List*)(Cstmt->tableElts);

  // Parse the CreateStmt and construct ColumnInfo
  ListCell   *entry;
  foreach(entry, ColumnList){

    ColumnDef  *coldef = static_cast<ColumnDef *>(lfirst(entry));

    // Get the type oid and type mod with given typeName
    Oid typeoid = typenameTypeId(NULL, coldef->typeName);
    int32 typemod;
    typenameTypeIdAndMod(NULL, coldef->typeName, &typeoid, &typemod);

    // Get type length
    Type tup = typeidType(typeoid);
    int typelen = typeLen(tup);
    ReleaseSysCache(tup);

    // For a fixed-size type, typlen is the number of bytes in the internal
    // representation of the type. But for a variable-length type, typlen is negative.
    if(typelen == - 1)
      typelen = typemod;

    ValueType column_valueType = PostgresValueTypeToPelotonValueType((PostgresValueType) typeoid);
    int column_length = typelen;
    std::string column_name = coldef->colname;

    //===--------------------------------------------------------------------===//
    // Column Constraint
    //===--------------------------------------------------------------------===//

    std::vector<catalog::Constraint> column_constraints;

    if(coldef->raw_default != NULL){
      catalog::Constraint constraint(CONSTRAINT_TYPE_DEFAULT, "", coldef->raw_default);
      column_constraints.push_back(constraint);
    };

    if(coldef->constraints != NULL){
      ListCell* constNodeEntry;

      foreach(constNodeEntry, coldef->constraints)
      {
        Constraint* ConstraintNode = static_cast<Constraint*>(lfirst(constNodeEntry));
        ConstraintType contype;
        std::string conname;

        // CONSTRAINT TYPE
        contype = PostgresConstraintTypeToPelotonConstraintType((PostgresConstraintType) ConstraintNode->contype);

        // CONSTRAINT NAME
        if(ConstraintNode->conname != NULL){
          conname = ConstraintNode->conname;
        }else{
          conname = "";
        }

        catalog::Constraint* constraint;

        switch(contype){

          case CONSTRAINT_TYPE_NULL:
            constraint = new catalog::Constraint(contype, conname);
            break;
          case CONSTRAINT_TYPE_NOTNULL:
            constraint = new catalog::Constraint(contype, conname);
            break;
          case CONSTRAINT_TYPE_CHECK:
            constraint = new catalog::Constraint(contype, conname, ConstraintNode->raw_expr);
            break;
          case CONSTRAINT_TYPE_PRIMARY:
            constraint = new catalog::Constraint(contype, conname);
            break;
          case CONSTRAINT_TYPE_UNIQUE:
            continue;
          case CONSTRAINT_TYPE_FOREIGN:
          {
            // REFERENCE TABLE NAME AND ACTION OPTION
            if(ConstraintNode->pktable != NULL){

              auto& manager = catalog::Manager::GetInstance();
              storage::Database* db = manager.GetDatabaseWithOid(Bridge::GetCurrentDatabaseOid());

              // PrimaryKey Table
              oid_t PrimaryKeyTableId = db->GetTableWithName(ConstraintNode->pktable->relname)->GetOid();

              // Each table column names
              std::vector<std::string> pk_column_names;
              std::vector<std::string> fk_column_names;

              ListCell   *column;
              if(ConstraintNode->pk_attrs != NULL && ConstraintNode->pk_attrs->length > 0){
                foreach(column, ConstraintNode->pk_attrs){
                  char* attname = strVal(lfirst(column));
                  pk_column_names.push_back(attname);
                }
              }
              if(ConstraintNode->fk_attrs != NULL && ConstraintNode->fk_attrs->length > 0){
                foreach(column, ConstraintNode->fk_attrs){
                  char* attname = strVal(lfirst(column));
                  fk_column_names.push_back(attname);
                }
              }

              catalog::ForeignKey*foreign_key = new catalog::ForeignKey(PrimaryKeyTableId,
                                                                        pk_column_names,
                                                                        fk_column_names,
                                                                        ConstraintNode->fk_upd_action,
                                                                        ConstraintNode->fk_del_action,
                                                                        conname);

              foreign_keys.push_back(*foreign_key);
            }
            continue;
          }
          default:
          {
            constraint = new catalog::Constraint(contype, conname);
            LOG_WARN("Unrecognized constraint type %d\n", (int) contype);
            break;
          }
        }

        column_constraints.push_back(*constraint);
      }
    }// end of parsing constraint

    catalog::Column column_info(column_valueType,
                                column_length,
                                column_name,
                                false);

    // Insert column_info into ColumnInfos
    column_infos.push_back(column_info);
  }// end of parsing column list
}

} // namespace bridge
} // namespace peloton
<commit_msg>Refactoring<commit_after>/*-------------------------------------------------------------------------
 *
 * ddl_utilities.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/ddl_utilities.cpp
 *
 *-------------------------------------------------------------------------
 */

#include <cassert>
#include <iostream>

#include "backend/bridge/ddl/ddl_utils.h"
#include "backend/common/logger.h"
#include "backend/storage/database.h"

#include "miscadmin.h"
#include "parser/parse_utilcmd.h"
#include "parser/parse_type.h"
#include "access/htup_details.h"
#include "utils/resowner.h"
#include "utils/syscache.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// DDL Utils
//===--------------------------------------------------------------------===//

/**
 * @brief parsing create statement
 * @param Cstmt a create statement
 * @param column_infos to create a table
 * @param refernce_table_infos to store reference table to the table
 */
void DDLUtils::ParsingCreateStmt(CreateStmt* Cstmt,
                                 std::vector<catalog::Column>& column_infos,
                                 std::vector<catalog::ForeignKey>& foreign_keys
) {
  assert(Cstmt);

  //===--------------------------------------------------------------------===//
  // Column Infomation
  //===--------------------------------------------------------------------===//

  // Get the column list from the create statement
  List* ColumnList = (List*)(Cstmt->tableElts);

  // Parse the CreateStmt and construct ColumnInfo
  ListCell   *entry;
  foreach(entry, ColumnList){

    ColumnDef  *coldef = static_cast<ColumnDef *>(lfirst(entry));

    // Get the type oid and type mod with given typeName
    Oid typeoid = typenameTypeId(NULL, coldef->typeName);
    int32 typemod;
    typenameTypeIdAndMod(NULL, coldef->typeName, &typeoid, &typemod);

    // Get type length
    Type tup = typeidType(typeoid);
    int typelen = typeLen(tup);
    ReleaseSysCache(tup);

    // For a fixed-size type, typlen is the number of bytes in the internal
    // representation of the type. But for a variable-length type, typlen is negative.
    if(typelen == - 1)
      typelen = typemod;

    ValueType column_valueType = PostgresValueTypeToPelotonValueType((PostgresValueType) typeoid);
    int column_length = typelen;
    std::string column_name = coldef->colname;

    //===--------------------------------------------------------------------===//
    // Column Constraint
    //===--------------------------------------------------------------------===//

    std::vector<catalog::Constraint> column_constraints;

    if(coldef->raw_default != NULL){
      catalog::Constraint constraint(CONSTRAINT_TYPE_DEFAULT, "", coldef->raw_default);
      column_constraints.push_back(constraint);
    };

    if(coldef->constraints != NULL){
      ListCell* constNodeEntry;

      foreach(constNodeEntry, coldef->constraints)
      {
        Constraint* ConstraintNode = static_cast<Constraint*>(lfirst(constNodeEntry));
        ConstraintType contype;
        std::string conname;

        // CONSTRAINT TYPE
        contype = PostgresConstraintTypeToPelotonConstraintType((PostgresConstraintType) ConstraintNode->contype);

        // CONSTRAINT NAME
        if(ConstraintNode->conname != NULL){
          conname = ConstraintNode->conname;
        }else{
          conname = "";
        }

        switch(contype){
          case CONSTRAINT_TYPE_UNIQUE:
            continue;

          case CONSTRAINT_TYPE_NULL:
          case CONSTRAINT_TYPE_NOTNULL:
          case CONSTRAINT_TYPE_PRIMARY:{
            catalog::Constraint constraint(contype, conname);
            column_constraints.push_back(constraint);
            break;
          }
          case CONSTRAINT_TYPE_CHECK:{
            catalog::Constraint constraint(contype, conname, ConstraintNode->raw_expr);
            column_constraints.push_back(constraint);
            break;
          }
          case CONSTRAINT_TYPE_DEFAULT:{
            catalog::Constraint constraint(contype, conname, coldef->raw_default);
            column_constraints.push_back(constraint);
            break;
          }
          case CONSTRAINT_TYPE_FOREIGN:
          {
            // REFERENCE TABLE NAME AND ACTION OPTION
            if(ConstraintNode->pktable != NULL){

              auto& manager = catalog::Manager::GetInstance();
              storage::Database* db = manager.GetDatabaseWithOid(Bridge::GetCurrentDatabaseOid());

              // PrimaryKey Table
              oid_t PrimaryKeyTableId = db->GetTableWithName(ConstraintNode->pktable->relname)->GetOid();

              // Each table column names
              std::vector<std::string> pk_column_names;
              std::vector<std::string> fk_column_names;

              ListCell   *column;
              if(ConstraintNode->pk_attrs != NULL && ConstraintNode->pk_attrs->length > 0){
                foreach(column, ConstraintNode->pk_attrs){
                  char* attname = strVal(lfirst(column));
                  pk_column_names.push_back(attname);
                }
              }
              if(ConstraintNode->fk_attrs != NULL && ConstraintNode->fk_attrs->length > 0){
                foreach(column, ConstraintNode->fk_attrs){
                  char* attname = strVal(lfirst(column));
                  fk_column_names.push_back(attname);
                }
              }

              catalog::ForeignKey*foreign_key = new catalog::ForeignKey(PrimaryKeyTableId,
                                                                        pk_column_names,
                                                                        fk_column_names,
                                                                        ConstraintNode->fk_upd_action,
                                                                        ConstraintNode->fk_del_action,
                                                                        conname);

              foreign_keys.push_back(*foreign_key);
            }
            continue;
          }
          default:
          {
            LOG_WARN("Unrecognized constraint type %d\n", (int) contype);
            break;
          }
        }
      }
    }// end of parsing constraint

    catalog::Column column_info(column_valueType,
                                column_length,
                                column_name,
                                false);

    // Insert column_info into ColumnInfos
    column_infos.push_back(column_info);
  }// end of parsing column list
}

} // namespace bridge
} // namespace peloton
<|endoftext|>


<commit_before>/*
TLD's work well w/ features (keypts) low-level features

- DoT works well with textureless objects (contoures)
- Use both to bootstrap a contour and features based reconstruction
- Does going to 3D from contour make tracking possible ??

*/
#define WINDOW_NAME "TLD Segmenter"

#include <set>
#include <bot_core/bot_core.h>
#include <bot_frames/bot_frames.h>
#include <bot_param/param_client.h>

#include <opencv2/opencv.hpp>

#include <image_io_utils/image_io_utils.hpp> // to simplify jpeg/zlib compression and decompression
#include <lcmtypes/perception_image_roi_t.h>
#include <ConciseArgs>

const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 800;

int MAX_IMAGE_WIDTH = 0;
int MAX_IMAGE_HEIGHT = 0;

int32_t OBJECT_ID = 1;
int32_t FEATURE_ID = 1; // 1 for object (reference), -1 for virtual heading object
using namespace cv;

struct state_t {
    lcm_t *lcm;
    pthread_t lcm_thread;
    pthread_mutex_t img_mutex;

    GMainLoop *mainloop;
    BotParam *param;
    BotFrames *frames;
    int counter;

    // Img
    cv::Mat img;

    // utimes for image
    int64_t  img_utime;

    // UI selection of desired object
    Rect selection, selection_virtual, tld_result;
    Point origin, origin_virtual;
    bool selectObject, selectObject_virtual;

    perception_image_roi_t *tracking_result;

    state_t () {
        // LCM, BotFrames, BotParam inits
        lcm =  bot_lcm_get_global(NULL);
        param = bot_param_new_from_server(lcm, 1);
        frames = bot_frames_get_global (lcm, param);

        img_mutex = PTHREAD_MUTEX_INITIALIZER;
        // Counter for debug prints
        counter = 0;
        tracking_result = NULL;
        selectObject = false;
        selectObject_virtual = false;
    }
    ~state_t () {
    }

};
state_t * state = NULL;

void* lcm_thread_handler(void *l) {
    state_t* state = (state_t*)l;
    while(1)
        lcm_handle(state->lcm);

}
struct MouseEvent {
    MouseEvent() { event = -1; buttonState = 0; }
    Point pt;
    int event;
    int buttonState;
};
MouseEvent mouse;

static void onMouse(int event, int x, int y, int flags, void* userdata) {
    MouseEvent* data = (MouseEvent*)userdata;

    float sx = 1.f / WINDOW_WIDTH ;
    float sy = 1.f / WINDOW_HEIGHT;

    if (state->selectObject) {
        state->selection.x = MIN(x, state->origin.x);
        state->selection.y = MIN(y, state->origin.y);
        state->selection.width = std::abs(x - state->origin.x);
        state->selection.height = std::abs(y - state->origin.y);
        state->selection &= Rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
    }

    if (state->selectObject_virtual) {
        state->selection_virtual.x = MIN(x, state->origin_virtual.x);
        state->selection_virtual.y = MIN(y, state->origin_virtual.y);
        state->selection_virtual.width = std::abs(x - state->origin_virtual.x);
        state->selection_virtual.height = std::abs(y - state->origin_virtual.y);
        state->selection &= Rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
    }

    switch (event) {
    case CV_EVENT_RBUTTONDOWN:
        state->origin_virtual = Point(x, y);
        state->selection_virtual = Rect(x, y, 0, 0);
        state->selectObject_virtual = true;
        break;
    case CV_EVENT_RBUTTONUP:
        state->selectObject_virtual = false;
        std::cerr << "SEND virtual selection: " << state->img_utime << " - " <<
            state->selection_virtual.x << " " << state->selection_virtual.y << " " <<
            state->selection_virtual.width << " " << state->selection_virtual.height << std::endl;

        perception_image_roi_t img_vselection;
        img_vselection.utime = state->img_utime;
        img_vselection.object_id = OBJECT_ID;
        img_vselection.feature_id = -1; // FEATURE_ID;
        img_vselection.roi.x = state->selection_virtual.x * sx;
        img_vselection.roi.y = state->selection_virtual.y * sy;
        img_vselection.roi.width = state->selection_virtual.width * sx;
        img_vselection.roi.height = state->selection_virtual.height * sy;
        perception_image_roi_t_publish(state->lcm, "TLD_OBJECT_ROI", &img_vselection);

        // destroyWindow(WINDOW_NAME);
        // state->img = cv::Mat();

        break;
    case CV_EVENT_LBUTTONDOWN:
        state->origin = Point(x, y);
        state->selection = Rect(x, y, 0, 0);
        state->selectObject = true;

        // reset virtual feature
        state->selection_virtual = Rect(0,0,0,0);

        break;
    case CV_EVENT_LBUTTONUP:
        state->selectObject = false;
        std::cerr << "SEND selection: " << state->img_utime << " - " <<
            state->selection.x << " " << state->selection.y << " " <<
            state->selection.width << " " << state->selection.height << std::endl;

        perception_image_roi_t img_selection;
        img_selection.utime = state->img_utime;
        img_selection.object_id = OBJECT_ID;
        img_selection.feature_id = 1; // FEATURE_ID;
        img_selection.roi.x = state->selection.x * sx;
        img_selection.roi.y = state->selection.y * sy;
        img_selection.roi.width = state->selection.width * sx;
        img_selection.roi.height = state->selection.height * sy;
        perception_image_roi_t_publish(state->lcm, "TLD_OBJECT_ROI", &img_selection);
        // destroyWindow(WINDOW_NAME);
        // state->img = cv::Mat();

        break;
    }
    return;
}

void  INThandler(int sig)
{
    printf("Exiting\n");
    if (state) delete state;
    exit(0);
}

void
decode_image(const bot_core_image_t * msg, cv::Mat& img)
{
    int ch = msg->row_stride / (msg->width);
    if (img.empty() || img.rows != msg->height || img.cols != msg->width)
        if (ch == 3)
            img.create(msg->height, msg->width, CV_8UC3);
        else
            img.create(msg->height, msg->width, CV_8UC1);
    std::cerr << "msg: " << ch << " " << msg->row_stride << " " << msg->width << "x" << msg->height << std::endl;

  // extract image data
  switch (msg->pixelformat) {
    case BOT_CORE_IMAGE_T_PIXEL_FORMAT_RGB:
        memcpy(img.data, msg->data, sizeof(uint8_t) * msg->width * msg->height * 3);
        cv::cvtColor(img, img, CV_RGB2BGR);
      break;
    case BOT_CORE_IMAGE_T_PIXEL_FORMAT_MJPEG:
      // for some reason msg->row_stride is 0, so we use msg->width instead.
        if (ch == 3) {
            jpeg_decompress_8u_rgb(msg->data,
                                    msg->size,
                                    img.data,
                                    msg->width,
                                    msg->height,
                                    msg->width * ch);
        cv::cvtColor(img, img, CV_RGB2BGR);
        } else {
            jpeg_decompress_8u_gray(msg->data,
                                    msg->size,
                                    img.data,
                                    msg->width,
                                    msg->height,
                                    msg->width);
        }
      break;
  case BOT_CORE_IMAGE_T_PIXEL_FORMAT_GRAY:
      memcpy(img.data, msg->data, sizeof(uint8_t) * msg->width * msg->height);
      break;
    default:
      fprintf(stderr, "Unrecognized image format\n");
      break;
  }
  return;
}

static void on_image_frame (const lcm_recv_buf_t *rbuf, const char *channel,
                            const bot_core_image_t *msg,
                            void *user_data ) {

    if (!msg->width || !msg->height) return;

    if (!MAX_IMAGE_WIDTH || !MAX_IMAGE_HEIGHT) {
        MAX_IMAGE_WIDTH = msg->width;
        MAX_IMAGE_HEIGHT = msg->height;
    }

    pthread_mutex_lock(&state->img_mutex);
    state_t* state = (state_t*) user_data;
    if (state->img.empty() || state->img.rows != msg->height || state->img.cols != msg->width) {
        if (msg->pixelformat == BOT_CORE_IMAGE_T_PIXEL_FORMAT_GRAY) {
            std::cerr << "ERROR: Incoming image is grayscale!! Cannot perform color tracking!!!" << std::endl;
            assert(0);
        } else {
            std::cerr << "One time creation of image" << std::endl;
            state->img.create(msg->height, msg->width, CV_8UC3);
        }
    }
    decode_image(msg, state->img);
    state->img_utime = msg->utime;
    pthread_mutex_unlock(&state->img_mutex);
    return;
}

static void on_result_frame (const lcm_recv_buf_t *rbuf, const char *channel,
                            const perception_image_roi_t *msg,
                            void *user_data ) {
    pthread_mutex_lock(&state->img_mutex);
    state_t* state = (state_t*) user_data;

    if(state->tracking_result != NULL){
        perception_image_roi_t_destroy(state->tracking_result);
    }
    state->tracking_result = perception_image_roi_t_copy(msg);

    state->tld_result.x = msg->roi.x; //MIN(msg->roi.x, state->origin.x);
    state->tld_result.y = msg->roi.y;//MIN(msg->roi.y, state->origin.y);

    state->tld_result.width = msg->roi.width;
    state->tld_result.height = msg->roi.height;
    state->tld_result &= Rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

    pthread_mutex_unlock(&state->img_mutex);
    return;
}

struct TLDSegmenterOptions {
    bool vDEBUG;
    std::string vCHANNEL;

    TLDSegmenterOptions () :
        vCHANNEL(std::string("CAMERALEFT")), vDEBUG(false) {}
};

TLDSegmenterOptions options;

int main(int argc, char** argv)
{
    std::cout << "============= QUICK MODES ===================\n";
    std::cout << "drc-tld-segmenter -c CAMERALEFT\n";
    std::cout << "=============================================\n";

    ConciseArgs opt(argc, (char**)argv);
    opt.add(options.vCHANNEL, "c", "camera-channel","Camera Channel [CAMERALEFT]");
    opt.add(options.vDEBUG, "d", "debug","Debug mode");
    opt.parse();

    std::cerr << "===========  TLD Tracker ============" << std::endl;
    std::cerr << "=> CAMERA CHANNEL : " << options.vCHANNEL << std::endl;
    std::cerr << "=> DEBUG : " << options.vDEBUG << std::endl;
    std::cerr << "===============================================" << std::endl;

    // Install signal handler to free data.
    signal(SIGINT, INThandler);

    // Param server, botframes
    state = new state_t();

    printf("starting lcm thread\n");
    pthread_create(&(state->lcm_thread), NULL, lcm_thread_handler, state);

    cv::namedWindow( WINDOW_NAME );
    cv::setMouseCallback( WINDOW_NAME, onMouse, &mouse);

    // Subscriptions
    bot_core_image_t_subscribe(state->lcm, options.vCHANNEL.c_str(), on_image_frame, (void*)state);
    perception_image_roi_t_subscribe(state->lcm, "TLD_OBJECT_ROI_RESULT", on_result_frame, (void*)state);

    // Install signal handler to free data.
    signal(SIGINT, INThandler);

    while(1) {
        unsigned char c = cv::waitKey(1) & 0xff;
	// lcm_handle(state->lcm);
        if (c == 'q') {
            break;
        // } else if (c == 'd') {
        //     FEATURE_ID++;
        // } else if (c == 'a') {
        //     FEATURE_ID--;
        } else if (c == 'w') {
            OBJECT_ID++;
        } else if (c == 's') {
            OBJECT_ID--;
        }

        pthread_mutex_lock(&state->img_mutex);
        // UI handling
        if (!state->img.empty()) {
            cv::Mat display;
            cv::resize(state->img.clone(), display, cv::Size(WINDOW_WIDTH,WINDOW_HEIGHT));
            if (state->selection.width > 0 && state->selection.height > 0) {

                cv::Mat roi(display, state->selection);
                rectangle(display, state->selection, cv::Scalar(0,255,255), 2);
                // bitwise_not(roi, roi);
            }
            if (state->selection_virtual.width > 0 && state->selection_virtual.height > 0) {

                cv::Mat roi(display, state->selection_virtual);
                rectangle(display, state->selection_virtual, cv::Scalar(0,255,0), 2);
                // bitwise_not(roi, roi);
            }

            if (state->tld_result.width > 0 && state->tld_result.height > 0) {
                cv::Mat roi(display, state->tld_result);
                rectangle(display, state->tld_result, cv::Scalar(0,0,255), 2);
                // bitwise_not(roi, roi);
            }

            // Show OBJECT_ID, FEATURE_ID
            cv::putText(display, cv::format("OBJ: %ld", OBJECT_ID),
                        Point(20,20), 0, .5, cv::Scalar(0,200,0), 2);

            imshow(WINDOW_NAME, display);
        }
        pthread_mutex_unlock(&state->img_mutex);
    }

    // if (state) delete state;
    return 0;
}
<commit_msg>added feedback on the basestation end<commit_after>/*
  TLD's work well w/ features (keypts) low-level features

  - DoT works well with textureless objects (contoures)
  - Use both to bootstrap a contour and features based reconstruction
  - Does going to 3D from contour make tracking possible ??

*/
#define WINDOW_NAME "TLD Segmenter"

#include <set>
#include <bot_core/bot_core.h>
#include <bot_frames/bot_frames.h>
#include <bot_param/param_client.h>

#include <opencv2/opencv.hpp>

#include <image_io_utils/image_io_utils.hpp> // to simplify jpeg/zlib compression and decompression
#include <lcmtypes/perception_image_roi_t.h>
#include <ConciseArgs>

const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 800;

int MAX_IMAGE_WIDTH = 0;
int MAX_IMAGE_HEIGHT = 0;

const int MAX_THUMB_SIZE = 100;

int32_t OBJECT_ID = 1;
int32_t FEATURE_ID = 1; // 1 for object (reference), -1 for virtual heading object
using namespace cv;

struct state_t {
    lcm_t *lcm;
    pthread_t lcm_thread;
    pthread_mutex_t img_mutex;

    GMainLoop *mainloop;
    BotParam *param;
    BotFrames *frames;
    int counter;

    // Img
    cv::Mat img;

    cv::Mat img_selection;

    // utimes for image
    int64_t  img_utime;

    // UI selection of desired object
    Rect selection, selection_virtual, tld_result;
    Point origin, origin_virtual;
    bool selectObject, selectObject_virtual;

    perception_image_roi_t *tracking_result;

    state_t () {
        // LCM, BotFrames, BotParam inits
        lcm =  bot_lcm_get_global(NULL);
        param = bot_param_new_from_server(lcm, 1);
        frames = bot_frames_get_global (lcm, param);

        img_mutex = PTHREAD_MUTEX_INITIALIZER;
        // Counter for debug prints
        counter = 0;
        tracking_result = NULL;
        selectObject = false;
        selectObject_virtual = false;
    }
    ~state_t () {
    }

};
state_t * state = NULL;

void* lcm_thread_handler(void *l) {
    state_t* state = (state_t*)l;
    while(1)
        lcm_handle(state->lcm);

}
struct MouseEvent {
    MouseEvent() { event = -1; buttonState = 0; }
    Point pt;
    int event;
    int buttonState;
};
MouseEvent mouse;

static void onMouse(int event, int x, int y, int flags, void* userdata) {
    MouseEvent* data = (MouseEvent*)userdata;

    float sx = 1.f / WINDOW_WIDTH ;
    float sy = 1.f / WINDOW_HEIGHT;

    if (state->selectObject) {
        state->selection.x = MIN(x, state->origin.x);
        state->selection.y = MIN(y, state->origin.y);
        state->selection.width = std::abs(x - state->origin.x);
        state->selection.height = std::abs(y - state->origin.y);
        state->selection &= Rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

    }

    if (state->selectObject_virtual) {
        state->selection_virtual.x = MIN(x, state->origin_virtual.x);
        state->selection_virtual.y = MIN(y, state->origin_virtual.y);
        state->selection_virtual.width = std::abs(x - state->origin_virtual.x);
        state->selection_virtual.height = std::abs(y - state->origin_virtual.y);
        state->selection &= Rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
    }

    switch (event) {
    case CV_EVENT_RBUTTONDOWN:
        state->origin_virtual = Point(x, y);
        state->selection_virtual = Rect(x, y, 0, 0);
        state->selectObject_virtual = true;
        break;
    case CV_EVENT_RBUTTONUP:
        state->selectObject_virtual = false;
        std::cerr << "SEND virtual selection: " << state->img_utime << " - " <<
            state->selection_virtual.x << " " << state->selection_virtual.y << " " <<
            state->selection_virtual.width << " " << state->selection_virtual.height << std::endl;

        perception_image_roi_t img_vselection;
        img_vselection.utime = state->img_utime;
        img_vselection.object_id = OBJECT_ID;
        img_vselection.feature_id = -1; // FEATURE_ID;
        img_vselection.roi.x = state->selection_virtual.x * sx;
        img_vselection.roi.y = state->selection_virtual.y * sy;
        img_vselection.roi.width = state->selection_virtual.width * sx;
        img_vselection.roi.height = state->selection_virtual.height * sy;
        perception_image_roi_t_publish(state->lcm, "TLD_OBJECT_ROI", &img_vselection);

        // destroyWindow(WINDOW_NAME);
        // state->img = cv::Mat();

        break;
    case CV_EVENT_LBUTTONDOWN:
        state->origin = Point(x, y);
        state->selection = Rect(x, y, 0, 0);
        state->selectObject = true;

        // reset virtual feature
        state->selection_virtual = Rect(0,0,0,0);

        break;
    case CV_EVENT_LBUTTONUP:
        state->selectObject = false;
        std::cerr << "SEND selection: " << state->img_utime << " - " <<
            state->selection.x << " " << state->selection.y << " " <<
            state->selection.width << " " << state->selection.height << std::endl;

        perception_image_roi_t img_selection;
        img_selection.utime = state->img_utime;
        img_selection.object_id = OBJECT_ID;
        img_selection.feature_id = 1; // FEATURE_ID;
        img_selection.roi.x = state->selection.x * sx;
        img_selection.roi.y = state->selection.y * sy;
        img_selection.roi.width = state->selection.width * sx;
        img_selection.roi.height = state->selection.height * sy;
        perception_image_roi_t_publish(state->lcm, "TLD_OBJECT_ROI", &img_selection);

        float sc_x = sx * state->img.cols;
        float sc_y = sy * state->img.rows;

        int x_s = state->selection.x * sc_x;
        int y_s = state->selection.y * sc_y;
        int width_s = state->selection.width * sc_x;
        int height_s = state->selection.height * sc_y;

        if(width_s > 0 && height_s >0){
            state->img_selection = state->img(cv::Rect(x_s, y_s, width_s, height_s)).clone();

        }
        // destroyWindow(WINDOW_NAME);
        // state->img = cv::Mat();

        break;
    }
    return;
}

void  INThandler(int sig)
{
    printf("Exiting\n");
    if (state) delete state;
    exit(0);
}

void
decode_image(const bot_core_image_t * msg, cv::Mat& img)
{
    int ch = msg->row_stride / (msg->width);
    if (img.empty() || img.rows != msg->height || img.cols != msg->width)
        if (ch == 3)
            img.create(msg->height, msg->width, CV_8UC3);
        else
            img.create(msg->height, msg->width, CV_8UC1);
    //std::cerr << "msg: " << ch << " " << msg->row_stride << " " << msg->width << "x" << msg->height << std::endl;

    // extract image data
    switch (msg->pixelformat) {
    case BOT_CORE_IMAGE_T_PIXEL_FORMAT_RGB:
        memcpy(img.data, msg->data, sizeof(uint8_t) * msg->width * msg->height * 3);
        cv::cvtColor(img, img, CV_RGB2BGR);
        break;
    case BOT_CORE_IMAGE_T_PIXEL_FORMAT_MJPEG:
        // for some reason msg->row_stride is 0, so we use msg->width instead.
        if (ch == 3) {
            jpeg_decompress_8u_rgb(msg->data,
                                   msg->size,
                                   img.data,
                                   msg->width,
                                   msg->height,
                                   msg->width * ch);
            cv::cvtColor(img, img, CV_RGB2BGR);
        } else {
            jpeg_decompress_8u_gray(msg->data,
                                    msg->size,
                                    img.data,
                                    msg->width,
                                    msg->height,
                                    msg->width);
        }
        break;
    case BOT_CORE_IMAGE_T_PIXEL_FORMAT_GRAY:
        memcpy(img.data, msg->data, sizeof(uint8_t) * msg->width * msg->height);
        break;
    default:
        fprintf(stderr, "Unrecognized image format\n");
        break;
    }
    return;
}

static void on_image_frame (const lcm_recv_buf_t *rbuf, const char *channel,
                            const bot_core_image_t *msg,
                            void *user_data ) {

    if (!msg->width || !msg->height) return;

    if (!MAX_IMAGE_WIDTH || !MAX_IMAGE_HEIGHT) {
        MAX_IMAGE_WIDTH = msg->width;
        MAX_IMAGE_HEIGHT = msg->height;
    }

    pthread_mutex_lock(&state->img_mutex);
    state_t* state = (state_t*) user_data;
    if (state->img.empty() || state->img.rows != msg->height || state->img.cols != msg->width) {
        if (msg->pixelformat == BOT_CORE_IMAGE_T_PIXEL_FORMAT_GRAY) {
            std::cerr << "ERROR: Incoming image is grayscale!! Cannot perform color tracking!!!" << std::endl;
            assert(0);
        } else {
            std::cerr << "One time creation of image" << std::endl;
            state->img.create(msg->height, msg->width, CV_8UC3);
        }
    }
    decode_image(msg, state->img);
    state->img_utime = msg->utime;
    pthread_mutex_unlock(&state->img_mutex);
    return;
}

static void on_result_frame (const lcm_recv_buf_t *rbuf, const char *channel,
                             const perception_image_roi_t *msg,
                             void *user_data ) {
    pthread_mutex_lock(&state->img_mutex);
    state_t* state = (state_t*) user_data;

    if(state->tracking_result != NULL){
        perception_image_roi_t_destroy(state->tracking_result);
    }
    state->tracking_result = perception_image_roi_t_copy(msg);

    state->tld_result.x = msg->roi.x; //MIN(msg->roi.x, state->origin.x);
    state->tld_result.y = msg->roi.y;//MIN(msg->roi.y, state->origin.y);

    state->tld_result.width = msg->roi.width;
    state->tld_result.height = msg->roi.height;
    state->tld_result &= Rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

    pthread_mutex_unlock(&state->img_mutex);
    return;
}

struct TLDSegmenterOptions {
    bool vDEBUG;
    std::string vCHANNEL;

    TLDSegmenterOptions () :
        vCHANNEL(std::string("CAMERALEFT")), vDEBUG(false) {}
};

TLDSegmenterOptions options;

int main(int argc, char** argv)
{
    std::cout << "============= QUICK MODES ===================\n";
    std::cout << "drc-tld-segmenter -c CAMERALEFT\n";
    std::cout << "=============================================\n";

    ConciseArgs opt(argc, (char**)argv);
    opt.add(options.vCHANNEL, "c", "camera-channel","Camera Channel [CAMERALEFT]");
    opt.add(options.vDEBUG, "d", "debug","Debug mode");
    opt.parse();

    std::cerr << "===========  TLD Tracker ============" << std::endl;
    std::cerr << "=> CAMERA CHANNEL : " << options.vCHANNEL << std::endl;
    std::cerr << "=> DEBUG : " << options.vDEBUG << std::endl;
    std::cerr << "===============================================" << std::endl;

    // Install signal handler to free data.
    signal(SIGINT, INThandler);

    // Param server, botframes
    state = new state_t();

    printf("starting lcm thread\n");
    pthread_create(&(state->lcm_thread), NULL, lcm_thread_handler, state);

    cv::namedWindow( WINDOW_NAME );
    cv::setMouseCallback( WINDOW_NAME, onMouse, &mouse);

    // Subscriptions
    bot_core_image_t_subscribe(state->lcm, options.vCHANNEL.c_str(), on_image_frame, (void*)state);
    perception_image_roi_t_subscribe(state->lcm, "TLD_OBJECT_ROI_RESULT", on_result_frame, (void*)state);

    // Install signal handler to free data.
    signal(SIGINT, INThandler);

    while(1) {
        unsigned char c = cv::waitKey(1) & 0xff;
	// lcm_handle(state->lcm);
        if (c == 'q') {
            break;
            // } else if (c == 'd') {
            //     FEATURE_ID++;
            // } else if (c == 'a') {
            //     FEATURE_ID--;
        } else if (c == 'w') {
            OBJECT_ID++;
        } else if (c == 's') {
            OBJECT_ID--;
        }

        pthread_mutex_lock(&state->img_mutex);
        // UI handling
        if (!state->img.empty()) {
            cv::Mat display;
            cv::resize(state->img.clone(), display, cv::Size(WINDOW_WIDTH,WINDOW_HEIGHT));
            if (state->selection.width > 0 && state->selection.height > 0) {

                cv::Mat roi(display, state->selection);
                rectangle(display, state->selection, cv::Scalar(0,255,255), 2);
                // bitwise_not(roi, roi);
            }
            if (state->selection_virtual.width > 0 && state->selection_virtual.height > 0) {

                cv::Mat roi(display, state->selection_virtual);
                rectangle(display, state->selection_virtual, cv::Scalar(0,255,0), 2);
                // bitwise_not(roi, roi);
            }

            if (state->tld_result.width > 0 && state->tld_result.height > 0) {
                cv::Mat roi(display, state->tld_result);
                rectangle(display, state->tld_result, cv::Scalar(0,0,255), 2);
                // bitwise_not(roi, roi);
            }

            if(!state->img_selection.empty()){

                int border_width = 2;

                float sx = 1.f / WINDOW_WIDTH ;
                float sy = 1.f / WINDOW_HEIGHT;

                int width = state->img_selection.cols / (sx * state->img.cols);
                int height = state->img_selection.rows / (sx * state->img.rows);

                int max_dim = fmax(width, height);

                double scale = 1.0;
                if(max_dim > MAX_THUMB_SIZE){
                    scale =  MAX_THUMB_SIZE / (double) max_dim;
                    width = width * scale;
                    height = height * scale;
                }

                cv::Mat img_sel;
                cv::resize(state->img_selection.clone(), img_sel, cv::Size(width, height));

                cv::Rect border(WINDOW_WIDTH - width - border_width , WINDOW_HEIGHT - height - border_width , width + border_width/2.0, height + border_width / 2.0);

                cv::Mat obj_roi = cv::Mat(display, cv::Rect(WINDOW_WIDTH - width - border_width , WINDOW_HEIGHT - height - border_width , width, height));

                img_sel.copyTo(obj_roi);

                cv::rectangle(display, border, cv::Scalar(100 ,0,255), border_width);

                //cv.
                //show this at the bottom somewhere

                //cv::imshow("Img Selection" , img_sel);
            }

            // Show OBJECT_ID, FEATURE_ID
            cv::putText(display, cv::format("OBJ: %ld", OBJECT_ID),
                        Point(20,20), 0, .5, cv::Scalar(0,200,0), 2);

            imshow(WINDOW_NAME, display);
        }
        if(0 && !state->img_selection.empty()){
            float sx = 1.f / WINDOW_WIDTH ;
            float sy = 1.f / WINDOW_HEIGHT;

            int width = state->img_selection.cols / (sx * state->img.cols);
            int height = state->img_selection.rows / (sx * state->img.rows);

            cv::Mat img_sel;
            cv::resize(state->img_selection.clone(), img_sel, cv::Size(width, height));
            cv::imshow("Img Selection" , img_sel);
        }

        pthread_mutex_unlock(&state->img_mutex);
    }

    // if (state) delete state;
    return 0;
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// A brpc based redis-server. Currently just implement set and
// get, but it's sufficient that you can get the idea how to
// implement brpc::RedisCommandHandler.

#include <brpc/server.h>
#include <brpc/redis.h>
#include <butil/crc32c.h>
#include <gflags/gflags.h>
#include <unordered_map>

class RedisServiceImpl : public brpc::RedisService {
public:
    bool Set(const std::string& key, const char* value) {
        int slot = butil::crc32c::Value(key.c_str(), key.size()) % HashSlotNum;
        _mutex[slot].lock();
        _map[slot][key] = value;
        _mutex[slot].unlock();
        return true;
    }

    bool Get(const std::string& key, std::string* value) {
        int slot = butil::crc32c::Value(key.c_str(), key.size()) % HashSlotNum;
        _mutex[slot].lock();
        auto it = _map[slot].find(key);
        if (it == _map[slot].end()) {
            _mutex[slot].unlock();
            return false;
        }
        *value = it->second;
        _mutex[slot].unlock();
        return true;
    }

private:
    const static int HashSlotNum = 32;
    std::unordered_map<std::string, std::string> _map[HashSlotNum];
    butil::Mutex _mutex[HashSlotNum];
};

class GetCommandHandler : public brpc::RedisCommandHandler {
public:
    GetCommandHandler(RedisServiceImpl* rsimpl)
        : _rsimpl(rsimpl) {}

    brpc::RedisCommandHandler::Result Run(const char* args[],
                                          brpc::RedisReply* output) {
        if (args[1] == NULL) {
            output->SetError("ERR wrong number of arguments for 'get' command");
            return brpc::RedisCommandHandler::OK;
        }
        std::string key = args[1];
        std::string value;
        if (_rsimpl->Get(key, &value)) {
            output->SetBulkString(value);
        } else {
            output->SetNilString();
        }
        return brpc::RedisCommandHandler::OK;
	}
    RedisCommandHandler* New() { return new GetCommandHandler(_rsimpl); }

private:
   	RedisServiceImpl* _rsimpl;
};

class SetCommandHandler : public brpc::RedisCommandHandler {
public:
    SetCommandHandler(RedisServiceImpl* rsimpl)
        : _rsimpl(rsimpl) {}

    brpc::RedisCommandHandler::Result Run(const char* args[],
                                          brpc::RedisReply* output) {
        if (args[1] == NULL || args[2] == NULL) {
            output->SetError("ERR wrong number of arguments for 'set' command");
            return brpc::RedisCommandHandler::OK;
        }
        std::string key = args[1];
        _rsimpl->Set(key, args[2]);
        output->SetStatus("OK");
        return brpc::RedisCommandHandler::OK;
	}
    RedisCommandHandler* New() { return new SetCommandHandler(_rsimpl); }

private:
   	RedisServiceImpl* _rsimpl;
};

int main(int argc, char* argv[]) {
    google::ParseCommandLineFlags(&argc, &argv, true);
    RedisServiceImpl* rsimpl = new RedisServiceImpl;
    rsimpl->AddCommandHandler("get", new GetCommandHandler(rsimpl));
    rsimpl->AddCommandHandler("set", new SetCommandHandler(rsimpl));

    brpc::Server server;
    brpc::ServerOptions server_options;
    server_options.redis_service = rsimpl;
    if (server.Start(6379, &server_options) != 0) {
        LOG(ERROR) << "Fail to start server";
        return -1;
    }
    server.RunUntilAskedToQuit();
    return 0;
}
<commit_msg>redis_server_protocol: update redis_server<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// A brpc based redis-server. Currently just implement set and
// get, but it's sufficient that you can get the idea how to
// implement brpc::RedisCommandHandler.

#include <brpc/server.h>
#include <brpc/redis.h>
#include <butil/crc32c.h>
#include <butil/string_splitter.h>
#include <gflags/gflags.h>
#include <unordered_map>

class RedisServiceImpl : public brpc::RedisService {
public:
    bool Set(const std::string& key, const std::string& value) {
        int slot = butil::crc32c::Value(key.c_str(), key.size()) % HashSlotNum;
        _mutex[slot].lock();
        _map[slot][key] = value;
        _mutex[slot].unlock();
        return true;
    }

    bool Get(const std::string& key, std::string* value) {
        int slot = butil::crc32c::Value(key.c_str(), key.size()) % HashSlotNum;
        _mutex[slot].lock();
        auto it = _map[slot].find(key);
        if (it == _map[slot].end()) {
            _mutex[slot].unlock();
            return false;
        }
        *value = it->second;
        _mutex[slot].unlock();
        return true;
    }

private:
    const static int HashSlotNum = 32;
    std::unordered_map<std::string, std::string> _map[HashSlotNum];
    butil::Mutex _mutex[HashSlotNum];
};

class GetCommandHandler : public brpc::RedisCommandHandler {
public:
    GetCommandHandler(RedisServiceImpl* rsimpl)
        : _rsimpl(rsimpl) {}

    brpc::RedisCommandHandler::Result Run(const char* args,
                                          brpc::RedisReply* output) {
        std::string key;
        bool parse_command = false;
        butil::StringSplitter sp(args, ' ');
        for (; sp; ++sp) {
            if (!parse_command) {
                parse_command = true;
            } else if (key.empty()) {
                key.assign(sp.field(), sp.length());
            } else {
                LOG(WARNING) << "unknown args: " << sp;
            }
        }
        if (key.empty()) {
            output->SetError("ERR wrong number of arguments for 'get' command");
            return brpc::RedisCommandHandler::OK;
        }
        std::string value;
        if (_rsimpl->Get(key, &value)) {
            output->SetBulkString(value);
        } else {
            output->SetNilString();
        }
        return brpc::RedisCommandHandler::OK;
	}
    RedisCommandHandler* New() { return new GetCommandHandler(_rsimpl); }

private:
   	RedisServiceImpl* _rsimpl;
};

class SetCommandHandler : public brpc::RedisCommandHandler {
public:
    SetCommandHandler(RedisServiceImpl* rsimpl)
        : _rsimpl(rsimpl) {}

    brpc::RedisCommandHandler::Result Run(const char* args,
                                          brpc::RedisReply* output) {
        std::string key;
        std::string value;
        bool parse_command = false;
        butil::StringSplitter sp(args, ' ');
        for (; sp; ++sp) {
            if (!parse_command) {
                parse_command = true;
            } else if (key.empty()) {
                key.assign(sp.field(), sp.length());
            } else if (value.empty()) {
                value.assign(sp.field(), sp.length());
            } else {
                LOG(WARNING) << "unknown args: " << sp;
            }
        }
        if (key.empty() || value.empty()) {
            output->SetError("ERR wrong number of arguments for 'set' command");
            return brpc::RedisCommandHandler::OK;
        }
        _rsimpl->Set(key, value);
        output->SetStatus("OK");
        return brpc::RedisCommandHandler::OK;
	}
    RedisCommandHandler* New() { return new SetCommandHandler(_rsimpl); }

private:
   	RedisServiceImpl* _rsimpl;
};

int main(int argc, char* argv[]) {
    google::ParseCommandLineFlags(&argc, &argv, true);
    RedisServiceImpl* rsimpl = new RedisServiceImpl;
    rsimpl->AddCommandHandler("get", new GetCommandHandler(rsimpl));
    rsimpl->AddCommandHandler("set", new SetCommandHandler(rsimpl));

    brpc::Server server;
    brpc::ServerOptions server_options;
    server_options.redis_service = rsimpl;
    if (server.Start(6379, &server_options) != 0) {
        LOG(ERROR) << "Fail to start server";
        return -1;
    }
    server.RunUntilAskedToQuit();
    return 0;
}
<|endoftext|>


<commit_before>
#include "Halide.h"
#include <stdio.h>
#include <stdint.h>
#include <string>

using namespace Halide;

template <typename T>
T local_popcount(T v) {
    T count = 0;
    while (v) {
        if (v & 1) ++count;
        v >>= 1;
    }
    return count;
}

template <typename T>
T local_count_trailing_zeros(T v) {
    const int bits = sizeof(T)*8;
    for (T b = 0; b < bits; ++b) {
        if (v & (1 << b)) {
            // found a set bit
            return b;
        }
    }
    return 0;
}

template <typename T>
T local_count_leading_zeros(T v) {
    const int bits = sizeof(T)*8;
    for (T b = 0; b < bits; ++b) {
        if (v & (1 << (bits - 1 - b))) {
            // found a set bit
            return b;
        }
    }
    return 0;
}

template <typename T>
std::string as_bits(T v) {
    const int bits = sizeof(T)*8;
    std::string ret;
    for (int i = bits - 1; i >= 0; --i)
        ret += (v & (1 << i)) ? '1' : '0';
    return ret;
}

Var x("x");

void schedule(Func f, const Target &t) {
    // TODO: Add GPU schedule where supported.
    f.vectorize(x, 16);
}

template <typename T>
int test_bit_counting(const Target &target) {
    const int bits = sizeof(T)*8;
    Image<T> input(256);
    for (int i = 0; i < 256; i++) {
        if (i < 16) {
            input(i) = i;
        } else if (i < 32) {
            input(i) = 0xffffffffUL - i;
        } else {
            input(i) = rand();
        }
    }

    Func popcount_test("popcount_test");
    popcount_test(x) = popcount(input(x));
    schedule(popcount_test, target);

    Image<T> popcount_result = popcount_test.realize(256);
    for (int i = 0; i < 256; ++i) {
        if (popcount_result(i) != local_popcount(input(i))) {
            std::string bits_string = as_bits(input(i));
            printf("Popcount of %u [0b%s] returned %d (should be %d)\n",
                   input(i), bits_string.c_str(), popcount_result(i),
                   local_popcount(input(i)));
            return -1;
        }
    }

    Func ctlz_test("ctlz_test");
    ctlz_test(x) = count_leading_zeros(input(x));
    schedule(ctlz_test, target);

    Image<T> ctlz_result = ctlz_test.realize(256);
    for (int i = 0; i < 256; ++i) {
        if (input(i) == 0) {
            // results are undefined for zero input
            continue;
        }

        if (ctlz_result(i) != local_count_leading_zeros(input(i))) {
            std::string bits_string = as_bits(input(i));
            printf("Ctlz of %u [0b%s] returned %d (should be %d)\n",
                   input(i), bits_string.c_str(), ctlz_result(i),
                   local_count_leading_zeros(input(i)));
            return -1;
        }
    }

    Func cttz_test("cttz_test");
    cttz_test(x) = count_trailing_zeros(input(x));
    schedule(cttz_test, target);

    Image<T> cttz_result = cttz_test.realize(256);
    for (int i = 0; i < 256; ++i) {
        if (input(i) == 0) {
            // results are undefined for zero input
            continue;
        }

        if (cttz_result(i) != local_count_trailing_zeros(input(i))) {
            std::string bits_string = as_bits(input(i));
            printf("Cttz of %u [0b%s] returned %d (should be %d)\n",
                   input(i), bits_string.c_str(), cttz_result(i),
                   local_count_trailing_zeros(input(i)));
            return -1;
        }
    }
    return 0;
}

int main() {
    Target target = get_jit_target_from_environment();

    if (test_bit_counting<uint16_t>(target) != 0) return -1;
    if (test_bit_counting<uint32_t>(target) != 0) return -1;

    printf("Success!\n");
    return 0;
}
<commit_msg>Delete dead code<commit_after>
#include "Halide.h"
#include <stdio.h>
#include <stdint.h>
#include <string>

using namespace Halide;

template <typename T>
T local_popcount(T v) {
    T count = 0;
    while (v) {
        if (v & 1) ++count;
        v >>= 1;
    }
    return count;
}

template <typename T>
T local_count_trailing_zeros(T v) {
    const int bits = sizeof(T)*8;
    for (T b = 0; b < bits; ++b) {
        if (v & (1 << b)) {
            // found a set bit
            return b;
        }
    }
    return 0;
}

template <typename T>
T local_count_leading_zeros(T v) {
    const int bits = sizeof(T)*8;
    for (T b = 0; b < bits; ++b) {
        if (v & (1 << (bits - 1 - b))) {
            // found a set bit
            return b;
        }
    }
    return 0;
}

template <typename T>
std::string as_bits(T v) {
    const int bits = sizeof(T)*8;
    std::string ret;
    for (int i = bits - 1; i >= 0; --i)
        ret += (v & (1 << i)) ? '1' : '0';
    return ret;
}

Var x("x");

void schedule(Func f, const Target &t) {
    // TODO: Add GPU schedule where supported.
    f.vectorize(x, 16);
}

template <typename T>
int test_bit_counting(const Target &target) {
    Image<T> input(256);
    for (int i = 0; i < 256; i++) {
        if (i < 16) {
            input(i) = i;
        } else if (i < 32) {
            input(i) = 0xffffffffUL - i;
        } else {
            input(i) = rand();
        }
    }

    Func popcount_test("popcount_test");
    popcount_test(x) = popcount(input(x));
    schedule(popcount_test, target);

    Image<T> popcount_result = popcount_test.realize(256);
    for (int i = 0; i < 256; ++i) {
        if (popcount_result(i) != local_popcount(input(i))) {
            std::string bits_string = as_bits(input(i));
            printf("Popcount of %u [0b%s] returned %d (should be %d)\n",
                   input(i), bits_string.c_str(), popcount_result(i),
                   local_popcount(input(i)));
            return -1;
        }
    }

    Func ctlz_test("ctlz_test");
    ctlz_test(x) = count_leading_zeros(input(x));
    schedule(ctlz_test, target);

    Image<T> ctlz_result = ctlz_test.realize(256);
    for (int i = 0; i < 256; ++i) {
        if (input(i) == 0) {
            // results are undefined for zero input
            continue;
        }

        if (ctlz_result(i) != local_count_leading_zeros(input(i))) {
            std::string bits_string = as_bits(input(i));
            printf("Ctlz of %u [0b%s] returned %d (should be %d)\n",
                   input(i), bits_string.c_str(), ctlz_result(i),
                   local_count_leading_zeros(input(i)));
            return -1;
        }
    }

    Func cttz_test("cttz_test");
    cttz_test(x) = count_trailing_zeros(input(x));
    schedule(cttz_test, target);

    Image<T> cttz_result = cttz_test.realize(256);
    for (int i = 0; i < 256; ++i) {
        if (input(i) == 0) {
            // results are undefined for zero input
            continue;
        }

        if (cttz_result(i) != local_count_trailing_zeros(input(i))) {
            std::string bits_string = as_bits(input(i));
            printf("Cttz of %u [0b%s] returned %d (should be %d)\n",
                   input(i), bits_string.c_str(), cttz_result(i),
                   local_count_trailing_zeros(input(i)));
            return -1;
        }
    }
    return 0;
}

int main() {
    Target target = get_jit_target_from_environment();

    if (test_bit_counting<uint16_t>(target) != 0) return -1;
    if (test_bit_counting<uint32_t>(target) != 0) return -1;

    printf("Success!\n");
    return 0;
}
<|endoftext|>