<commit_before>/*****************************************************************************
 *  Copyright (C) 2008-2011 Massachusetts Institute of Technology            *
 *                                                                           *
 *  Permission is hereby granted, free of charge, to any person obtaining    *
 *  a copy of this software and associated documentation files (the          *
 *  "Software"), to deal in the Software without restriction, including      *
 *  without limitation the rights to use, copy, modify, merge, publish,      *
 *  distribute, sublicense, and/or sell copies of the Software, and to       *
 *  permit persons to whom the Software is furnished to do so, subject       *
 *  to the following conditions:                                             *
 *                                                                           *
 *  The above copyright notice and this permission notice shall be included  *
 *  in all copies or substantial portions of the Software.                   *
 *                                                                           *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY                *
 *  KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE               *
 *  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND      *
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE   *
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION   *
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION    *
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE           *
 *                                                                           *
 *  This source code is part of the PetaBricks project:                      *
 *    http://projects.csail.mit.edu/petabricks/                              *
 *                                                                           *
 *****************************************************************************/
#include "syntheticrule.h"

#include "codegenerator.h"
#include "iterationorders.h"
#include "maximawrapper.h"
#include "transform.h"

void petabricks::SyntheticRule::compileRuleBody(Transform&, RIRScope&){}
void petabricks::SyntheticRule::initialize(Transform&){}

petabricks::RuleFlags::PriorityT petabricks::SyntheticRule::priority() const {
  return RuleFlags::PRIORITY_DEFAULT;
}
bool petabricks::SyntheticRule::isRecursive() const {
  return true;
}
bool petabricks::SyntheticRule::hasWhereClause() const {
  return false;
}
petabricks::FormulaPtr petabricks::SyntheticRule::getWhereClause() const {
  return NULL;
}

std::string petabricks::SyntheticRule::getLabel() const {
  return "synthetic";
}

bool petabricks::SyntheticRule::canProvide(const MatrixDefPtr&) const {
  UNIMPLEMENTED();
  return false;
}

void petabricks::SyntheticRule::getApplicableRegionDescriptors(RuleDescriptorList&, const MatrixDefPtr&, int, const RulePtr&) {
  UNIMPLEMENTED();
}
//
// void petabricks::SyntheticRule::generateCallCode(const std::string&,
//                                                  Transform&,
//                                                  CodeGenerator& o,
//                                                  const SimpleRegionPtr&,
//                                                  RuleFlavor,
//                                                  std::vector<RegionNodeGroup>&,
//                                                  int, int){
//   o.comment("synthetic generateCallCode");
// }
//
void petabricks::SyntheticRule::generateDeclCode(Transform&, CodeGenerator&, RuleFlavor) {}
//void petabricks::SyntheticRule::generateTrampCode(Transform&, CodeGenerator&, RuleFlavor) {}

void petabricks::SyntheticRule::markRecursive() {
  UNIMPLEMENTED();
}
const petabricks::FormulaPtr& petabricks::SyntheticRule::recursiveHint() const {
  return FormulaPtr::null();
}
void petabricks::SyntheticRule::print(std::ostream& os) const {
  os << "SyntheticRule " << _id << std::endl;;
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//WrapperSyntheticRule:

void petabricks::WrapperSyntheticRule::generateCallCode(const std::string& name,
                                            Transform& trans,
                                            CodeGenerator& o,
                                            const SimpleRegionPtr& region,
                                            RuleFlavor flavor,
                                            std::vector<RegionNodeGroup>& regionNodesGroups,
                                            int nodeID,
                                            int gpuCopyOut){
  _rule->generateCallCode(name, trans, o, region, flavor, regionNodesGroups, nodeID, gpuCopyOut);
}

void petabricks::WrapperSyntheticRule::generateTrampCode(Transform& trans, CodeGenerator& o, RuleFlavor rf){
  _rule->generateTrampCode(trans, o, rf);
}

bool petabricks::WrapperSyntheticRule::isSingleElement() const {
  return _rule->isSingleElement();
}

int petabricks::WrapperSyntheticRule::dimensions() const {
  return _rule->dimensions();
}
petabricks::DependencyDirection petabricks::WrapperSyntheticRule::getSelfDependency() const {
  return _rule->getSelfDependency();
}
petabricks::FormulaPtr petabricks::WrapperSyntheticRule::getSizeOfRuleIn(int d) {
  return _rule->getSizeOfRuleIn(d);
}

void petabricks::WrapperSyntheticRule::collectDependencies(StaticScheduler& scheduler) {
  _rule->collectDependencies(scheduler);
}

petabricks::RuleFlags::PriorityT petabricks::WrapperSyntheticRule::priority() const {
  return _rule->priority();
}
bool petabricks::WrapperSyntheticRule::isRecursive() const {
  return _rule->isRecursive();
}
bool petabricks::WrapperSyntheticRule::hasWhereClause() const {
  return _rule->hasWhereClause();
}
petabricks::FormulaPtr petabricks::WrapperSyntheticRule::getWhereClause() const {
  return _rule->getWhereClause();
}
bool petabricks::WrapperSyntheticRule::canProvide(const MatrixDefPtr& md) const {
  return _rule->canProvide(md);
}
void petabricks::WrapperSyntheticRule::getApplicableRegionDescriptors(RuleDescriptorList& rdl, const MatrixDefPtr& md, int i, const RulePtr& rule) {
  _rule->getApplicableRegionDescriptors(rdl, md, i, rule);
}
const petabricks::FormulaPtr& petabricks::WrapperSyntheticRule::recursiveHint() const {
  return _rule->recursiveHint();
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//TODO: consider new file for WhereExpansionRule

void petabricks::WhereExpansionRule::generateCallCode(const std::string& name,
                                            Transform& trans,
                                            CodeGenerator& o,
                                            const SimpleRegionPtr& region,
                                            RuleFlavor flavor,
                                            std::vector<RegionNodeGroup>&,
                                            int,
                                            int){
  SRCPOSSCOPE();
  switch(flavor) {
  case RuleFlavor::SEQUENTIAL:
    o.callSpatial(codename()+"_"+flavor.str(), region);
    break;
  case RuleFlavor::WORKSTEALING:
  case RuleFlavor::DISTRIBUTED:
    o.mkSpatialTask(name, trans.instClassName(), codename()+"_"+flavor.str(), region);
    break;
  default:
    UNIMPLEMENTED();
  }
}

void petabricks::WhereExpansionRule::generateTrampCode(Transform& trans, CodeGenerator& o, RuleFlavor flavor){
  IterationDefinition iterdef(*this, getSelfDependency() , false);
  std::vector<std::string> packedargs = iterdef.packedargs();
  o.beginFunc("petabricks::DynamicTaskPtr", codename()+"_"+flavor.str(), packedargs);
  if(RuleFlavor::SEQUENTIAL != flavor) {
    o.write("DynamicTaskPtr _spawner = new NullDynamicTask();");
    o.write("DynamicTaskPtr _last = NULL;");
  }
  iterdef.unpackargs(o);
  iterdef.genLoopBegin(o);
  genWhereSwitch(trans, o, flavor);
  iterdef.genLoopEnd(o);
  if(RuleFlavor::SEQUENTIAL != flavor){
    o.write("_spawner->dependsOn(_last);");
    o.write("return _spawner;");
  }
  else o.write("return NULL;");
  o.endFunc();
}

void petabricks::WhereExpansionRule::genWhereSwitch(Transform& trans, CodeGenerator& o, RuleFlavor rf){
  RuleSet::iterator i;
  for(i=_rules.begin(); i!=_rules.end(); ++i){
    for(int d=0; d<(*i)->dimensions(); ++d){
      o._define((*i)->getOffsetVar(d)->toString(), getOffsetVar(d)->toString());
    }

    FormulaPtr wc = (*i)->getWhereClause();
    if(!wc)
      o.elseIf();
    else if(i==_rules.begin())
      o.beginIf(wc->toCppString());
    else
      o.elseIf(wc->toCppString());

    (*i)->generateTrampCellCodeSimple(trans, o, rf);

    for(int d=0; d<(*i)->dimensions(); ++d){
      o._undefine((*i)->getOffsetVar(d)->toString());
    }

    if(!wc){
      o.endIf();
      return; //we reached an unconditioned rule
    }
  }
  o.elseIf();
  o.write("JASSERT(false).Text(\"All where clauses failed, no rule to compute region\");");
  o.endIf();
}

bool petabricks::WhereExpansionRule::isSingleElement() const {
  return false;
}

int petabricks::WhereExpansionRule::dimensions() const {
  RuleSet::const_iterator i=_rules.begin();
  int rv = (*i)->dimensions();
  for(++i ;i!=_rules.end(); ++i)
    JASSERT(rv==(*i)->dimensions())(rv)((*i)->dimensions())
      .Text("where clauses only work with common number of dimensions");;
  return rv;
}
petabricks::DependencyDirection petabricks::WhereExpansionRule::getSelfDependency() const {
  DependencyDirection rv;
  RuleSet::const_iterator i;
  for(i=_rules.begin(); i!=_rules.end(); ++i)
    rv.addDirection((*i)->getSelfDependency());
  return rv;
}
petabricks::FormulaPtr petabricks::WhereExpansionRule::getSizeOfRuleIn(int d) {
  RuleSet::const_iterator i=_rules.begin();
  FormulaPtr rv = (*i)->getSizeOfRuleIn(d);
  for(++i ;i!=_rules.end(); ++i)
    JASSERT(MAXIMA.compare(rv,"=", (*i)->getSizeOfRuleIn(d)))
      .Text("where clauses only work with common sizes in each choice");;
  return rv;
}

std::string petabricks::WhereExpansionRule::codename() const {
  return "whereExpansion"+jalib::XToString(_id);
}

void petabricks::WhereExpansionRule::collectDependencies(StaticScheduler& scheduler) {
  RuleSet::const_iterator i;
  for(i=_rules.begin(); i!=_rules.end(); ++i)
    (*i)->collectDependencies(scheduler);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//TODO: consider new file for DuplicateExpansionRule

void petabricks::DuplicateExpansionRule::generateCallCode(const std::string& name,
                                            Transform& trans,
                                            CodeGenerator& o,
                                            const SimpleRegionPtr& region,
                                            RuleFlavor flavor,
                                            std::vector<RegionNodeGroup>& regionNodesGroups,
                                            int nodeID,
                                            int gpuCopyOut){
  SRCPOSSCOPE();
  size_t old = _rule->setDuplicateNumber(_dup);
  WrapperSyntheticRule::generateCallCode(name, trans, o, region, flavor, regionNodesGroups, nodeID, gpuCopyOut);
  _rule->setDuplicateNumber(old);
}

void petabricks::DuplicateExpansionRule::generateTrampCode(Transform& trans, CodeGenerator& o, RuleFlavor rf){
  size_t old = _rule->setDuplicateNumber(_dup);
  WrapperSyntheticRule::generateTrampCode(trans, o, rf);
  _rule->setDuplicateNumber(old);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//TODO: consider new file for CallInSequenceRule

void petabricks::CallInSequenceRule::generateCallCode(const std::string& name,
                                            Transform& trans,
                                            CodeGenerator& o,
                                            const SimpleRegionPtr& region,
                                            RuleFlavor flavor,
                                            std::vector<RegionNodeGroup>& regionNodesGroups,
                                            int nodeID,
                                            int gpuCopyOut){
  SRCPOSSCOPE();
  if(flavor != RuleFlavor::SEQUENTIAL)
    o.write("{ DynamicTaskPtr __last;");
  RuleList::iterator i;
  for(i=_rules.begin(); i!=_rules.end(); ++i){
    (*i)->generateCallCode(name, trans, o, region, flavor, regionNodesGroups, nodeID, gpuCopyOut);
    if(flavor != RuleFlavor::SEQUENTIAL) {
      if(i!=_rules.begin()) {
        o.write(name+"->dependsOn(__last);");
        o.write("__last->enqueue();");
      }
      o.write("__last = "+name+";");
    }
  }
  if(flavor != RuleFlavor::SEQUENTIAL)
    o.write("}");
}

void petabricks::CallInSequenceRule::generateTrampCode(Transform& /*trans*/, CodeGenerator& /*o*/, RuleFlavor){
  UNIMPLEMENTED();
}

bool petabricks::CallInSequenceRule::isSingleElement() const { UNIMPLEMENTED(); return false; }

int petabricks::CallInSequenceRule::dimensions() const { UNIMPLEMENTED(); return -1; }
petabricks::FormulaPtr petabricks::CallInSequenceRule::getSizeOfRuleIn(int /*d*/) { UNIMPLEMENTED(); return 0; }

std::string petabricks::CallInSequenceRule::codename() const { UNIMPLEMENTED(); return ""; }

void petabricks::CallInSequenceRule::collectDependencies(StaticScheduler& /*scheduler*/) { UNIMPLEMENTED(); }

void petabricks::CallInSequenceRule::genWhereSwitch(Transform& /*trans*/, CodeGenerator& /*o*/) { UNIMPLEMENTED(); }

petabricks::DependencyDirection petabricks::CallInSequenceRule::getSelfDependency() const { UNIMPLEMENTED(); return 0; }

<commit_msg>Mark WhereExpansionRule::generateTrampCode as UNIMPLEMENTED()<commit_after>/*****************************************************************************
 *  Copyright (C) 2008-2011 Massachusetts Institute of Technology            *
 *                                                                           *
 *  Permission is hereby granted, free of charge, to any person obtaining    *
 *  a copy of this software and associated documentation files (the          *
 *  "Software"), to deal in the Software without restriction, including      *
 *  without limitation the rights to use, copy, modify, merge, publish,      *
 *  distribute, sublicense, and/or sell copies of the Software, and to       *
 *  permit persons to whom the Software is furnished to do so, subject       *
 *  to the following conditions:                                             *
 *                                                                           *
 *  The above copyright notice and this permission notice shall be included  *
 *  in all copies or substantial portions of the Software.                   *
 *                                                                           *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY                *
 *  KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE               *
 *  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND      *
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE   *
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION   *
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION    *
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE           *
 *                                                                           *
 *  This source code is part of the PetaBricks project:                      *
 *    http://projects.csail.mit.edu/petabricks/                              *
 *                                                                           *
 *****************************************************************************/
#include "syntheticrule.h"

#include "codegenerator.h"
#include "iterationorders.h"
#include "maximawrapper.h"
#include "transform.h"

void petabricks::SyntheticRule::compileRuleBody(Transform&, RIRScope&){}
void petabricks::SyntheticRule::initialize(Transform&){}

petabricks::RuleFlags::PriorityT petabricks::SyntheticRule::priority() const {
  return RuleFlags::PRIORITY_DEFAULT;
}
bool petabricks::SyntheticRule::isRecursive() const {
  return true;
}
bool petabricks::SyntheticRule::hasWhereClause() const {
  return false;
}
petabricks::FormulaPtr petabricks::SyntheticRule::getWhereClause() const {
  return NULL;
}

std::string petabricks::SyntheticRule::getLabel() const {
  return "synthetic";
}

bool petabricks::SyntheticRule::canProvide(const MatrixDefPtr&) const {
  UNIMPLEMENTED();
  return false;
}

void petabricks::SyntheticRule::getApplicableRegionDescriptors(RuleDescriptorList&, const MatrixDefPtr&, int, const RulePtr&) {
  UNIMPLEMENTED();
}
//
// void petabricks::SyntheticRule::generateCallCode(const std::string&,
//                                                  Transform&,
//                                                  CodeGenerator& o,
//                                                  const SimpleRegionPtr&,
//                                                  RuleFlavor,
//                                                  std::vector<RegionNodeGroup>&,
//                                                  int, int){
//   o.comment("synthetic generateCallCode");
// }
//
void petabricks::SyntheticRule::generateDeclCode(Transform&, CodeGenerator&, RuleFlavor) {}
//void petabricks::SyntheticRule::generateTrampCode(Transform&, CodeGenerator&, RuleFlavor) {}

void petabricks::SyntheticRule::markRecursive() {
  UNIMPLEMENTED();
}
const petabricks::FormulaPtr& petabricks::SyntheticRule::recursiveHint() const {
  return FormulaPtr::null();
}
void petabricks::SyntheticRule::print(std::ostream& os) const {
  os << "SyntheticRule " << _id << std::endl;;
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//WrapperSyntheticRule:

void petabricks::WrapperSyntheticRule::generateCallCode(const std::string& name,
                                            Transform& trans,
                                            CodeGenerator& o,
                                            const SimpleRegionPtr& region,
                                            RuleFlavor flavor,
                                            std::vector<RegionNodeGroup>& regionNodesGroups,
                                            int nodeID,
                                            int gpuCopyOut){
  _rule->generateCallCode(name, trans, o, region, flavor, regionNodesGroups, nodeID, gpuCopyOut);
}

void petabricks::WrapperSyntheticRule::generateTrampCode(Transform& trans, CodeGenerator& o, RuleFlavor rf){
  _rule->generateTrampCode(trans, o, rf);
}

bool petabricks::WrapperSyntheticRule::isSingleElement() const {
  return _rule->isSingleElement();
}

int petabricks::WrapperSyntheticRule::dimensions() const {
  return _rule->dimensions();
}
petabricks::DependencyDirection petabricks::WrapperSyntheticRule::getSelfDependency() const {
  return _rule->getSelfDependency();
}
petabricks::FormulaPtr petabricks::WrapperSyntheticRule::getSizeOfRuleIn(int d) {
  return _rule->getSizeOfRuleIn(d);
}

void petabricks::WrapperSyntheticRule::collectDependencies(StaticScheduler& scheduler) {
  _rule->collectDependencies(scheduler);
}

petabricks::RuleFlags::PriorityT petabricks::WrapperSyntheticRule::priority() const {
  return _rule->priority();
}
bool petabricks::WrapperSyntheticRule::isRecursive() const {
  return _rule->isRecursive();
}
bool petabricks::WrapperSyntheticRule::hasWhereClause() const {
  return _rule->hasWhereClause();
}
petabricks::FormulaPtr petabricks::WrapperSyntheticRule::getWhereClause() const {
  return _rule->getWhereClause();
}
bool petabricks::WrapperSyntheticRule::canProvide(const MatrixDefPtr& md) const {
  return _rule->canProvide(md);
}
void petabricks::WrapperSyntheticRule::getApplicableRegionDescriptors(RuleDescriptorList& rdl, const MatrixDefPtr& md, int i, const RulePtr& rule) {
  _rule->getApplicableRegionDescriptors(rdl, md, i, rule);
}
const petabricks::FormulaPtr& petabricks::WrapperSyntheticRule::recursiveHint() const {
  return _rule->recursiveHint();
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//TODO: consider new file for WhereExpansionRule

void petabricks::WhereExpansionRule::generateCallCode(const std::string& name,
                                            Transform& trans,
                                            CodeGenerator& o,
                                            const SimpleRegionPtr& region,
                                            RuleFlavor flavor,
                                            std::vector<RegionNodeGroup>&,
                                            int,
                                            int){
  SRCPOSSCOPE();
  switch(flavor) {
  case RuleFlavor::SEQUENTIAL:
    o.callSpatial(codename()+"_"+flavor.str(), region);
    break;
  case RuleFlavor::WORKSTEALING:
  case RuleFlavor::DISTRIBUTED:
    o.mkSpatialTask(name, trans.instClassName(), codename()+"_"+flavor.str(), region);
    break;
  default:
    UNIMPLEMENTED();
  }
}

void petabricks::WhereExpansionRule::generateTrampCode(Transform& trans, CodeGenerator& o, RuleFlavor flavor){
  // TODO: This should create IterationTrampTask like in UserRule::generateTrampCode
  UNIMPLEMENTED();

  IterationDefinition iterdef(*this, getSelfDependency() , false);
  std::vector<std::string> packedargs = iterdef.packedargs();
  o.beginFunc("petabricks::DynamicTaskPtr", codename()+"_"+flavor.str(), packedargs);
  if(RuleFlavor::SEQUENTIAL != flavor) {
    o.write("DynamicTaskPtr _spawner = new NullDynamicTask();");
    o.write("DynamicTaskPtr _last = NULL;");
  }
  iterdef.unpackargs(o);
  iterdef.genLoopBegin(o);
  genWhereSwitch(trans, o, flavor);
  iterdef.genLoopEnd(o);
  if(RuleFlavor::SEQUENTIAL != flavor){
    o.write("_spawner->dependsOn(_last);");
    o.write("return _spawner;");
  }
  else o.write("return NULL;");
  o.endFunc();
}

void petabricks::WhereExpansionRule::genWhereSwitch(Transform& trans, CodeGenerator& o, RuleFlavor rf){
  RuleSet::iterator i;
  for(i=_rules.begin(); i!=_rules.end(); ++i){
    for(int d=0; d<(*i)->dimensions(); ++d){
      o._define((*i)->getOffsetVar(d)->toString(), getOffsetVar(d)->toString());
    }

    FormulaPtr wc = (*i)->getWhereClause();
    if(!wc)
      o.elseIf();
    else if(i==_rules.begin())
      o.beginIf(wc->toCppString());
    else
      o.elseIf(wc->toCppString());

    (*i)->generateTrampCellCodeSimple(trans, o, rf);

    for(int d=0; d<(*i)->dimensions(); ++d){
      o._undefine((*i)->getOffsetVar(d)->toString());
    }

    if(!wc){
      o.endIf();
      return; //we reached an unconditioned rule
    }
  }
  o.elseIf();
  o.write("JASSERT(false).Text(\"All where clauses failed, no rule to compute region\");");
  o.endIf();
}

bool petabricks::WhereExpansionRule::isSingleElement() const {
  return false;
}

int petabricks::WhereExpansionRule::dimensions() const {
  RuleSet::const_iterator i=_rules.begin();
  int rv = (*i)->dimensions();
  for(++i ;i!=_rules.end(); ++i)
    JASSERT(rv==(*i)->dimensions())(rv)((*i)->dimensions())
      .Text("where clauses only work with common number of dimensions");;
  return rv;
}
petabricks::DependencyDirection petabricks::WhereExpansionRule::getSelfDependency() const {
  DependencyDirection rv;
  RuleSet::const_iterator i;
  for(i=_rules.begin(); i!=_rules.end(); ++i)
    rv.addDirection((*i)->getSelfDependency());
  return rv;
}
petabricks::FormulaPtr petabricks::WhereExpansionRule::getSizeOfRuleIn(int d) {
  RuleSet::const_iterator i=_rules.begin();
  FormulaPtr rv = (*i)->getSizeOfRuleIn(d);
  for(++i ;i!=_rules.end(); ++i)
    JASSERT(MAXIMA.compare(rv,"=", (*i)->getSizeOfRuleIn(d)))
      .Text("where clauses only work with common sizes in each choice");;
  return rv;
}

std::string petabricks::WhereExpansionRule::codename() const {
  return "whereExpansion"+jalib::XToString(_id);
}

void petabricks::WhereExpansionRule::collectDependencies(StaticScheduler& scheduler) {
  RuleSet::const_iterator i;
  for(i=_rules.begin(); i!=_rules.end(); ++i)
    (*i)->collectDependencies(scheduler);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//TODO: consider new file for DuplicateExpansionRule

void petabricks::DuplicateExpansionRule::generateCallCode(const std::string& name,
                                            Transform& trans,
                                            CodeGenerator& o,
                                            const SimpleRegionPtr& region,
                                            RuleFlavor flavor,
                                            std::vector<RegionNodeGroup>& regionNodesGroups,
                                            int nodeID,
                                            int gpuCopyOut){
  SRCPOSSCOPE();
  size_t old = _rule->setDuplicateNumber(_dup);
  WrapperSyntheticRule::generateCallCode(name, trans, o, region, flavor, regionNodesGroups, nodeID, gpuCopyOut);
  _rule->setDuplicateNumber(old);
}

void petabricks::DuplicateExpansionRule::generateTrampCode(Transform& trans, CodeGenerator& o, RuleFlavor rf){
  size_t old = _rule->setDuplicateNumber(_dup);
  WrapperSyntheticRule::generateTrampCode(trans, o, rf);
  _rule->setDuplicateNumber(old);
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//TODO: consider new file for CallInSequenceRule

void petabricks::CallInSequenceRule::generateCallCode(const std::string& name,
                                            Transform& trans,
                                            CodeGenerator& o,
                                            const SimpleRegionPtr& region,
                                            RuleFlavor flavor,
                                            std::vector<RegionNodeGroup>& regionNodesGroups,
                                            int nodeID,
                                            int gpuCopyOut){
  SRCPOSSCOPE();
  if(flavor != RuleFlavor::SEQUENTIAL)
    o.write("{ DynamicTaskPtr __last;");
  RuleList::iterator i;
  for(i=_rules.begin(); i!=_rules.end(); ++i){
    (*i)->generateCallCode(name, trans, o, region, flavor, regionNodesGroups, nodeID, gpuCopyOut);
    if(flavor != RuleFlavor::SEQUENTIAL) {
      if(i!=_rules.begin()) {
        o.write(name+"->dependsOn(__last);");
        o.write("__last->enqueue();");
      }
      o.write("__last = "+name+";");
    }
  }
  if(flavor != RuleFlavor::SEQUENTIAL)
    o.write("}");
}

void petabricks::CallInSequenceRule::generateTrampCode(Transform& /*trans*/, CodeGenerator& /*o*/, RuleFlavor){
  UNIMPLEMENTED();
}

bool petabricks::CallInSequenceRule::isSingleElement() const { UNIMPLEMENTED(); return false; }

int petabricks::CallInSequenceRule::dimensions() const { UNIMPLEMENTED(); return -1; }
petabricks::FormulaPtr petabricks::CallInSequenceRule::getSizeOfRuleIn(int /*d*/) { UNIMPLEMENTED(); return 0; }

std::string petabricks::CallInSequenceRule::codename() const { UNIMPLEMENTED(); return ""; }

void petabricks::CallInSequenceRule::collectDependencies(StaticScheduler& /*scheduler*/) { UNIMPLEMENTED(); }

void petabricks::CallInSequenceRule::genWhereSwitch(Transform& /*trans*/, CodeGenerator& /*o*/) { UNIMPLEMENTED(); }

petabricks::DependencyDirection petabricks::CallInSequenceRule::getSelfDependency() const { UNIMPLEMENTED(); return 0; }

<|endoftext|>


<commit_before>#include <time.h>
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "imds2.h"
#include "fileinfo2.h"
#include "fileindex2.h"

u_lint IMDS::GetNumFiles()
{
	return FileStats.GetNumFiles();
}

int IMDS::LockStatus(struct in_addr machine_IP,
					 const char*    owner_name,
					 const char*    file_name)
{
	return Index.LockStatus(machine_IP, owner_name, file_name);
}

void IMDS::Lock(struct in_addr machine_IP,
				const char*    owner_name,
				const char*    file_name,
				file_state     state)
{
	file_node*      file_ptr;
	file_info_node* file_data;

	file_ptr = Index.GetFileNode(machine_IP, owner_name, file_name);
	if (file_ptr != NULL) {
		file_data = file_ptr->file_data;
		file_data->lock = EXCLUSIVE_LOCK;
		file_data->data.state = state;
    }
}

void IMDS::Unlock(struct in_addr machine_IP,
				  const char*    owner_name,
				  const char*    file_name)
{
	file_node*      file_ptr;
	file_info_node* file_data;

	file_ptr = Index.GetFileNode(machine_IP, owner_name, file_name);
	if (file_ptr != NULL) {
		file_data = file_ptr->file_data;
		file_data->lock = UNLOCKED;
		file_data->data.state = ON_SERVER;
    }
}

int IMDS::AddFile(struct in_addr machine_IP,
		  const char*    owner_name,
		  const char*    file_name,
		  u_lint         file_size,
		  file_state     state)
{
  file_node*      file_ptr;
  file_info_node* file_data;
  char            pathname[MAX_PATHNAME_LENGTH];

  file_ptr = Index.GetFileNode(machine_IP, owner_name, file_name);
  if (file_ptr != NULL)
    {
      file_data = file_ptr->file_data;
      if (file_data->lock != UNLOCKED)
	return FILE_LOCKED;
      sprintf(pathname, "%s%s/%s/%s", LOCAL_DRIVE_PREFIX,
	      file_data->data.machine_IP_name, owner_name, file_name);
      if ((state == NOT_PRESENT) || (state == LOADING))
	remove(pathname);                        // Do not care if fails
      file_data->data.size = file_size;
      file_data->data.last_modified_time = time(NULL);
      file_data->data.state = state;
      file_data->lock = EXCLUSIVE_LOCK;
    }
  else
    {
      file_data = FileStats.AddFileInfo(machine_IP, owner_name, file_name,
					file_size, state, NULL);
      (void) Index.AddNewFile(machine_IP, owner_name, file_name, file_data);
    }
  return CREATED;
}

int IMDS::RenameFile(struct in_addr machine_IP,
					 const char*    owner_name,
					 const char*    file_name,
					 const char*    new_file_name)
{
	file_node*      old_fn;
	file_node*      new_fn;
	file_info_node* old_file_ptr;
	file_info_node* new_file_ptr;
	char            new_pathname[MAX_PATHNAME_LENGTH];
	char            old_pathname[MAX_PATHNAME_LENGTH];

	old_fn = Index.GetFileNode(machine_IP, owner_name, file_name);
	if (old_fn == NULL)
		return DOES_NOT_EXIST;
	old_file_ptr = old_fn->file_data;
	if (old_file_ptr->lock != UNLOCKED)
		return FILE_LOCKED;
	sprintf(old_pathname, "%s%s/%s/%s", LOCAL_DRIVE_PREFIX,
			old_file_ptr->data.machine_IP_name, owner_name, file_name);
	sprintf(new_pathname, "%s%s/%s/%s", LOCAL_DRIVE_PREFIX,
			old_file_ptr->data.machine_IP_name, owner_name, new_file_name);
	new_fn = Index.GetFileNode(machine_IP, owner_name, new_file_name);
	if (new_fn == NULL) {
		if (rename(old_pathname, new_pathname) != 0)
			return CANNOT_RENAME_FILE;
		strncpy(old_file_ptr->data.machine_IP_name, new_file_name,
				MAX_CONDOR_FILENAME_LENGTH);
		old_file_ptr->data.last_modified_time = time(NULL);
		(void) Index.AddNewFile(machine_IP, owner_name, new_file_name,
								old_file_ptr);
    } else {
		new_file_ptr = new_fn->file_data;
		if (new_file_ptr->lock != UNLOCKED)
			return FILE_LOCKED;
		if (rename(old_pathname, new_pathname) != 0)
			return CANNOT_RENAME_FILE;
		new_file_ptr->data.size = old_file_ptr->data.size;
		new_file_ptr->data.state = old_file_ptr->data.state;
		new_file_ptr->data.last_modified_time = time(NULL);
		(void) FileStats.RemoveFileInfo(old_file_ptr);
    }
	(void) Index.DeleteFile(machine_IP, owner_name, file_name);
/*	return RENAMED; */
	return OK;
}

u_short IMDS::RemoveFile(struct in_addr machine_IP,
						 const char*    owner_name,
						 const char*    file_name)
{
	file_node* file_ptr;
	int        d_ret_code;
	int        i_ret_code;

	file_ptr = Index.GetFileNode(machine_IP, owner_name, file_name);
	if (file_ptr == NULL)
		return DOES_NOT_EXIST;
	d_ret_code = FileStats.RemoveFileInfo(file_ptr->file_data);
	if (d_ret_code != REMOVED_FILE)
		return (u_short) d_ret_code;
	i_ret_code = Index.DeleteFile(machine_IP, owner_name, file_name);
	return (u_short) i_ret_code;
}

void IMDS::TransferFileInfo(int socket_desc)
{
  FileStats.TransferFileInfo(socket_desc);
}

<commit_msg>Files should be unlocked when they are added to the imds.  Otherwise, the files get all locked up when the server restarts.<commit_after>#include <time.h>
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "imds2.h"
#include "fileinfo2.h"
#include "fileindex2.h"

u_lint IMDS::GetNumFiles()
{
	return FileStats.GetNumFiles();
}

int IMDS::LockStatus(struct in_addr machine_IP,
					 const char*    owner_name,
					 const char*    file_name)
{
	return Index.LockStatus(machine_IP, owner_name, file_name);
}

void IMDS::Lock(struct in_addr machine_IP,
				const char*    owner_name,
				const char*    file_name,
				file_state     state)
{
	file_node*      file_ptr;
	file_info_node* file_data;

	file_ptr = Index.GetFileNode(machine_IP, owner_name, file_name);
	if (file_ptr != NULL) {
		file_data = file_ptr->file_data;
		file_data->lock = EXCLUSIVE_LOCK;
		file_data->data.state = state;
    }
}

void IMDS::Unlock(struct in_addr machine_IP,
				  const char*    owner_name,
				  const char*    file_name)
{
	file_node*      file_ptr;
	file_info_node* file_data;

	file_ptr = Index.GetFileNode(machine_IP, owner_name, file_name);
	if (file_ptr != NULL) {
		file_data = file_ptr->file_data;
		file_data->lock = UNLOCKED;
		file_data->data.state = ON_SERVER;
    }
}

int IMDS::AddFile(struct in_addr machine_IP,
		  const char*    owner_name,
		  const char*    file_name,
		  u_lint         file_size,
		  file_state     state)
{
  file_node*      file_ptr;
  file_info_node* file_data;
  char            pathname[MAX_PATHNAME_LENGTH];

  file_ptr = Index.GetFileNode(machine_IP, owner_name, file_name);
  if (file_ptr != NULL)
    {
      file_data = file_ptr->file_data;
      if (file_data->lock != UNLOCKED)
	return FILE_LOCKED;
      sprintf(pathname, "%s%s/%s/%s", LOCAL_DRIVE_PREFIX,
	      file_data->data.machine_IP_name, owner_name, file_name);
      if ((state == NOT_PRESENT) || (state == LOADING))
	remove(pathname);                        // Do not care if fails
      file_data->data.size = file_size;
      file_data->data.last_modified_time = time(NULL);
      file_data->data.state = state;
      file_data->lock = UNLOCKED;
    }
  else
    {
      file_data = FileStats.AddFileInfo(machine_IP, owner_name, file_name,
					file_size, state, NULL);
      (void) Index.AddNewFile(machine_IP, owner_name, file_name, file_data);
    }
  return CREATED;
}

int IMDS::RenameFile(struct in_addr machine_IP,
					 const char*    owner_name,
					 const char*    file_name,
					 const char*    new_file_name)
{
	file_node*      old_fn;
	file_node*      new_fn;
	file_info_node* old_file_ptr;
	file_info_node* new_file_ptr;
	char            new_pathname[MAX_PATHNAME_LENGTH];
	char            old_pathname[MAX_PATHNAME_LENGTH];

	old_fn = Index.GetFileNode(machine_IP, owner_name, file_name);
	if (old_fn == NULL)
		return DOES_NOT_EXIST;
	old_file_ptr = old_fn->file_data;
	if (old_file_ptr->lock != UNLOCKED)
		return FILE_LOCKED;
	sprintf(old_pathname, "%s%s/%s/%s", LOCAL_DRIVE_PREFIX,
			old_file_ptr->data.machine_IP_name, owner_name, file_name);
	sprintf(new_pathname, "%s%s/%s/%s", LOCAL_DRIVE_PREFIX,
			old_file_ptr->data.machine_IP_name, owner_name, new_file_name);
	new_fn = Index.GetFileNode(machine_IP, owner_name, new_file_name);
	if (new_fn == NULL) {
		if (rename(old_pathname, new_pathname) != 0)
			return CANNOT_RENAME_FILE;
		strncpy(old_file_ptr->data.machine_IP_name, new_file_name,
				MAX_CONDOR_FILENAME_LENGTH);
		old_file_ptr->data.last_modified_time = time(NULL);
		(void) Index.AddNewFile(machine_IP, owner_name, new_file_name,
								old_file_ptr);
    } else {
		new_file_ptr = new_fn->file_data;
		if (new_file_ptr->lock != UNLOCKED)
			return FILE_LOCKED;
		if (rename(old_pathname, new_pathname) != 0)
			return CANNOT_RENAME_FILE;
		new_file_ptr->data.size = old_file_ptr->data.size;
		new_file_ptr->data.state = old_file_ptr->data.state;
		new_file_ptr->data.last_modified_time = time(NULL);
		(void) FileStats.RemoveFileInfo(old_file_ptr);
    }
	(void) Index.DeleteFile(machine_IP, owner_name, file_name);
/*	return RENAMED; */
	return OK;
}

u_short IMDS::RemoveFile(struct in_addr machine_IP,
						 const char*    owner_name,
						 const char*    file_name)
{
	file_node* file_ptr;
	int        d_ret_code;
	int        i_ret_code;

	file_ptr = Index.GetFileNode(machine_IP, owner_name, file_name);
	if (file_ptr == NULL)
		return DOES_NOT_EXIST;
	d_ret_code = FileStats.RemoveFileInfo(file_ptr->file_data);
	if (d_ret_code != REMOVED_FILE)
		return (u_short) d_ret_code;
	i_ret_code = Index.DeleteFile(machine_IP, owner_name, file_name);
	return (u_short) i_ret_code;
}

void IMDS::TransferFileInfo(int socket_desc)
{
  FileStats.TransferFileInfo(socket_desc);
}

<|endoftext|>


<commit_before>/*
** Copyright 2011 Merethis
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <assert.h>
#include <stdlib.h>
#include "config/applier/endpoint.hh"
#include "exceptions/basic.hh"
#include "io/acceptor.hh"
#include "io/connector.hh"
#include "io/protocols.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::config::applier;

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Default constructor.
 */
endpoint::endpoint() : QObject() {}

/**
 *  @brief Copy constructor.
 *
 *  Any call to this constructor will result in a call to abort().
 *
 *  @param[in] e Object to copy.
 */
endpoint::endpoint(endpoint const& e) : QObject() {
  (void)e;
  assert(false);
  abort();
}

/**
 *  @brief Assignment operator.
 *
 *  Any call to this method will result in a call to abort().
 *
 *  @param[in] e Object to copy.
 *
 *  @return This object.
 */
endpoint& endpoint::operator=(endpoint const& e) {
  (void)e;
  assert(false);
  abort();
  return (*this);
}

/**
 *  Create and register an endpoint according to configuration.
 *
 *  @param[in] cfg       Endpoint configuration.
 *  @param[in] is_output true if the endpoint will act as output.
 */
void endpoint::_create_endpoint(config::endpoint const& cfg, bool is_output) {
  // Create endpoint object.
  QSharedPointer<io::endpoint> endp;
  bool is_acceptor;
  int level;
  for (QMap<QString, io::protocols::protocol>::const_iterator it = io::protocols::instance().begin(),
         end = io::protocols::instance().end();
       it != end;
       ++it) {
    if ((it.value().osi_to == 7)
        && it.value().endpntfactry->has_endpoint(cfg, !is_output, is_output)) {
      endp = QSharedPointer<io::endpoint>(it.value().endpntfactry->new_endpoint(cfg, !is_output, is_output, is_acceptor));
      level = it.value().osi_from - 1;
      break ;
    }
  }
  if (endp.isNull())
    throw (exceptions::basic() << "no matching protocol found for endpoint '"
             << cfg.name.toStdString().c_str() << "'");

  // Create remaining objects.
  io::endpoint* prev(endp.data());
  while (level > 0) {
    // Browse protocol list.
    QMap<QString, io::protocols::protocol>::const_iterator it(io::protocols::instance().begin());
    QMap<QString, io::protocols::protocol>::const_iterator end(io::protocols::instance().end());
    while (it != end) {
      if ((it.value().osi_from == level)
          && (it.value().endpntfactry->has_endpoint(cfg, !is_output, is_output))) {
        if (is_acceptor) {
          QSharedPointer<io::acceptor> current(static_cast<io::acceptor*>(it.value().endpntfactry->new_endpoint(cfg, !is_output, is_output, is_acceptor)));
          static_cast<io::acceptor*>(prev)->on(current);
          prev = current.data();
        }
        else {
          QSharedPointer<io::connector> current(static_cast<io::connector*>(it.value().endpntfactry->new_endpoint(cfg, !is_output, is_output, is_acceptor)));
          static_cast<io::connector*>(prev)->from(current);
          prev = current.data();
        }
        level = it.value().osi_to;
        break ;
      }
      ++it;
    }
    if ((1 == level) && (it == end))
      throw (exceptions::basic() << "no matching protocol found for endpoint '"
               << cfg.name.toStdString().c_str() << "'");
    --level;
  }

  // Create thread.
  QScopedPointer<processing::failover> fo(new processing::failover(is_output));
  fo->set_endpoint(endp);

  // Connect thread.
  connect(fo.data(), SIGNAL(finished()), fo.data(), SLOT(deleteLater()));
  if (!is_output) {
    connect(fo.data(), SIGNAL(finished()), this, SLOT(terminated_input()));
    _inputs[cfg] = fo.data();
  }
  else {
    connect(fo.data(), SIGNAL(finished()), this, SLOT(terminated_output()));
    _outputs[cfg] = fo.data();
  }

  // Run thread.
  fo.take()->start();

  return ;
}

/**
 *  Diff the current configuration with the new configuration.
 *
 *  @param[in]  current       Current endpoints.
 *  @param[in]  new_endpoints New endpoints configuration.
 *  @param[out] to_create     Endpoints that should be created.
 */
void endpoint::_diff_endpoints(QMap<config::endpoint, processing::failover*> & current,
                               QList<config::endpoint> const& new_endpoints,
                               QList<config::endpoint>& to_create) {
  // Find which endpoints will be kept, created and deleted.
  QMap<config::endpoint, processing::failover*> to_delete(current);
  for (QList<config::endpoint>::const_iterator it = new_endpoints.begin(),
         end = new_endpoints.end();
       it != end;
       ++it) {
    QMap<config::endpoint, processing::failover*>::iterator endp(to_delete.find(*it));
    if (endp != to_delete.end())
      to_delete.erase(endp);
    else
      to_create.push_back(*it);
  }

  // Remove old endpoints.
  for (QMap<config::endpoint, processing::failover*>::iterator it = to_delete.begin(),
         end = to_delete.end();
       it != end;
       ++it) {
    // XXX : send only termination request, object will
    //       be destroyed by event loop on termination.
    //       But wait for threads, because
  }

  return ;
}

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Destructor.
 */
endpoint::~endpoint() {}

/**
 *  Apply the endpoint configuration.
 *
 *  @param[in] inputs  Inputs configuration.
 *  @param[in] outputs Outputs configuration.
 */
void endpoint::apply(QList<config::endpoint> const& inputs,
                     QList<config::endpoint> const& outputs) {
  // Remove old inputs and generate inputs to create.
  QList<config::endpoint> in_to_create;
  _diff_endpoints(_inputs, inputs, in_to_create);

  // Remove old outputs and generate outputs to create.
  QList<config::endpoint> out_to_create;
  _diff_endpoints(_outputs, outputs, out_to_create);

  // Create new outputs.
  for (QList<config::endpoint>::iterator it = out_to_create.begin(),
         end = out_to_create.end();
       it != end;
       ++it)
    _create_endpoint(*it, true);

  // Create new inputs.
  for (QList<config::endpoint>::iterator it = in_to_create.begin(),
         end = in_to_create.end();
       it != end;
       ++it)
    _create_endpoint(*it, false);

  return ;
}

/**
 *  Get the class instance.
 *
 *  @return Class instance.
 */
endpoint& endpoint::instance() {
  static endpoint gl_endpoint;
  return (gl_endpoint);
}

/**
 *  An input thread finished executing.
 */
void endpoint::terminated_input() {
  // XXX
}

/**
 *  An output thread finished executing.
 */
void endpoint::terminated_output() {
  // XXX
}
<commit_msg>Bugfix.<commit_after>/*
** Copyright 2011 Merethis
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <assert.h>
#include <stdlib.h>
#include "config/applier/endpoint.hh"
#include "exceptions/basic.hh"
#include "io/acceptor.hh"
#include "io/connector.hh"
#include "io/protocols.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::config::applier;

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Default constructor.
 */
endpoint::endpoint() : QObject() {}

/**
 *  @brief Copy constructor.
 *
 *  Any call to this constructor will result in a call to abort().
 *
 *  @param[in] e Object to copy.
 */
endpoint::endpoint(endpoint const& e) : QObject() {
  (void)e;
  assert(false);
  abort();
}

/**
 *  @brief Assignment operator.
 *
 *  Any call to this method will result in a call to abort().
 *
 *  @param[in] e Object to copy.
 *
 *  @return This object.
 */
endpoint& endpoint::operator=(endpoint const& e) {
  (void)e;
  assert(false);
  abort();
  return (*this);
}

/**
 *  Create and register an endpoint according to configuration.
 *
 *  @param[in] cfg       Endpoint configuration.
 *  @param[in] is_output true if the endpoint will act as output.
 */
void endpoint::_create_endpoint(config::endpoint const& cfg, bool is_output) {
  // Create endpoint object.
  QSharedPointer<io::endpoint> endp;
  bool is_acceptor;
  int level;
  for (QMap<QString, io::protocols::protocol>::const_iterator it = io::protocols::instance().begin(),
         end = io::protocols::instance().end();
       it != end;
       ++it) {
    if ((it.value().osi_to == 7)
        && it.value().endpntfactry->has_endpoint(cfg, !is_output, is_output)) {
      endp = QSharedPointer<io::endpoint>(it.value().endpntfactry->new_endpoint(cfg, !is_output, is_output, is_acceptor));
      level = it.value().osi_from - 1;
      break ;
    }
  }
  if (endp.isNull())
    throw (exceptions::basic() << "no matching protocol found for endpoint '"
             << cfg.name.toStdString().c_str() << "'");

  // Create remaining objects.
  io::endpoint* prev(endp.data());
  while (level > 0) {
    // Browse protocol list.
    QMap<QString, io::protocols::protocol>::const_iterator it(io::protocols::instance().begin());
    QMap<QString, io::protocols::protocol>::const_iterator end(io::protocols::instance().end());
    while (it != end) {
      if ((it.value().osi_to == level)
          && (it.value().endpntfactry->has_endpoint(cfg, !is_output, is_output))) {
        if (is_acceptor) {
          QSharedPointer<io::acceptor> current(static_cast<io::acceptor*>(it.value().endpntfactry->new_endpoint(cfg, !is_output, is_output, is_acceptor)));
          static_cast<io::acceptor*>(prev)->on(current);
          prev = current.data();
        }
        else {
          QSharedPointer<io::connector> current(static_cast<io::connector*>(it.value().endpntfactry->new_endpoint(cfg, !is_output, is_output, is_acceptor)));
          static_cast<io::connector*>(prev)->from(current);
          prev = current.data();
        }
        level = it.value().osi_from;
        break ;
      }
      ++it;
    }
    if ((1 == level) && (it == end))
      throw (exceptions::basic() << "no matching protocol found for endpoint '"
               << cfg.name.toStdString().c_str() << "'");
    --level;
  }

  // Create thread.
  QScopedPointer<processing::failover> fo(new processing::failover(is_output));
  fo->set_endpoint(endp);

  // Connect thread.
  connect(fo.data(), SIGNAL(finished()), fo.data(), SLOT(deleteLater()));
  if (!is_output) {
    connect(fo.data(), SIGNAL(finished()), this, SLOT(terminated_input()));
    _inputs[cfg] = fo.data();
  }
  else {
    connect(fo.data(), SIGNAL(finished()), this, SLOT(terminated_output()));
    _outputs[cfg] = fo.data();
  }

  // Run thread.
  fo.take()->start();

  return ;
}

/**
 *  Diff the current configuration with the new configuration.
 *
 *  @param[in]  current       Current endpoints.
 *  @param[in]  new_endpoints New endpoints configuration.
 *  @param[out] to_create     Endpoints that should be created.
 */
void endpoint::_diff_endpoints(QMap<config::endpoint, processing::failover*> & current,
                               QList<config::endpoint> const& new_endpoints,
                               QList<config::endpoint>& to_create) {
  // Find which endpoints will be kept, created and deleted.
  QMap<config::endpoint, processing::failover*> to_delete(current);
  for (QList<config::endpoint>::const_iterator it = new_endpoints.begin(),
         end = new_endpoints.end();
       it != end;
       ++it) {
    QMap<config::endpoint, processing::failover*>::iterator endp(to_delete.find(*it));
    if (endp != to_delete.end())
      to_delete.erase(endp);
    else
      to_create.push_back(*it);
  }

  // Remove old endpoints.
  for (QMap<config::endpoint, processing::failover*>::iterator it = to_delete.begin(),
         end = to_delete.end();
       it != end;
       ++it) {
    // XXX : send only termination request, object will
    //       be destroyed by event loop on termination.
    //       But wait for threads, because
  }

  return ;
}

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Destructor.
 */
endpoint::~endpoint() {}

/**
 *  Apply the endpoint configuration.
 *
 *  @param[in] inputs  Inputs configuration.
 *  @param[in] outputs Outputs configuration.
 */
void endpoint::apply(QList<config::endpoint> const& inputs,
                     QList<config::endpoint> const& outputs) {
  // Remove old inputs and generate inputs to create.
  QList<config::endpoint> in_to_create;
  _diff_endpoints(_inputs, inputs, in_to_create);

  // Remove old outputs and generate outputs to create.
  QList<config::endpoint> out_to_create;
  _diff_endpoints(_outputs, outputs, out_to_create);

  // Create new outputs.
  for (QList<config::endpoint>::iterator it = out_to_create.begin(),
         end = out_to_create.end();
       it != end;
       ++it)
    _create_endpoint(*it, true);

  // Create new inputs.
  for (QList<config::endpoint>::iterator it = in_to_create.begin(),
         end = in_to_create.end();
       it != end;
       ++it)
    _create_endpoint(*it, false);

  return ;
}

/**
 *  Get the class instance.
 *
 *  @return Class instance.
 */
endpoint& endpoint::instance() {
  static endpoint gl_endpoint;
  return (gl_endpoint);
}

/**
 *  An input thread finished executing.
 */
void endpoint::terminated_input() {
  // XXX
}

/**
 *  An output thread finished executing.
 */
void endpoint::terminated_output() {
  // XXX
}
<|endoftext|>


<commit_before>#ifndef CONTAINERS_NAME_STRING_HPP_
#define CONTAINERS_NAME_STRING_HPP_

#include <string>

#include "http/json/json_adapter.hpp"
#include "rpc/serialize_macros.hpp"

// The kind of string that can only contain either the empty string or acceptable names for
// things.  You may only assign non-empty strings.

class name_string_t {
public:
    // Initializes to the empty string.
    name_string_t();

    // Succeeds on valid non-empty strings.
    MUST_USE bool assign_value(const std::string& s);

    const std::string& str() const { return str_; }

    bool empty() const { return str_.empty(); }  // TODO(1253): get rid of this.
    const char *c_str() const { return str_.c_str(); }  // TODO(1253): get rid of this.

    RDB_MAKE_ME_SERIALIZABLE_1(str_);

    static const char *const valid_char_msg;

private:
    std::string str_;
};

inline bool operator==(const name_string_t& x, const name_string_t& y) {
    return x.str() == y.str();
}

inline bool operator!=(const name_string_t& x, const name_string_t& y) {
    return !(x == y);
}

inline bool operator<(const name_string_t& x, const name_string_t& y) {
    return x.str() < y.str();
}

// ctx-less json adapter concept for name_string_t
json_adapter_if_t::json_adapter_map_t get_json_subfields(name_string_t *target);
cJSON *render_as_json(name_string_t *target);
void apply_json_to(cJSON *change, name_string_t *target);
void on_subfield_change(name_string_t *);

void debug_print(append_only_printf_buffer_t *buf, const name_string_t& s);

#endif  // CONTAINERS_NAME_STRING_HPP_
<commit_msg>Removed some TODO(1253).<commit_after>#ifndef CONTAINERS_NAME_STRING_HPP_
#define CONTAINERS_NAME_STRING_HPP_

#include <string>

#include "http/json/json_adapter.hpp"
#include "rpc/serialize_macros.hpp"

// The kind of string that can only contain either the empty string or acceptable names for
// things.  You may only assign non-empty strings.

class name_string_t {
public:
    // Initializes to the empty string.
    name_string_t();

    // Succeeds on valid non-empty strings.
    MUST_USE bool assign_value(const std::string& s);

    const std::string& str() const { return str_; }

    // TODO: We should get rid of this, and code that uses this is known to be untrustworthy.
    bool empty() const { return str_.empty(); }
    const char *c_str() const { return str_.c_str(); }

    RDB_MAKE_ME_SERIALIZABLE_1(str_);

    static const char *const valid_char_msg;

private:
    std::string str_;
};

inline bool operator==(const name_string_t& x, const name_string_t& y) {
    return x.str() == y.str();
}

inline bool operator!=(const name_string_t& x, const name_string_t& y) {
    return !(x == y);
}

inline bool operator<(const name_string_t& x, const name_string_t& y) {
    return x.str() < y.str();
}

// ctx-less json adapter concept for name_string_t
json_adapter_if_t::json_adapter_map_t get_json_subfields(name_string_t *target);
cJSON *render_as_json(name_string_t *target);
void apply_json_to(cJSON *change, name_string_t *target);
void on_subfield_change(name_string_t *);

void debug_print(append_only_printf_buffer_t *buf, const name_string_t& s);

#endif  // CONTAINERS_NAME_STRING_HPP_
<|endoftext|>


<commit_before>#include "zpublic.hpp"
#include "stdio.h"
#include <string>
#include <atlbase.h>
#include <fstream>

#include "cpptest-1.1.2/src/cpptest.h"
using namespace Test;
#ifdef _MSC_VER
#pragma warning (disable: 4290)
#endif

void test_mrumap();
void test_thread();
void test_ptr();
void test_vector();
void teststring();
void test_time();
void test_info();
void test_encode();
void test_hashtable();
void test_basic();
void test_heap();

class FailTestSuite : public Test::Suite
{
public:
    FailTestSuite()
    {
        TEST_ADD(FailTestSuite::success)
        TEST_ADD(FailTestSuite::always_fail)

    }

private:
    void success() {}

    void always_fail()
    {
        TEST_FAIL("unconditional fail");
    }
};

int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "chs");
    Suite ts;
    ts.add(std::auto_ptr<Test::Suite>(new FailTestSuite));
    std::auto_ptr<Test::Output> output(new Test::HtmlOutput); //new Test::TextOutput(Test::TextOutput::Verbose));
    ts.run(*output, true);
    Test::HtmlOutput* const html = dynamic_cast<Test::HtmlOutput*>(output.get());
    if (html)
    {
        std::ofstream fout("./test.html");
        html->generate(fout, true, "TestReport");
    }
//     const BYTE pp[] = {"124"};
//     //cout << hex <<  zl::ExCRC32(pp, 3) << endl;
//     printf("%08x", zl::ExCRC32(pp, 3));
//
//
//     const char *pp2 = {"124"};
//     printf("%08x", zl::HashKey(pp2));
//     printf("%08x", zl::HashKey(100));
//
//     zl::Pair<int, int> p;
//     p.key =1; p.value =2;
//     zl::Pair<int, int> p2(p);
//     printf("%d %d", p2.key, p2.value);
//
//     zl::Bit b1(1), b2;
//     printf("%d %d %d %d %d %d\n", b1, b2, b1<b2, b1&b2, b1|b2, b1^b2);
//     //std::cout << b1 << std::endl;
//     //<< " "<< b2 << " " << b1<b2 << " " << b1&b2 << " " << b1|b2 << " " << b1^b2 << std::endl;
//
//     char source[100] = "what the fuck xxxx qqqqd fsds kevin sadsadeqw";
//     char pattern[10] = "kevin";
//     size_t ret = zl::SundayMatchString(source, strlen(source), pattern, strlen(pattern), 0);
//     printf("%d\n",ret);
//
//     zl::CIncreaseMemory<char> mem(8);
//     mem.Inc();
//     printf("%ld\n", mem.Size());
//     mem.Inc();
//     printf("%ld\n", mem.Size());
//     mem.Release();
//
//     int a;
//     int *b = 0;
//     zl::_Allocate(4, &a);
//     zl::_Allocate(b, 10);
//     b = zl::_Allocate<int>(10);
//
//
//     zl::CArrayFixed<int, 10> arr10 = {0};
//     for (int i = 0; i < 10; i++)
//         arr10[i] = i * 5;
//     printf("%d\n", arr10[1]);
//
//     zl::CArrayFixedEx<int, 20> arr20 = {0};
//     for (int i = 0; i < 20; i++)
//         arr20[i] = i * 5;
//
//     zl::CArrayVariable<int> arrX;
//     arrX = arr20[zl::DoublePos(13, 17)];
//
//     for (size_t i = 0; i < arrX.Size(); i++)
//         printf("%d\n", arrX[i]);
//
//     printf("\n");
//
//     zl::CArrayVariable<int> arrY = arr20[zl::ThreePos(5, 17, 3)];
//     for (size_t i = 0; i < arrY.Size(); i++)
//         printf("%d\n", arrY[i]);

// 	zl::basic_string str("hello world");
// 	printf("%s\n",str.c_str());
// 	str.upper();
// 	printf("%s\n",str.c_str());
// 	str.lower();
// 	printf("%s\n",str.c_str());
// 	printf("%d\n",str.find("world"));
// 	printf("%d\n",str.rfind("or"));
//
//
//
//     USES_CONVERSION;
//     std::string strB(CW2A(L"hello", CP_UTF8));
//     std::string strB2, strB3;
//     zl::Base64Encode(strB, &strB2);
//     printf("%s\n", strB2.c_str());
//     zl::Base64Decode(strB2, &strB3);
//     wprintf(CA2W(strB3.c_str(), CP_UTF8));

    test_mrumap();
    //test_thread();
    test_ptr();

    ///> 躸ר
	test_heap();
	test_hashtable();
    test_vector();

	teststring();

    ///> zapר
    test_time();
    test_info();
    test_encode();
    test_basic();

    return 0;
}

void test_mrumap()
{
    typedef zl::MRUCache<int, int> Cache;
    Cache cache(4);
    cache.Put(1, 5);
    cache.Put(2, 10);
    cache.Put(3, 15);
    cache.Put(4, 20);
    cache.Put(2, 25);
    for (Cache::const_iterator p = cache.begin();
        p != cache.end();
        ++p)
    {
        printf("%d ", p->second);
    }

    typedef zl::HashingMRUCache<const char*, int> Cache2;
    Cache2 cache2(4);
    cache2.Put("1", 5);
    cache2.Put("2", 10);
    cache2.Put("3", 15);
    cache2.Put("4", 20);
    cache2.Put("2", 25);
    for (Cache2::const_iterator p = cache2.begin();
        p != cache2.end();
        ++p)
    {
        printf("%d ", p->second);
    }
}

void test_thread()
{
    zl::CEvent xEvent;
    xEvent.Create();
    xEvent.Wait(5000);
    xEvent.Set();
    xEvent.Wait(10000);

    zl::CSemaphore xSemaphore;
    xSemaphore.Create(0, 10);
    xSemaphore.Wait(3000);
    xSemaphore.Release();
    xSemaphore.Release();
    xSemaphore.Wait(3000);
    xSemaphore.Wait(3000);
    xSemaphore.Wait(3000);

}

void test_ptr()
{
    class CPtrTest : public zl::RefCounted<CPtrTest>
    {
    public:
        CPtrTest() {}

    private:
        FREIEND_REFCOUNTED(CPtrTest)
    };

    CPtrTest *pp1 = new CPtrTest;
    pp1->AddRef();
    pp1->AddRef();
    pp1->Release();
    pp1->Release();
}

void test_vector()
{
	zl::CSimpleVector<int> vecInt(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.RemoveAt(3);
    zl::CSimpleVector<int> vecInt2 = vecInt;
    for (int i=0; i<vecInt2.GetSize(); i++)
    {
        printf("%d ", vecInt2[i]);
    }
}

void teststring()
{
	zl::CArrayVariable<zl::basic_string*> stringlist;
	zl::basic_string a = "hello kevin fuck you kevin yes true";
	zl::basic_string sub;
	zl::basic_string b;
	zl::CSimpleVector<zl::basic_string *> vecSplit;
	a.split(" ", vecSplit);

	b = a + " fuck you";
	printf("%s\n",b.c_str());

	b = a.GetSub(6,5);
	zl::basic_string x;
	b.swap(x);
	printf("%s\n",x.c_str());
	b = a.replace("kevin", "()");

	zl::basic_string str1 = "kzvin";
	zl::basic_string str2 = "kevin";
	printf("%d", str1 <= str2);
	//stringlist[0] = &a;
//     zl::basic_string a = "hello kevin";
//     zl::basic_string sub;
//     if(a.GetSub(&sub, 6, 5))
//     {
//         printf("%s\n",sub.c_str());
//     }
    //stringlist[0] = &a;

    //a.split(" ", stringlist);
}

void test_time()
{
//     LARGE_INTEGER llTimeBegin = {0};
//     zl::CTimeInterval::GetTime(llTimeBegin);
//
//     __time64_t t1 = 0;
//     zl::GetFileTimeInfo(L"c:\\windows\\notepad.exe", &t1, 0, 0);
//     FILETIME ft = zl::Time642FileTime(t1);
//
//     SYSTEMTIME sTime;
//     GetSystemTime(&sTime);
//     wchar_t strTime[TIME_STRING_MAX_LEN] = {0};
//     zl::Time2Str(sTime, strTime);
//     zl::Str2Time(strTime, sTime);
//
//
//     double dfTimeInterval = 0.0;
//     zl::CTimeInterval::Calc(llTimeBegin, dfTimeInterval);
//     printf("%.2f", dfTimeInterval);

    zl::timer t;
    printf("\n%f ", zl::timer_elapsed_min);
    ::Sleep(1000);
    printf("%f\n", t.elapsed());
}

void test_info()
{
    std::wstring sGuid = zl::GenerateGUID();
    zl::IsValidGUID(sGuid);
}

void test_encode()
{
    std::wstring sHello1(L"hello");
    std::string sHello2 = zl::WideToUTF8(sHello1);
    std::wstring sHello3 = zl::UTF8ToWide(sHello2);
}

void test_hashtable()
{
	struct st
	{
		int key;
		int value;
	};

	struct st_equal
	{
		bool operator() (const st& first, const st& second) const
		{
			return first.value == second.value;
		}
	};

	struct st_hash
	{
		unsigned long operator() (const st& first, const unsigned long n) const
		{
			return first.value % n;
		}
	};

	zl::HashTable<st, st_hash, st_equal> myHashTable(10);
	st tmp;
	int count = 0;
	for(unsigned long i = 0; i<100; i++)
	{
		tmp.key = 10;
		tmp.value = i;
		myHashTable.insert_unique(tmp);
	}
	tmp.value = 10;
	myHashTable.find(tmp);
	tmp.key = 21;
	tmp.value = 64;
	myHashTable.find(tmp);
}

void test_basic()
{
//     zl::singleton<std::string>::Instance() = "123";
//     printf("\n%s\n", zl::singleton<std::string>::Instance().c_str());
//
//     zl::scoped_ptr<std::string> p(new std::string("1234"));
//     p->c_str();

    zl::scoped_arr<int> arrInt(new int[10]);
}

void test_heap()
{
	zl::Heap<zl::basic_string> heap;
    zl::Heap<int> heap2;
	int array[11] = {68, 32, 19, 21, 16, 31, 50, 24, 13, 26, 65};
	char str[10][20] = {"kevin", "lily", "david", "zapline", "lafeng", "laopan", "animal", "dachu", "moster"};
	//int array[11] = {31, 65, 68};
	zl::basic_string x;

	for(int i=0; i<9; i++)
		heap.push(str[i]);
    //heap.print_heap();
	for(int i = 0; i < 9; i++)
	{
		if(heap.pop(x))
            printf("%s ", x.c_str());
	}

    int b;
    for(int i = 0; i < 11; i++)
        heap2.push(array[i]);
    //heap2.print_heap1();
    for(int i = 0; i < 11; i++)
    {
        if(heap2.pop(b))
            printf("%d ", b);
    }

	//heap.print_heap();
}<commit_msg>修改测试输出目录<commit_after>#include "zpublic.hpp"
#include "stdio.h"
#include <string>
#include <atlbase.h>
#include <fstream>

#include "cpptest-1.1.2/src/cpptest.h"
using namespace Test;
#ifdef _MSC_VER
#pragma warning (disable: 4290)
#endif

void test_mrumap();
void test_thread();
void test_ptr();
void test_vector();
void teststring();
void test_time();
void test_info();
void test_encode();
void test_hashtable();
void test_basic();
void test_heap();

class FailTestSuite : public Test::Suite
{
public:
    FailTestSuite()
    {
        TEST_ADD(FailTestSuite::success)
        TEST_ADD(FailTestSuite::always_fail)

    }

private:
    void success() {}

    void always_fail()
    {
        TEST_FAIL("unconditional fail");
    }
};

int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "chs");
    Suite ts;
    ts.add(std::auto_ptr<Test::Suite>(new FailTestSuite));
    std::auto_ptr<Test::Output> output(new Test::HtmlOutput); //new Test::TextOutput(Test::TextOutput::Verbose));
    ts.run(*output, true);
    Test::HtmlOutput* const html = dynamic_cast<Test::HtmlOutput*>(output.get());
    if (html)
    {
        std::ofstream fout("./bin/test.html");
        html->generate(fout, true, "TestReport");
    }
//     const BYTE pp[] = {"124"};
//     //cout << hex <<  zl::ExCRC32(pp, 3) << endl;
//     printf("%08x", zl::ExCRC32(pp, 3));
//
//
//     const char *pp2 = {"124"};
//     printf("%08x", zl::HashKey(pp2));
//     printf("%08x", zl::HashKey(100));
//
//     zl::Pair<int, int> p;
//     p.key =1; p.value =2;
//     zl::Pair<int, int> p2(p);
//     printf("%d %d", p2.key, p2.value);
//
//     zl::Bit b1(1), b2;
//     printf("%d %d %d %d %d %d\n", b1, b2, b1<b2, b1&b2, b1|b2, b1^b2);
//     //std::cout << b1 << std::endl;
//     //<< " "<< b2 << " " << b1<b2 << " " << b1&b2 << " " << b1|b2 << " " << b1^b2 << std::endl;
//
//     char source[100] = "what the fuck xxxx qqqqd fsds kevin sadsadeqw";
//     char pattern[10] = "kevin";
//     size_t ret = zl::SundayMatchString(source, strlen(source), pattern, strlen(pattern), 0);
//     printf("%d\n",ret);
//
//     zl::CIncreaseMemory<char> mem(8);
//     mem.Inc();
//     printf("%ld\n", mem.Size());
//     mem.Inc();
//     printf("%ld\n", mem.Size());
//     mem.Release();
//
//     int a;
//     int *b = 0;
//     zl::_Allocate(4, &a);
//     zl::_Allocate(b, 10);
//     b = zl::_Allocate<int>(10);
//
//
//     zl::CArrayFixed<int, 10> arr10 = {0};
//     for (int i = 0; i < 10; i++)
//         arr10[i] = i * 5;
//     printf("%d\n", arr10[1]);
//
//     zl::CArrayFixedEx<int, 20> arr20 = {0};
//     for (int i = 0; i < 20; i++)
//         arr20[i] = i * 5;
//
//     zl::CArrayVariable<int> arrX;
//     arrX = arr20[zl::DoublePos(13, 17)];
//
//     for (size_t i = 0; i < arrX.Size(); i++)
//         printf("%d\n", arrX[i]);
//
//     printf("\n");
//
//     zl::CArrayVariable<int> arrY = arr20[zl::ThreePos(5, 17, 3)];
//     for (size_t i = 0; i < arrY.Size(); i++)
//         printf("%d\n", arrY[i]);

// 	zl::basic_string str("hello world");
// 	printf("%s\n",str.c_str());
// 	str.upper();
// 	printf("%s\n",str.c_str());
// 	str.lower();
// 	printf("%s\n",str.c_str());
// 	printf("%d\n",str.find("world"));
// 	printf("%d\n",str.rfind("or"));
//
//
//
//     USES_CONVERSION;
//     std::string strB(CW2A(L"hello", CP_UTF8));
//     std::string strB2, strB3;
//     zl::Base64Encode(strB, &strB2);
//     printf("%s\n", strB2.c_str());
//     zl::Base64Decode(strB2, &strB3);
//     wprintf(CA2W(strB3.c_str(), CP_UTF8));

    test_mrumap();
    //test_thread();
    test_ptr();

    ///> 躸ר
	test_heap();
	test_hashtable();
    test_vector();

	teststring();

    ///> zapר
    test_time();
    test_info();
    test_encode();
    test_basic();

    return 0;
}

void test_mrumap()
{
    typedef zl::MRUCache<int, int> Cache;
    Cache cache(4);
    cache.Put(1, 5);
    cache.Put(2, 10);
    cache.Put(3, 15);
    cache.Put(4, 20);
    cache.Put(2, 25);
    for (Cache::const_iterator p = cache.begin();
        p != cache.end();
        ++p)
    {
        printf("%d ", p->second);
    }

    typedef zl::HashingMRUCache<const char*, int> Cache2;
    Cache2 cache2(4);
    cache2.Put("1", 5);
    cache2.Put("2", 10);
    cache2.Put("3", 15);
    cache2.Put("4", 20);
    cache2.Put("2", 25);
    for (Cache2::const_iterator p = cache2.begin();
        p != cache2.end();
        ++p)
    {
        printf("%d ", p->second);
    }
}

void test_thread()
{
    zl::CEvent xEvent;
    xEvent.Create();
    xEvent.Wait(5000);
    xEvent.Set();
    xEvent.Wait(10000);

    zl::CSemaphore xSemaphore;
    xSemaphore.Create(0, 10);
    xSemaphore.Wait(3000);
    xSemaphore.Release();
    xSemaphore.Release();
    xSemaphore.Wait(3000);
    xSemaphore.Wait(3000);
    xSemaphore.Wait(3000);

}

void test_ptr()
{
    class CPtrTest : public zl::RefCounted<CPtrTest>
    {
    public:
        CPtrTest() {}

    private:
        FREIEND_REFCOUNTED(CPtrTest)
    };

    CPtrTest *pp1 = new CPtrTest;
    pp1->AddRef();
    pp1->AddRef();
    pp1->Release();
    pp1->Release();
}

void test_vector()
{
	zl::CSimpleVector<int> vecInt(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.Add(1);
    vecInt.Add(2);
    vecInt.RemoveAt(3);
    zl::CSimpleVector<int> vecInt2 = vecInt;
    for (int i=0; i<vecInt2.GetSize(); i++)
    {
        printf("%d ", vecInt2[i]);
    }
}

void teststring()
{
	zl::CArrayVariable<zl::basic_string*> stringlist;
	zl::basic_string a = "hello kevin fuck you kevin yes true";
	zl::basic_string sub;
	zl::basic_string b;
	zl::CSimpleVector<zl::basic_string *> vecSplit;
	a.split(" ", vecSplit);

	b = a + " fuck you";
	printf("%s\n",b.c_str());

	b = a.GetSub(6,5);
	zl::basic_string x;
	b.swap(x);
	printf("%s\n",x.c_str());
	b = a.replace("kevin", "()");

	zl::basic_string str1 = "kzvin";
	zl::basic_string str2 = "kevin";
	printf("%d", str1 <= str2);
	//stringlist[0] = &a;
//     zl::basic_string a = "hello kevin";
//     zl::basic_string sub;
//     if(a.GetSub(&sub, 6, 5))
//     {
//         printf("%s\n",sub.c_str());
//     }
    //stringlist[0] = &a;

    //a.split(" ", stringlist);
}

void test_time()
{
//     LARGE_INTEGER llTimeBegin = {0};
//     zl::CTimeInterval::GetTime(llTimeBegin);
//
//     __time64_t t1 = 0;
//     zl::GetFileTimeInfo(L"c:\\windows\\notepad.exe", &t1, 0, 0);
//     FILETIME ft = zl::Time642FileTime(t1);
//
//     SYSTEMTIME sTime;
//     GetSystemTime(&sTime);
//     wchar_t strTime[TIME_STRING_MAX_LEN] = {0};
//     zl::Time2Str(sTime, strTime);
//     zl::Str2Time(strTime, sTime);
//
//
//     double dfTimeInterval = 0.0;
//     zl::CTimeInterval::Calc(llTimeBegin, dfTimeInterval);
//     printf("%.2f", dfTimeInterval);

    zl::timer t;
    printf("\n%f ", zl::timer_elapsed_min);
    ::Sleep(1000);
    printf("%f\n", t.elapsed());
}

void test_info()
{
    std::wstring sGuid = zl::GenerateGUID();
    zl::IsValidGUID(sGuid);
}

void test_encode()
{
    std::wstring sHello1(L"hello");
    std::string sHello2 = zl::WideToUTF8(sHello1);
    std::wstring sHello3 = zl::UTF8ToWide(sHello2);
}

void test_hashtable()
{
	struct st
	{
		int key;
		int value;
	};

	struct st_equal
	{
		bool operator() (const st& first, const st& second) const
		{
			return first.value == second.value;
		}
	};

	struct st_hash
	{
		unsigned long operator() (const st& first, const unsigned long n) const
		{
			return first.value % n;
		}
	};

	zl::HashTable<st, st_hash, st_equal> myHashTable(10);
	st tmp;
	int count = 0;
	for(unsigned long i = 0; i<100; i++)
	{
		tmp.key = 10;
		tmp.value = i;
		myHashTable.insert_unique(tmp);
	}
	tmp.value = 10;
	myHashTable.find(tmp);
	tmp.key = 21;
	tmp.value = 64;
	myHashTable.find(tmp);
}

void test_basic()
{
//     zl::singleton<std::string>::Instance() = "123";
//     printf("\n%s\n", zl::singleton<std::string>::Instance().c_str());
//
//     zl::scoped_ptr<std::string> p(new std::string("1234"));
//     p->c_str();

    zl::scoped_arr<int> arrInt(new int[10]);
}

void test_heap()
{
	zl::Heap<zl::basic_string> heap;
    zl::Heap<int> heap2;
	int array[11] = {68, 32, 19, 21, 16, 31, 50, 24, 13, 26, 65};
	char str[10][20] = {"kevin", "lily", "david", "zapline", "lafeng", "laopan", "animal", "dachu", "moster"};
	//int array[11] = {31, 65, 68};
	zl::basic_string x;

	for(int i=0; i<9; i++)
		heap.push(str[i]);
    //heap.print_heap();
	for(int i = 0; i < 9; i++)
	{
		if(heap.pop(x))
            printf("%s ", x.c_str());
	}

    int b;
    for(int i = 0; i < 11; i++)
        heap2.push(array[i]);
    //heap2.print_heap1();
    for(int i = 0; i < 11; i++)
    {
        if(heap2.pop(b))
            printf("%d ", b);
    }

	//heap.print_heap();
}<|endoftext|>


<commit_before>//
//  ofxLaserDacBase.cpp
//
//  Created by Seb Lee-Delisle on 07/11/2017.
//
//

#include "ofxLaserDacHelios.h"

using namespace ofxLaser;

DacHelios:: DacHelios() : heliosManager(DacHeliosManager::getInstance()) {
	pps = 30000;
	newPPS = 30000;

	frameMode = true;

	connected = false;
    newArmed = false;  // as in the PPS system, this knows
                            // if armed status has changed and sends
                            // signal to DAC
	deviceId = "";
	dacDevice = nullptr;

}
DacHelios:: ~DacHelios() {
	ofLogNotice("DacHelios destructor");
	//stopThread();
	close();

}

void DacHelios::close() {

	if(isThreadRunning()) {
		waitForThread(true); // also stops the thread
		if(lock()) {
			if(dacDevice!=nullptr) {
				dacDevice->SetClosed();
				dacDevice = nullptr;
			}
			unlock();
		}
		delete dacDevice;
	}
}

void DacHelios::setup(string name) {

	deviceName = name; // the parameter which shows the name

	ofLogNotice("DacHelios::setup "+name);

	connectToDevice(deviceName);

	pointBufferDisplay.set("Point Buffer", 0,0,1799);
	displayData.push_back(&deviceName);
	displayData.push_back(&pointBufferDisplay);

	startThread();

}

const vector<ofAbstractParameter*>& DacHelios :: getDisplayData() {
	if(lock()) {

		//pointBufferDisplay += (response.status.buffer_fullness-pointBufferDisplay)*1;

		//int pointssincelastmessage = (float)((ofGetElapsedTimeMicros()-lastMessageTimeMicros)*response.status.point_rate)/1000000.0f;

		//pointBufferDisplay = bufferedPoints.size();

		//latencyDisplay += (latencyMicros - latencyDisplay)*0.1;
		//reconnectCount = prepareSendCount;

		unlock();
	}

	return displayData;
}

bool DacHelios::connectToDevice(string name) {

	dacDevice = heliosManager.getDacDeviceForName(name);
	if(dacDevice!=nullptr) {
		deviceId = deviceName = dacDevice->nameStr;
		if(dacDevice->isClosed()) { // not sure why it should be but hey
			ofLogError("HeliosDac device is closed before it's used!"+ name);
			heliosManager.deleteDevice(dacDevice);
			connected = false;

			dacDevice = nullptr;
		} else {
			connected = true;
		}
	} else {
		connected = false;
	}

	return connected;

}

bool DacHelios:: sendFrame(const vector<Point>& points){
	if(!connected) return false;
	// get frame object

	DacHeliosFrame* frame = new DacHeliosFrame();

	// add all points into the frame object
	frameMode = true;
	for(ofxLaser::Point p : points) {
		frame->addPoint(p);
	}
	// add the frame object to the frame channel
	framesChannel.send(frame);

	return true;

}

bool DacHelios::sendPoints(const vector<Point>& points) {
	return false;

	//	if(bufferedPoints.size()>pps*0.5) {
//		return false;
//	}
//	frameMode = false;
//	HeliosPoint p1;
//	if(lock()) {
//		frameMode = false;
//
//		for(size_t i= 0; i<points.size(); i++) {
//			const Point& p2 = points[i];
//			p1.x = ofMap(p2.x,0,800, HELIOS_MIN, HELIOS_MAX);
//			p1.y = ofMap(p2.y,800,0, HELIOS_MIN, HELIOS_MAX); // Y is UP
//			p1.r = roundf(p2.r);
//			p1.g = roundf(p2.g);
//			p1.b = roundf(p2.b);
//			p1.i = 255;
//			addPoint(p1);
//		}
//		unlock();
//	}
//	return true;
};

bool DacHelios::setPointsPerSecond(uint32_t newpps) {
	ofLog(OF_LOG_NOTICE, "setPointsPerSecond " + ofToString(newpps));
	while(!lock());
	newPPS = newpps;
	unlock();
	return true;

};

void DacHelios :: setActive(bool active){
    newArmed = active;

}
void DacHelios :: reset() {
    if(lock()) {
        resetFlag = true;
        unlock();
    }
}

void DacHelios :: threadedFunction(){

	//const uint32_t samples_per_packet = 1024;
    const int minBuffer = 500; // TODO make this dependent on pointrate

	//HeliosPoint * samples = (HeliosPoint *)calloc(sizeof(HeliosPoint), samples_per_packet);
	DacHeliosFrame* currentFrame = nullptr;
	DacHeliosFrame* nextFrame = nullptr;
	DacHeliosFrame* newFrame = nullptr;

	while(isThreadRunning()) {

		if(connected && (newPPS!=pps)) {
			pps = newPPS;

		}
        if(connected && (newArmed!=armed)) {
            if((dacDevice!=nullptr) && (dacDevice->SetShutter(newArmed)==HELIOS_SUCCESS)) {
                armed = newArmed;
            }
        }

		if(connected && isThreadRunning()) {

			// is there a new frame?
			// if so, store it
			bool dacReady = false;
			int status = 0;

			while(!dacReady)  {
				if(framesChannel.tryReceive(newFrame)) {
					if(nextFrame!=nullptr) {
						delete nextFrame;
					}
					nextFrame = newFrame;
				}

				if(dacDevice!=nullptr) status = dacDevice->GetStatus();

				dacReady = (status == 1);

				if(!dacReady) {
					if(status>1)
						ofLog(OF_LOG_NOTICE, "heliosDac.getStatus : "+ ofToString(status));
					sleep(1);
				}

			}
			// if we got to here then the dac is ready but we might not have a
			// currentFrame yet...
			if(nextFrame!=nullptr) {
				if(currentFrame!=nullptr) {
					delete currentFrame;
				}
				currentFrame = nextFrame;
				nextFrame = nullptr;
			}
			if(currentFrame!=nullptr) {
				int result =  0;
				if(dacDevice!=nullptr) result = dacDevice->SendFrame(pps, HELIOS_FLAGS_SINGLE_MODE, currentFrame->samples, currentFrame->numSamples);
				//ofLog(OF_LOG_NOTICE, "heliosDac.WriteFrame : "+ ofToString(result));
				if(result <=-5000){ // then we have a USB connection error
					ofLog(OF_LOG_NOTICE, "heliosDac.WriteFrame failed. LIBUSB error : "+ ofToString(result));
					if(result!=-5007) setConnected(false); // time out error
				} else if(result!=HELIOS_SUCCESS) {
					ofLog(OF_LOG_NOTICE, "heliosDac.WriteFrame failed. Error : "+ ofToString(result));
					setConnected(false);
				} else {
					setConnected(true);
				}
			}
		} else  {

            // DO RECONNECT
            //resetFlag = false;

			// TODO : handle reconnection better
			// try to reconnect!

			if(isThreadRunning()) {
				if(lock()) {
					if(connectToDevice(deviceName)) {
						setConnected(true);
					// wait half a second?
						unlock();
					} else {
						unlock();
						for(size_t i = 0; (i<10)&&(isThreadRunning()); i++ ) {
							sleep(50);
						}
					}
				}
				yield();

			}

		}
	}

	//free(samples);
}

void DacHelios :: setConnected(bool state) {
	if(connected!=state) {

		while(!lock()){};
		connected = state;
		if(!connected) {
			//heliosManager.deviceDisconnected(deviceName);
			armed = !newArmed;
			heliosManager.deleteDevice(dacDevice);
			dacDevice = nullptr;
		}
		ofLogNotice("Helios Dac changed connection state : "+ofToString(connected));
		unlock();

	}
}
<commit_msg>HeliosDac refactors<commit_after>//
//  ofxLaserDacBase.cpp
//
//  Created by Seb Lee-Delisle on 07/11/2017.
//
//

#include "ofxLaserDacHelios.h"

using namespace ofxLaser;

DacHelios:: DacHelios() : heliosManager(DacHeliosManager::getInstance()) {
	pps = 30000;
	newPPS = 30000;

	frameMode = true;

	connected = false;
    newArmed = false;  // as in the PPS system, this knows
                            // if armed status has changed and sends
                            // signal to DAC
	deviceId = "";
	dacDevice = nullptr;

}
DacHelios:: ~DacHelios() {
	ofLogNotice("DacHelios destructor");
	//stopThread();
	close();

}

void DacHelios::close() {

	if(isThreadRunning()) {
		waitForThread(true); // also stops the thread
		if(lock()) {
			if(dacDevice!=nullptr) {
				dacDevice->SetClosed();
				dacDevice = nullptr;
			}
			unlock();
		}
		delete dacDevice;
	}
}

void DacHelios::setup(string name) {

	deviceName = name; // the parameter which shows the name

	ofLogNotice("DacHelios::setup "+name);

	connectToDevice(deviceName);

	pointBufferDisplay.set("Point Buffer", 0,0,1799);
	displayData.push_back(&deviceName);
	displayData.push_back(&pointBufferDisplay);

	startThread();

}

const vector<ofAbstractParameter*>& DacHelios :: getDisplayData() {
	if(lock()) {

		//pointBufferDisplay += (response.status.buffer_fullness-pointBufferDisplay)*1;

		//int pointssincelastmessage = (float)((ofGetElapsedTimeMicros()-lastMessageTimeMicros)*response.status.point_rate)/1000000.0f;

		//pointBufferDisplay = bufferedPoints.size();

		//latencyDisplay += (latencyMicros - latencyDisplay)*0.1;
		//reconnectCount = prepareSendCount;

		unlock();
	}

	return displayData;
}

bool DacHelios::connectToDevice(string name) {

	dacDevice = heliosManager.getDacDeviceForName(name);
	if(dacDevice!=nullptr) {
		deviceId = deviceName = dacDevice->nameStr;
		if(dacDevice->isClosed()) { // not sure why it should be but hey
			ofLogError("HeliosDac device is closed before it's used!"+ name);
			heliosManager.deleteDevice(dacDevice);
			connected = false;

			dacDevice = nullptr;
		} else {
			connected = true;
		}
	} else {
		connected = false;
	}

	return connected;

}

bool DacHelios:: sendFrame(const vector<Point>& points){
	if(!connected) return false;
	// get frame object

	DacHeliosFrame* frame = new DacHeliosFrame();

	// add all points into the frame object
	frameMode = true;
	for(ofxLaser::Point p : points) {
		frame->addPoint(p);
	}
	// add the frame object to the frame channel
	framesChannel.send(frame);

	return true;

}

bool DacHelios::sendPoints(const vector<Point>& points) {
	return false;

	//	if(bufferedPoints.size()>pps*0.5) {
//		return false;
//	}
//	frameMode = false;
//	HeliosPoint p1;
//	if(lock()) {
//		frameMode = false;
//
//		for(size_t i= 0; i<points.size(); i++) {
//			const Point& p2 = points[i];
//			p1.x = ofMap(p2.x,0,800, HELIOS_MIN, HELIOS_MAX);
//			p1.y = ofMap(p2.y,800,0, HELIOS_MIN, HELIOS_MAX); // Y is UP
//			p1.r = roundf(p2.r);
//			p1.g = roundf(p2.g);
//			p1.b = roundf(p2.b);
//			p1.i = 255;
//			addPoint(p1);
//		}
//		unlock();
//	}
//	return true;
};

bool DacHelios::setPointsPerSecond(uint32_t newpps) {
	ofLog(OF_LOG_NOTICE, "setPointsPerSecond " + ofToString(newpps));
	while(!lock());
	newPPS = newpps;
	unlock();
	return true;

};

void DacHelios :: setActive(bool active){
    newArmed = active;

}
void DacHelios :: reset() {
    if(lock()) {
        resetFlag = true;
        unlock();
    }
}

void DacHelios :: threadedFunction(){

	//HeliosPoint * samples = (HeliosPoint *)calloc(sizeof(HeliosPoint), samples_per_packet);
	DacHeliosFrame* currentFrame = nullptr;
	DacHeliosFrame* nextFrame = nullptr;
	DacHeliosFrame* newFrame = nullptr;

	while(isThreadRunning()) {

		if(connected && (newPPS!=pps)) {
			pps = newPPS;

		}
        if(connected && (newArmed!=armed)) {
            if((dacDevice!=nullptr) && (dacDevice->SetShutter(newArmed)==HELIOS_SUCCESS)) {
                armed = newArmed;
            }
        }

		if(connected && isThreadRunning()) {

			// is there a new frame?
			// if so, store it
			bool dacReady = false;
			int status = 0;

			while(!dacReady)  {
				if(framesChannel.tryReceive(newFrame)) {
					if(nextFrame!=nullptr) {
						delete nextFrame;
					}
					nextFrame = newFrame;
				}
				//float time = ofGetElapsedTimef();
				if(dacDevice!=nullptr) status = dacDevice->GetStatus();
				//cout << status << " " << ofGetElapsedTimef()-time << endl;
				dacReady = (status == 1);

				if(!dacReady) {
					if(status<0) {
						ofLog(OF_LOG_NOTICE, "heliosDac.getStatus error: "+ ofToString(status));
					sleep(1);
					//cout << ".";
				}

			}
			// if we got to here then the dac is ready but we might not have a
			// currentFrame yet...
			if(nextFrame!=nullptr) {
				if(currentFrame!=nullptr) {
					delete currentFrame;
				}
				currentFrame = nextFrame;
				nextFrame = nullptr;
			}
			if(currentFrame!=nullptr) {
				int result =  0;
				if(dacDevice!=nullptr) result = dacDevice->SendFrame(pps, HELIOS_FLAGS_SINGLE_MODE, currentFrame->samples, currentFrame->numSamples);
				//ofLog(OF_LOG_NOTICE, "heliosDac.WriteFrame : "+ ofToString(result));
				if(result <=-5000){ // then we have a USB connection error
					ofLog(OF_LOG_NOTICE, "heliosDac.WriteFrame failed. LIBUSB error : "+ ofToString(result));
					if(result!=-5007) setConnected(false); // time out error
				} else if(result!=HELIOS_SUCCESS) {
					ofLog(OF_LOG_NOTICE, "heliosDac.WriteFrame failed. Error : "+ ofToString(result));
					setConnected(false);
				} else {
					setConnected(true);
				}
			}
		} else  {

            // DO RECONNECT
            //resetFlag = false;

			// TODO : handle reconnection better
			// try to reconnect!

			if(isThreadRunning()) {
				if(lock()) {
					if(connectToDevice(deviceName)) {
						setConnected(true);
					// wait half a second?
						unlock();
					} else {
						unlock();
						for(size_t i = 0; (i<10)&&(isThreadRunning()); i++ ) {
							sleep(50);
						}
					}
				}
				yield();

			}

		}
	}

	//free(samples);
}

void DacHelios :: setConnected(bool state) {
	if(connected!=state) {

		while(!lock()){};
		connected = state;
		if(!connected) {
			//heliosManager.deviceDisconnected(deviceName);
			armed = !newArmed;
			heliosManager.deleteDevice(dacDevice);
			dacDevice = nullptr;
		}
		ofLogNotice("Helios Dac changed connection state : "+ofToString(connected));
		unlock();

	}
}
<|endoftext|>