<commit_before>/*
* Copyright (C) 2015 German Aerospace Center (DLR/SC)
*
* Created: 2015-10-21 Jonas Jepsen <Jonas.Jepsen@dlr.de>
*
* Licensed 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.
*/

/**
* @file
* @brief  Implementation of CPACS wing handling routines.
*/

#include <iostream>
#include <algorithm>

#include "CCPACSGenericSystem.h"
#include "CCPACSConfiguration.h"
#include "CTiglError.h"
#include "tiglcommonfunctions.h"
#include "CNamedShape.h"

#include "BRepBuilderAPI_GTransform.hxx"
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeCone.hxx>
#include <BRepPrimAPI_MakeBox.hxx>

namespace tigl
{

// Constructor
CCPACSGenericSystem::CCPACSGenericSystem(CCPACSConfiguration* config)
    : CTiglRelativelyPositionedComponent(NULL, &transformation, &symmetryAxis), transformation(config ? &config->GetUIDManager() : NULL), configuration(config)
{
    Cleanup();
}

// Destructor
CCPACSGenericSystem::~CCPACSGenericSystem()
{
    Cleanup();
}

const std::string& CCPACSGenericSystem::GetUID() const {
    return uid;
}

void CCPACSGenericSystem::SetUID(const std::string& uid) {
    if (configuration) {
        configuration->GetUIDManager().TryRemoveGeometricComponent(this->uid);
        configuration->GetUIDManager().AddGeometricComponent(uid, this);
    }
    this->uid = uid;
}

std::string CCPACSGenericSystem::GetDefaultedUID() const {
    return uid;
}

// Invalidates internal state
void CCPACSGenericSystem::Invalidate()
{
    invalidated = true;
}

// Cleanup routine
void CCPACSGenericSystem::Cleanup()
{
    name = "";
    transformation.reset();

    // Calls ITiglGeometricComponent interface Reset to delete e.g. all childs.
    Reset();

    Invalidate();
}

// Update internal generic system data
void CCPACSGenericSystem::Update()
{
    if (!invalidated) {
        return;
    }

    transformation.updateMatrix();
    invalidated = false;
}

// Read CPACS generic system element
void CCPACSGenericSystem::ReadCPACS(TixiDocumentHandle tixiHandle, const std::string& genericSysXPath)
{
    Cleanup();

    char*       elementPath;
    std::string tempString;

    // Get subelement "name"
    char* ptrName = NULL;
    tempString    = genericSysXPath + "/name";
    elementPath   = const_cast<char*>(tempString.c_str());
    if (tixiGetTextElement(tixiHandle, elementPath, &ptrName) == SUCCESS) {
        name          = ptrName;
    }

    // Get subelement "geometricBaseType"
    char* ptrBaseType = NULL;
    tempString    = genericSysXPath + "/geometricBaseType";
    elementPath   = const_cast<char*>(tempString.c_str());
    if (tixiGetTextElement(tixiHandle, elementPath, &ptrBaseType) == SUCCESS) {
        geometricBaseType = ptrBaseType;

        // check validity of type
        if (geometricBaseType != "cylinder" && geometricBaseType != "sphere" && geometricBaseType != "cone" && geometricBaseType != "cube") {
            throw CTiglError("Invalid geometry base type: " + geometricBaseType, TIGL_XML_ERROR);
        }
    }

    // Get attribute "uid"
    char* ptrUID = NULL;
    tempString   = "uID";
    elementPath  = const_cast<char*>(tempString.c_str());
    if (tixiGetTextAttribute(tixiHandle, const_cast<char*>(genericSysXPath.c_str()), const_cast<char*>(tempString.c_str()), &ptrUID) == SUCCESS) {
        SetUID(ptrUID);
    }

    // Get Transformation
    transformation.ReadCPACS(tixiHandle, genericSysXPath);

    // Register ourself at the unique id manager
    if (configuration) {
        configuration->GetUIDManager().AddGeometricComponent(ptrUID, this);
    }

    // Get symmetry axis attribute
    char* ptrSym = NULL;
    tempString   = "symmetry";
    if (tixiGetTextAttribute(tixiHandle, const_cast<char*>(genericSysXPath.c_str()), const_cast<char*>(tempString.c_str()), &ptrSym) == SUCCESS) {
        SetSymmetryAxis(stringToTiglSymmetryAxis(ptrSym));
    }

    Update();
}

// Returns the name of the generic system
const std::string& CCPACSGenericSystem::GetName() const
{
    return name;
}

// Returns the parent configuration
CCPACSConfiguration& CCPACSGenericSystem::GetConfiguration() const
{
    return *configuration;
}

// build loft
PNamedShape CCPACSGenericSystem::BuildLoft()
{
    TopoDS_Shape sysShape;
    if (geometricBaseType == "cylinder") {
        BRepPrimAPI_MakeCylinder cyl(0.5, 1);
        gp_Vec vec(0, 0, -0.5);
        gp_Trsf trsf = gp_Trsf();
        trsf.SetTranslation(vec);
        TopLoc_Location loc(trsf);
        sysShape = cyl.Shape();
        sysShape.Location(loc);
    }
    else if (geometricBaseType == "sphere") {
        BRepPrimAPI_MakeSphere sph(0.5);
        sysShape = sph.Shape();
    }
    else if (geometricBaseType == "cone") {
        BRepPrimAPI_MakeCone cone(0.5, 0, 1);
        gp_Vec vec(0, 0, -0.5);
        gp_Trsf trsf = gp_Trsf();
        trsf.SetTranslation(vec);
        TopLoc_Location loc(trsf);
        sysShape = cone.Shape();
        sysShape.Location(loc);
    }
    else if (geometricBaseType == "cube") {
        gp_Pnt p1(-0.5, -0.5, -0.5);
        gp_Pnt p2(0.5, 0.5, 0.5);
        BRepPrimAPI_MakeBox cube(p1, p2);
        sysShape = cube.Shape();
    }

    sysShape = GetTransformationMatrix().Transform(sysShape);
    std::string loftName = GetUID();
    std::string loftShortName = GetShortShapeName();
    PNamedShape loft(new CNamedShape(sysShape, loftName.c_str(), loftShortName.c_str()));

    return loft;
}

// get short name for loft
std::string CCPACSGenericSystem::GetShortShapeName()
{
    unsigned int gsindex = 0;
    for (int i = 1; i <= GetConfiguration().GetGenericSystemCount(); ++i) {
        tigl::CCPACSGenericSystem& gs = GetConfiguration().GetGenericSystem(i);
        if (GetUID() == gs.GetUID()) {
            gsindex = i;
            std::stringstream shortName;
            shortName << "GS" << gsindex;
            return shortName.str();
        }
    }
    return "UNKNOWN";
}

// Sets the Transformation object
void CCPACSGenericSystem::Translate(CTiglPoint trans)
{
    CTiglRelativelyPositionedComponent::Translate(trans);
    invalidated = true;
    Update();
}

} // end namespace tigl
<commit_msg>Fixed opening of files with generic systems<commit_after>/*
* Copyright (C) 2015 German Aerospace Center (DLR/SC)
*
* Created: 2015-10-21 Jonas Jepsen <Jonas.Jepsen@dlr.de>
*
* Licensed 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.
*/

/**
* @file
* @brief  Implementation of CPACS wing handling routines.
*/

#include <iostream>
#include <algorithm>

#include "CCPACSGenericSystem.h"
#include "CCPACSConfiguration.h"
#include "CTiglError.h"
#include "tiglcommonfunctions.h"
#include "CNamedShape.h"

#include "BRepBuilderAPI_GTransform.hxx"
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeCone.hxx>
#include <BRepPrimAPI_MakeBox.hxx>

namespace tigl
{

// Constructor
CCPACSGenericSystem::CCPACSGenericSystem(CCPACSConfiguration* config)
    : CTiglRelativelyPositionedComponent(NULL, &transformation, &symmetryAxis), transformation(config ? &config->GetUIDManager() : NULL), configuration(config)
{
    Cleanup();
}

// Destructor
CCPACSGenericSystem::~CCPACSGenericSystem()
{
    Cleanup();
}

const std::string& CCPACSGenericSystem::GetUID() const {
    return uid;
}

void CCPACSGenericSystem::SetUID(const std::string& uid) {
    if (configuration) {
        configuration->GetUIDManager().TryRemoveGeometricComponent(this->uid);
        configuration->GetUIDManager().AddGeometricComponent(uid, this);
    }
    this->uid = uid;
}

std::string CCPACSGenericSystem::GetDefaultedUID() const {
    return uid;
}

// Invalidates internal state
void CCPACSGenericSystem::Invalidate()
{
    invalidated = true;
}

// Cleanup routine
void CCPACSGenericSystem::Cleanup()
{
    name = "";
    transformation.reset();

    // Calls ITiglGeometricComponent interface Reset to delete e.g. all childs.
    Reset();

    Invalidate();
}

// Update internal generic system data
void CCPACSGenericSystem::Update()
{
    if (!invalidated) {
        return;
    }

    transformation.updateMatrix();
    invalidated = false;
}

// Read CPACS generic system element
void CCPACSGenericSystem::ReadCPACS(TixiDocumentHandle tixiHandle, const std::string& genericSysXPath)
{
    Cleanup();

    char*       elementPath;
    std::string tempString;

    // Get subelement "name"
    char* ptrName = NULL;
    tempString    = genericSysXPath + "/name";
    elementPath   = const_cast<char*>(tempString.c_str());
    if (tixiGetTextElement(tixiHandle, elementPath, &ptrName) == SUCCESS) {
        name          = ptrName;
    }

    // Get subelement "geometricBaseType"
    char* ptrBaseType = NULL;
    tempString    = genericSysXPath + "/geometricBaseType";
    elementPath   = const_cast<char*>(tempString.c_str());
    if (tixiGetTextElement(tixiHandle, elementPath, &ptrBaseType) == SUCCESS) {
        geometricBaseType = ptrBaseType;

        // check validity of type
        if (geometricBaseType != "cylinder" && geometricBaseType != "sphere" && geometricBaseType != "cone" && geometricBaseType != "cube") {
            throw CTiglError("Invalid geometry base type: " + geometricBaseType, TIGL_XML_ERROR);
        }
    }

    // Get attribute "uid"
    char* ptrUID = NULL;
    tempString   = "uID";
    elementPath  = const_cast<char*>(tempString.c_str());
    if (tixiGetTextAttribute(tixiHandle, const_cast<char*>(genericSysXPath.c_str()), const_cast<char*>(tempString.c_str()), &ptrUID) == SUCCESS) {
        SetUID(ptrUID);
    }

    // Get Transformation
    transformation.ReadCPACS(tixiHandle, genericSysXPath);

    // Get symmetry axis attribute
    char* ptrSym = NULL;
    tempString   = "symmetry";
    if (tixiGetTextAttribute(tixiHandle, const_cast<char*>(genericSysXPath.c_str()), const_cast<char*>(tempString.c_str()), &ptrSym) == SUCCESS) {
        SetSymmetryAxis(stringToTiglSymmetryAxis(ptrSym));
    }

    Update();
}

// Returns the name of the generic system
const std::string& CCPACSGenericSystem::GetName() const
{
    return name;
}

// Returns the parent configuration
CCPACSConfiguration& CCPACSGenericSystem::GetConfiguration() const
{
    return *configuration;
}

// build loft
PNamedShape CCPACSGenericSystem::BuildLoft()
{
    TopoDS_Shape sysShape;
    if (geometricBaseType == "cylinder") {
        BRepPrimAPI_MakeCylinder cyl(0.5, 1);
        gp_Vec vec(0, 0, -0.5);
        gp_Trsf trsf = gp_Trsf();
        trsf.SetTranslation(vec);
        TopLoc_Location loc(trsf);
        sysShape = cyl.Shape();
        sysShape.Location(loc);
    }
    else if (geometricBaseType == "sphere") {
        BRepPrimAPI_MakeSphere sph(0.5);
        sysShape = sph.Shape();
    }
    else if (geometricBaseType == "cone") {
        BRepPrimAPI_MakeCone cone(0.5, 0, 1);
        gp_Vec vec(0, 0, -0.5);
        gp_Trsf trsf = gp_Trsf();
        trsf.SetTranslation(vec);
        TopLoc_Location loc(trsf);
        sysShape = cone.Shape();
        sysShape.Location(loc);
    }
    else if (geometricBaseType == "cube") {
        gp_Pnt p1(-0.5, -0.5, -0.5);
        gp_Pnt p2(0.5, 0.5, 0.5);
        BRepPrimAPI_MakeBox cube(p1, p2);
        sysShape = cube.Shape();
    }

    sysShape = GetTransformationMatrix().Transform(sysShape);
    std::string loftName = GetUID();
    std::string loftShortName = GetShortShapeName();
    PNamedShape loft(new CNamedShape(sysShape, loftName.c_str(), loftShortName.c_str()));

    return loft;
}

// get short name for loft
std::string CCPACSGenericSystem::GetShortShapeName()
{
    unsigned int gsindex = 0;
    for (int i = 1; i <= GetConfiguration().GetGenericSystemCount(); ++i) {
        tigl::CCPACSGenericSystem& gs = GetConfiguration().GetGenericSystem(i);
        if (GetUID() == gs.GetUID()) {
            gsindex = i;
            std::stringstream shortName;
            shortName << "GS" << gsindex;
            return shortName.str();
        }
    }
    return "UNKNOWN";
}

// Sets the Transformation object
void CCPACSGenericSystem::Translate(CTiglPoint trans)
{
    CTiglRelativelyPositionedComponent::Translate(trans);
    invalidated = true;
    Update();
}

} // end namespace tigl
<|endoftext|>


<commit_before>#include "tlb.h"
#include "stats.h"

namespace ParametricDramDirectoryMSI
{

TLB::TLB(String name, String cfgname, core_id_t core_id, UInt32 size, UInt32 associativity)
   : m_size(size)
   , m_associativity(associativity)
   , m_cache(name + "_cache", cfgname, core_id, size, associativity, SIM_PAGE_SIZE, "lru", CacheBase::PR_L1_CACHE)
   , m_access(0)
   , m_miss(0)
{
   registerStatsMetric(name, core_id, "access", &m_access);
   registerStatsMetric(name, core_id, "miss", &m_miss);
}

bool
TLB::lookup(IntPtr address, SubsecondTime now)
{
   m_access++;

   if (m_cache.peekSingleLine(address))
      return true;

   m_miss++;

   bool eviction;
   IntPtr evict_addr;
   CacheBlockInfo evict_block_info;
   m_cache.insertSingleLine(address, NULL, &eviction, &evict_addr, &evict_block_info, NULL, now);

   return false;
}

}
<commit_msg>[tlb] Fix TLB accesses to perform a real cache access which is necessary to update the LRU state<commit_after>#include "tlb.h"
#include "stats.h"

namespace ParametricDramDirectoryMSI
{

TLB::TLB(String name, String cfgname, core_id_t core_id, UInt32 size, UInt32 associativity)
   : m_size(size)
   , m_associativity(associativity)
   , m_cache(name + "_cache", cfgname, core_id, size, associativity, SIM_PAGE_SIZE, "lru", CacheBase::PR_L1_CACHE)
   , m_access(0)
   , m_miss(0)
{
   registerStatsMetric(name, core_id, "access", &m_access);
   registerStatsMetric(name, core_id, "miss", &m_miss);
}

bool
TLB::lookup(IntPtr address, SubsecondTime now)
{
   m_access++;

   if (m_cache.accessSingleLine(address, Cache::LOAD, NULL, 0, now))
      return true;

   m_miss++;

   bool eviction;
   IntPtr evict_addr;
   CacheBlockInfo evict_block_info;
   m_cache.insertSingleLine(address, NULL, &eviction, &evict_addr, &evict_block_info, NULL, now);

   return false;
}

}
<|endoftext|>


<commit_before>/*
 * Executor.cpp
 *
 *  Created on: Oct 20, 2015
 *      Author: Péter Fankhauser
 *   Institute: ETH Zurich, Autonomous Systems Lab
 */

#include "free_gait_core/executor/Executor.hpp"

#include <robotUtils/timers/ChronoTimer.hpp>

#include <free_gait_core/leg_motion/JointTrajectory.hpp>

namespace free_gait {

Executor::Executor(std::shared_ptr<StepCompleter> completer,
                   std::shared_ptr<AdapterBase> adapter,
                   std::shared_ptr<State> state)
    : completer_(completer),
      adapter_(adapter),
      state_(state),
      isInitialized_(false),
      executionStatus_(true)
{
}

Executor::~Executor()
{
}

bool Executor::initialize()
{
  Lock lock(mutex_);
  state_->initialize(adapter_->getLimbs(), adapter_->getBranches());
  reset();
  return isInitialized_ = true;
}

bool Executor::isInitialized() const
{
  return isInitialized_;
}

Executor::Mutex& Executor::getMutex()
{
  return mutex_;
}

bool Executor::advance(double dt)
{
  timer_ = robotUtils::HighResolutionClockTimer("FreeGait::Executor");
  timer_.setAlpha(1.0);

  timer_.pinTime("Total");
  timer_.pinTime("Mutex");
  Lock lock(mutex_);
  timer_.splitTime("Mutex");

  timer_.pinTime("First part");
  if (!isInitialized_) return false;
  updateStateWithMeasurements();
  updateExecutionStatus();

  if (executionStatus_) {
    if (!state_->getRobotExecutionStatus()) std::cout << "Continuing with free gait execution." << std::endl;
    state_->setRobotExecutionStatus(true);
  } else {
    if (state_->getRobotExecutionStatus()) std::cout << "Robot status is not OK, not continuing with free gait execution." << std::endl;
    state_->setRobotExecutionStatus(false);
    return true;
  }

  bool hasSwitchedStep;
  if (!queue_.advance(dt, hasSwitchedStep)) return false;
  timer_.splitTime("First part");

  timer_.pinTime("Second part");
  while (hasSwitchedStep) {

    if (!queue_.getCurrentStep().requiresMultiThreading()) {
      if (!completeCurrentStep()) return false;
      if (!queue_.advance(dt, hasSwitchedStep)) return false; // Advance again after completion.
    } else {
      timer_.pinTime("Creating thread");
      std::thread thread(&Executor::completeCurrentStep, this, true);
      thread.detach();
      timer_.splitTime("Creating thread");
      hasSwitchedStep = false;
    }
  }

  timer_.pinTime("writeIgnoreContact");
  if (!writeIgnoreContact()) return false;
  timer_.splitTime("writeIgnoreContact");
  timer_.pinTime("writeIgnoreForPoseAdaptation");
  if (!writeIgnoreForPoseAdaptation()) return false;
  timer_.splitTime("writeIgnoreForPoseAdaptation");
    timer_.pinTime("writeSupportLegs");
  if (!writeSupportLegs()) return false;
  timer_.splitTime("writeSupportLegs");
    timer_.pinTime("writeSurfaceNormals");
  if (!writeSurfaceNormals()) return false;
  timer_.splitTime("writeSurfaceNormals");
    timer_.pinTime("writeLegMotion");
  if (!writeLegMotion()) return false;
  timer_.splitTime("writeLegMotion");
    timer_.pinTime("writeTorsoMotion");
  if (!writeTorsoMotion()) return false;
  timer_.splitTime("writeTorsoMotion");
    timer_.pinTime("updateExtras");
  if (!adapter_->updateExtras(queue_, *state_)) return false;
  timer_.pinTime("updateExtras");
//  std::cout << *state_ << std::endl;
  timer_.splitTime("Second part");
  timer_.splitTime("Total");

  return true;
}

bool Executor::getExecutionStatus()
{
  return executionStatus_;
}

bool Executor::completeCurrentStep(bool multiThreaded)
{
  robotUtils::HighResolutionClockTimer timer("Executor::completeCurrentStep");
  timer.pinTime();

  // TODO: Add mutexes on state and queue?
  bool completionSuccessful;
  if (multiThreaded) {
    const State state(*state_);
    completionSuccessful = completer_->complete(state, queue_, queue_.getCurrentStep());
  } else {
    completionSuccessful = completer_->complete(*state_, queue_, queue_.getCurrentStep());
  }

  if (!completionSuccessful) {
    std::cerr << "Executor::advance: Could not complete step." << std::endl;
    return false;
  }

  timer.splitTime();
  std::cout << timer << std::endl;
  std::cout << "Switched step to:" << std::endl;
  std::cout << queue_.getCurrentStep() << std::endl;
  return true;
}

void Executor::reset()
{
  Lock lock(mutex_);
  queue_.clear();
  initializeStateWithRobot();
}

const StepQueue& Executor::getQueue() const
{
  return queue_;
}

StepQueue& Executor::getQueue()
{
  return queue_;
}

const State& Executor::getState() const
{
  return *state_;
}

const AdapterBase& Executor::getAdapter() const
{
  return *adapter_;
}

const robotUtils::HighResolutionClockTimer& Executor::getTimer()
{
  return timer_;
}

bool Executor::initializeStateWithRobot()
{
  for (const auto& limb : adapter_->getLimbs()) {
    state_->setSupportLeg(limb, adapter_->isLegGrounded(limb));
    state_->setIgnoreContact(limb, !adapter_->isLegGrounded(limb));
    state_->setIgnoreForPoseAdaptation(limb, !adapter_->isLegGrounded(limb));
    state_->removeSurfaceNormal(limb);
  }

  if (state_->getNumberOfSupportLegs() > 0) {
    state_->setControlSetup(BranchEnum::BASE, adapter_->getControlSetup(BranchEnum::BASE));
  } else {
    state_->setEmptyControlSetup(BranchEnum::BASE);
  }

  for (const auto& limb : adapter_->getLimbs()) {
    if (state_->isSupportLeg(limb)) {
      state_->setEmptyControlSetup(limb);
    } else {
      state_->setControlSetup(limb, adapter_->getControlSetup(limb));
    }
  }

  state_->setAllJointPositions(adapter_->getAllJointPositions());
  state_->setAllJointVelocities(adapter_->getAllJointVelocities());
//  state_->setAllJointAccelerations(adapter_->getAllJointAccelerations()); // TODO
  state_->setAllJointEfforts(adapter_->getAllJointEfforts());
  state_->setPositionWorldToBaseInWorldFrame(adapter_->getPositionWorldToBaseInWorldFrame());
  state_->setOrientationWorldToBase(adapter_->getOrientationWorldToBase());

  for (const auto& limb : adapter_->getLimbs()) {
    state_->setSupportLeg(limb, adapter_->isLegGrounded(limb));
    state_->setIgnoreContact(limb, !adapter_->isLegGrounded(limb));
  }

  state_->setRobotExecutionStatus(true);

  return true;
}

bool Executor::updateStateWithMeasurements()
{
  for (const auto& limb : adapter_->getLimbs()) {
    const auto& controlSetup = state_->getControlSetup(limb);
    if (!controlSetup.at(ControlLevel::Position)) {
      state_->setJointPositions(limb, adapter_->getJointPositions(limb));
    }
    if (!controlSetup.at(ControlLevel::Velocity)) {
      state_->setJointVelocities(limb, adapter_->getJointVelocities(limb));
    }
    if (!controlSetup.at(ControlLevel::Acceleration)) {
//      state_->setJointAccelerations(limb, adapter_->getJointAccelerations(limb));
    }
    if (!controlSetup.at(ControlLevel::Effort)) {
      state_->setJointEfforts(limb, adapter_->getJointEfforts(limb));
    }
  }

  const auto& controlSetup = state_->getControlSetup(BranchEnum::BASE);
  if (!controlSetup.at(ControlLevel::Position)) {
    state_->setPositionWorldToBaseInWorldFrame(adapter_->getPositionWorldToBaseInWorldFrame());
    state_->setOrientationWorldToBase(adapter_->getOrientationWorldToBase());
  }

  state_->setAllJointVelocities(adapter_->getAllJointVelocities());
  // TODO Copy also acceleraitons and torques.
//    state.setLinearVelocityBaseInWorldFrame(torso_->getMeasuredState().getLinearVelocityBaseInBaseFrame());
//    state.setAngularVelocityBaseInBaseFrame(torso_->getMeasuredState().getAngularVelocityBaseInBaseFrame());
  return true;
}

void Executor::updateExecutionStatus()
{
  executionStatus_ = true;
  for (const auto& limb : adapter_->getLimbs()) {
    if (state_->isSupportLeg(limb) && !adapter_->isLegGrounded(limb)) {
      executionStatus_ = false;
      return;
    }
  }
}

bool Executor::writeIgnoreContact()
{
  if (!queue_.active()) return true;
  const Step& step = queue_.getCurrentStep();
  for (const auto& limb : adapter_->getLimbs()) {
    if (step.hasLegMotion(limb)) {
      bool ignoreContact = step.getLegMotion(limb).isIgnoreContact();
      state_->setIgnoreContact(limb, ignoreContact);
    }
  }
  return true;
}

bool Executor::writeIgnoreForPoseAdaptation()
{
  if (!queue_.active()) return true;
  const Step& step = queue_.getCurrentStep();
  for (const auto& limb : adapter_->getLimbs()) {
    if (step.hasLegMotion(limb)) {
      bool ignoreForPoseAdaptation = step.getLegMotion(limb).isIgnoreForPoseAdaptation();
      state_->setIgnoreForPoseAdaptation(limb, ignoreForPoseAdaptation);
    }
  }
  return true;
}

bool Executor::writeSupportLegs()
{
  if (!queue_.active()) {
    for (const auto& limb : adapter_->getLimbs()) {
      state_->setSupportLeg(limb, !state_->isIgnoreContact(limb));
    }
    return true;
  }

  const Step& step = queue_.getCurrentStep();
  for (const auto& limb : adapter_->getLimbs()) {
    if (step.hasLegMotion(limb) || state_->isIgnoreContact(limb)) {
      state_->setSupportLeg(limb, false);
    } else {
      state_->setSupportLeg(limb, true);
    }
  }
  return true;
}

bool Executor::writeSurfaceNormals()
{
  if (!queue_.active()) return true;
  const Step& step = queue_.getCurrentStep();
  for (const auto& limb : adapter_->getLimbs()) {
    if (step.hasLegMotion(limb)) {
      if (step.getLegMotion(limb).hasSurfaceNormal()) {
        state_->setSurfaceNormal(limb, step.getLegMotion(limb).getSurfaceNormal());
      } else {
        state_->removeSurfaceNormal(limb);
      }
    }
  }
  return true;
}

bool Executor::writeLegMotion()
{
  timer_.pinTime("1");
  for (const auto& limb : adapter_->getLimbs()) {
    if (state_->isSupportLeg(limb)) state_->setEmptyControlSetup(limb);
  }
  if (!queue_.active()) return true;

  const auto& step = queue_.getCurrentStep();
  if (!step.hasLegMotion()) return true;
  timer_.splitTime("1");

  timer_.pinTime("2");
  double time = queue_.getCurrentStep().getTime();
  for (const auto& limb : adapter_->getLimbs()) {
    timer_.pinTime("writeLegmotion for loop");
    if (!step.hasLegMotion(limb)) continue;
    auto const& legMotion = step.getLegMotion(limb);
    ControlSetup controlSetup = legMotion.getControlSetup();
    state_->setControlSetup(limb, controlSetup);

    switch (legMotion.getTrajectoryType()) {

      case LegMotionBase::TrajectoryType::EndEffector:
      {
        const auto& endEffectorMotion = dynamic_cast<const EndEffectorMotionBase&>(legMotion);
        if (controlSetup[ControlLevel::Position]) {
          // TODO Add frame handling.
          Position positionInWorldFrame(endEffectorMotion.evaluatePosition(time));
          // TODO adapter_->getOrientationWorldToBase() is nicer when the robot slips, but leads to problems at lift-off.
          Position positionInBaseFrame(adapter_->getOrientationWorldToBase().rotate(positionInWorldFrame - adapter_->getPositionWorldToBaseInWorldFrame()));
//          Position positionInBaseFrame(state_->getOrientationWorldToBase().rotate(positionInWorldFrame - adapter_->getPositionWorldToBaseInWorldFrame()));
          JointPositions jointPositions;
          adapter_->getLimbJointPositionsFromPositionBaseToFootInBaseFrame(positionInBaseFrame, limb, jointPositions);
          state_->setJointPositions(limb, jointPositions);
        }
        break;
      }

      case LegMotionBase::TrajectoryType::Joints:
      {
        const auto& jointMotion = dynamic_cast<const JointTrajectory&>(legMotion);
        timer_.pinTime("writeLegMotion evalute spline");
        if (controlSetup[ControlLevel::Position]) state_->setJointPositions(limb, jointMotion.evaluatePosition(time, timer_));
//        if (controlSetup[ControlLevel::Velocity]) state_->setJointVelocities(limb, jointMotion.evaluateVelocity(time));
//        if (controlSetup[ControlLevel::Acceleration]) state_->setJointAcceleration(limb, jointMotion.evaluateAcceleration(time));
        if (controlSetup[ControlLevel::Effort]) state_->setJointEfforts(limb, jointMotion.evaluateEffort(time));
        timer_.splitTime("writeLegMotion evalute spline");
        break;
      }

      default:
        throw std::runtime_error("Executor::writeLegMotion() could not write leg motion of this type.");
        break;
    }
    timer_.splitTime("writeLegmotion for loop");
  }
  timer_.splitTime("2");

  return true;
}

bool Executor::writeTorsoMotion()
{
  if (state_->getNumberOfSupportLegs() == 0) state_->setEmptyControlSetup(BranchEnum::BASE);
  if (!queue_.active()) return true;

  if (!queue_.getCurrentStep().hasBaseMotion()) return true;
  double time = queue_.getCurrentStep().getTime();
  // TODO Add frame handling.
  const auto& baseMotion = queue_.getCurrentStep().getBaseMotion();
  ControlSetup controlSetup = baseMotion.getControlSetup();
  state_->setControlSetup(BranchEnum::BASE, controlSetup);
  if (controlSetup[ControlLevel::Position]) {
    Pose pose = baseMotion.evaluatePose(time);
    state_->setPositionWorldToBaseInWorldFrame(pose.getPosition());
    state_->setOrientationWorldToBase(pose.getRotation());
  }
  if (controlSetup[ControlLevel::Velocity]) {
    Twist twist = baseMotion.evaluateTwist(time);
    state_->setLinearVelocityBaseInWorldFrame(twist.getTranslationalVelocity());
    state_->setAngularVelocityBaseInBaseFrame(twist.getRotationalVelocity());
  }
  // TODO Set more states.
  return true;
}

} /* namespace free_gait */
<commit_msg>Compilation errors.<commit_after>/*
 * Executor.cpp
 *
 *  Created on: Oct 20, 2015
 *      Author: Péter Fankhauser
 *   Institute: ETH Zurich, Autonomous Systems Lab
 */

#include "free_gait_core/executor/Executor.hpp"

#include <robotUtils/timers/ChronoTimer.hpp>

#include <free_gait_core/leg_motion/JointTrajectory.hpp>

namespace free_gait {

Executor::Executor(std::shared_ptr<StepCompleter> completer,
                   std::shared_ptr<AdapterBase> adapter,
                   std::shared_ptr<State> state)
    : completer_(completer),
      adapter_(adapter),
      state_(state),
      isInitialized_(false),
      executionStatus_(true)
{
}

Executor::~Executor()
{
}

bool Executor::initialize()
{
  Lock lock(mutex_);
  state_->initialize(adapter_->getLimbs(), adapter_->getBranches());
  reset();
  return isInitialized_ = true;
}

bool Executor::isInitialized() const
{
  return isInitialized_;
}

Executor::Mutex& Executor::getMutex()
{
  return mutex_;
}

bool Executor::advance(double dt)
{
  timer_ = robotUtils::HighResolutionClockTimer("FreeGait::Executor");
  timer_.setAlpha(1.0);

  timer_.pinTime("Total");
  timer_.pinTime("Mutex");
  Lock lock(mutex_);
  timer_.splitTime("Mutex");

  timer_.pinTime("First part");
  if (!isInitialized_) return false;
  updateStateWithMeasurements();
  updateExecutionStatus();

  if (executionStatus_) {
    if (!state_->getRobotExecutionStatus()) std::cout << "Continuing with free gait execution." << std::endl;
    state_->setRobotExecutionStatus(true);
  } else {
    if (state_->getRobotExecutionStatus()) std::cout << "Robot status is not OK, not continuing with free gait execution." << std::endl;
    state_->setRobotExecutionStatus(false);
    return true;
  }

  bool hasSwitchedStep;
  if (!queue_.advance(dt, hasSwitchedStep)) return false;
  timer_.splitTime("First part");

  timer_.pinTime("Second part");
  while (hasSwitchedStep) {

    if (!queue_.getCurrentStep().requiresMultiThreading()) {
      if (!completeCurrentStep()) return false;
      if (!queue_.advance(dt, hasSwitchedStep)) return false; // Advance again after completion.
    } else {
      timer_.pinTime("Creating thread");
      std::thread thread(&Executor::completeCurrentStep, this, true);
      thread.detach();
      timer_.splitTime("Creating thread");
      hasSwitchedStep = false;
    }
  }

  timer_.pinTime("writeIgnoreContact");
  if (!writeIgnoreContact()) return false;
  timer_.splitTime("writeIgnoreContact");
  timer_.pinTime("writeIgnoreForPoseAdaptation");
  if (!writeIgnoreForPoseAdaptation()) return false;
  timer_.splitTime("writeIgnoreForPoseAdaptation");
    timer_.pinTime("writeSupportLegs");
  if (!writeSupportLegs()) return false;
  timer_.splitTime("writeSupportLegs");
    timer_.pinTime("writeSurfaceNormals");
  if (!writeSurfaceNormals()) return false;
  timer_.splitTime("writeSurfaceNormals");
    timer_.pinTime("writeLegMotion");
  if (!writeLegMotion()) return false;
  timer_.splitTime("writeLegMotion");
    timer_.pinTime("writeTorsoMotion");
  if (!writeTorsoMotion()) return false;
  timer_.splitTime("writeTorsoMotion");
    timer_.pinTime("updateExtras");
  if (!adapter_->updateExtras(queue_, *state_)) return false;
  timer_.pinTime("updateExtras");
//  std::cout << *state_ << std::endl;
  timer_.splitTime("Second part");
  timer_.splitTime("Total");

  return true;
}

bool Executor::getExecutionStatus()
{
  return executionStatus_;
}

bool Executor::completeCurrentStep(bool multiThreaded)
{
  robotUtils::HighResolutionClockTimer timer("Executor::completeCurrentStep");
  timer.pinTime();

  // TODO: Add mutexes on state and queue?
  bool completionSuccessful;
  if (multiThreaded) {
    const State state(*state_);
    completionSuccessful = completer_->complete(state, queue_, queue_.getCurrentStep());
  } else {
    completionSuccessful = completer_->complete(*state_, queue_, queue_.getCurrentStep());
  }

  if (!completionSuccessful) {
    std::cerr << "Executor::advance: Could not complete step." << std::endl;
    return false;
  }

  timer.splitTime();
  std::cout << timer << std::endl;
  std::cout << "Switched step to:" << std::endl;
  std::cout << queue_.getCurrentStep() << std::endl;
  return true;
}

void Executor::reset()
{
  Lock lock(mutex_);
  queue_.clear();
  initializeStateWithRobot();
}

const StepQueue& Executor::getQueue() const
{
  return queue_;
}

StepQueue& Executor::getQueue()
{
  return queue_;
}

const State& Executor::getState() const
{
  return *state_;
}

const AdapterBase& Executor::getAdapter() const
{
  return *adapter_;
}

const robotUtils::HighResolutionClockTimer& Executor::getTimer()
{
  return timer_;
}

bool Executor::initializeStateWithRobot()
{
  for (const auto& limb : adapter_->getLimbs()) {
    state_->setSupportLeg(limb, adapter_->isLegGrounded(limb));
    state_->setIgnoreContact(limb, !adapter_->isLegGrounded(limb));
    state_->setIgnoreForPoseAdaptation(limb, !adapter_->isLegGrounded(limb));
    state_->removeSurfaceNormal(limb);
  }

  if (state_->getNumberOfSupportLegs() > 0) {
    state_->setControlSetup(BranchEnum::BASE, adapter_->getControlSetup(BranchEnum::BASE));
  } else {
    state_->setEmptyControlSetup(BranchEnum::BASE);
  }

  for (const auto& limb : adapter_->getLimbs()) {
    if (state_->isSupportLeg(limb)) {
      state_->setEmptyControlSetup(limb);
    } else {
      state_->setControlSetup(limb, adapter_->getControlSetup(limb));
    }
  }

  state_->setAllJointPositions(adapter_->getAllJointPositions());
  state_->setAllJointVelocities(adapter_->getAllJointVelocities());
//  state_->setAllJointAccelerations(adapter_->getAllJointAccelerations()); // TODO
  state_->setAllJointEfforts(adapter_->getAllJointEfforts());
  state_->setPositionWorldToBaseInWorldFrame(adapter_->getPositionWorldToBaseInWorldFrame());
  state_->setOrientationWorldToBase(adapter_->getOrientationWorldToBase());

  for (const auto& limb : adapter_->getLimbs()) {
    state_->setSupportLeg(limb, adapter_->isLegGrounded(limb));
    state_->setIgnoreContact(limb, !adapter_->isLegGrounded(limb));
  }

  state_->setRobotExecutionStatus(true);

  return true;
}

bool Executor::updateStateWithMeasurements()
{
  for (const auto& limb : adapter_->getLimbs()) {
    const auto& controlSetup = state_->getControlSetup(limb);
    if (!controlSetup.at(ControlLevel::Position)) {
      state_->setJointPositions(limb, adapter_->getJointPositions(limb));
    }
    if (!controlSetup.at(ControlLevel::Velocity)) {
      state_->setJointVelocities(limb, adapter_->getJointVelocities(limb));
    }
    if (!controlSetup.at(ControlLevel::Acceleration)) {
//      state_->setJointAccelerations(limb, adapter_->getJointAccelerations(limb));
    }
    if (!controlSetup.at(ControlLevel::Effort)) {
      state_->setJointEfforts(limb, adapter_->getJointEfforts(limb));
    }
  }

  const auto& controlSetup = state_->getControlSetup(BranchEnum::BASE);
  if (!controlSetup.at(ControlLevel::Position)) {
    state_->setPositionWorldToBaseInWorldFrame(adapter_->getPositionWorldToBaseInWorldFrame());
    state_->setOrientationWorldToBase(adapter_->getOrientationWorldToBase());
  }

  state_->setAllJointVelocities(adapter_->getAllJointVelocities());
  // TODO Copy also acceleraitons and torques.
//    state.setLinearVelocityBaseInWorldFrame(torso_->getMeasuredState().getLinearVelocityBaseInBaseFrame());
//    state.setAngularVelocityBaseInBaseFrame(torso_->getMeasuredState().getAngularVelocityBaseInBaseFrame());
  return true;
}

void Executor::updateExecutionStatus()
{
  executionStatus_ = true;
  for (const auto& limb : adapter_->getLimbs()) {
    if (state_->isSupportLeg(limb) && !adapter_->isLegGrounded(limb)) {
      executionStatus_ = false;
      return;
    }
  }
}

bool Executor::writeIgnoreContact()
{
  if (!queue_.active()) return true;
  const Step& step = queue_.getCurrentStep();
  for (const auto& limb : adapter_->getLimbs()) {
    if (step.hasLegMotion(limb)) {
      bool ignoreContact = step.getLegMotion(limb).isIgnoreContact();
      state_->setIgnoreContact(limb, ignoreContact);
    }
  }
  return true;
}

bool Executor::writeIgnoreForPoseAdaptation()
{
  if (!queue_.active()) return true;
  const Step& step = queue_.getCurrentStep();
  for (const auto& limb : adapter_->getLimbs()) {
    if (step.hasLegMotion(limb)) {
      bool ignoreForPoseAdaptation = step.getLegMotion(limb).isIgnoreForPoseAdaptation();
      state_->setIgnoreForPoseAdaptation(limb, ignoreForPoseAdaptation);
    }
  }
  return true;
}

bool Executor::writeSupportLegs()
{
  if (!queue_.active()) {
    for (const auto& limb : adapter_->getLimbs()) {
      state_->setSupportLeg(limb, !state_->isIgnoreContact(limb));
    }
    return true;
  }

  const Step& step = queue_.getCurrentStep();
  for (const auto& limb : adapter_->getLimbs()) {
    if (step.hasLegMotion(limb) || state_->isIgnoreContact(limb)) {
      state_->setSupportLeg(limb, false);
    } else {
      state_->setSupportLeg(limb, true);
    }
  }
  return true;
}

bool Executor::writeSurfaceNormals()
{
  if (!queue_.active()) return true;
  const Step& step = queue_.getCurrentStep();
  for (const auto& limb : adapter_->getLimbs()) {
    if (step.hasLegMotion(limb)) {
      if (step.getLegMotion(limb).hasSurfaceNormal()) {
        state_->setSurfaceNormal(limb, step.getLegMotion(limb).getSurfaceNormal());
      } else {
        state_->removeSurfaceNormal(limb);
      }
    }
  }
  return true;
}

bool Executor::writeLegMotion()
{
  timer_.pinTime("1");
  for (const auto& limb : adapter_->getLimbs()) {
    if (state_->isSupportLeg(limb)) state_->setEmptyControlSetup(limb);
  }
  if (!queue_.active()) return true;

  const auto& step = queue_.getCurrentStep();
  if (!step.hasLegMotion()) return true;
  timer_.splitTime("1");

  timer_.pinTime("2");
  double time = queue_.getCurrentStep().getTime();
  for (const auto& limb : adapter_->getLimbs()) {
    timer_.pinTime("writeLegmotion for loop");
    if (!step.hasLegMotion(limb)) continue;
    auto const& legMotion = step.getLegMotion(limb);
    ControlSetup controlSetup = legMotion.getControlSetup();
    state_->setControlSetup(limb, controlSetup);

    switch (legMotion.getTrajectoryType()) {

      case LegMotionBase::TrajectoryType::EndEffector:
      {
        const auto& endEffectorMotion = dynamic_cast<const EndEffectorMotionBase&>(legMotion);
        if (controlSetup[ControlLevel::Position]) {
          // TODO Add frame handling.
          Position positionInWorldFrame(endEffectorMotion.evaluatePosition(time));
          // TODO adapter_->getOrientationWorldToBase() is nicer when the robot slips, but leads to problems at lift-off.
          Position positionInBaseFrame(adapter_->getOrientationWorldToBase().rotate(positionInWorldFrame - adapter_->getPositionWorldToBaseInWorldFrame()));
//          Position positionInBaseFrame(state_->getOrientationWorldToBase().rotate(positionInWorldFrame - adapter_->getPositionWorldToBaseInWorldFrame()));
          JointPositions jointPositions;
          adapter_->getLimbJointPositionsFromPositionBaseToFootInBaseFrame(positionInBaseFrame, limb, jointPositions);
          state_->setJointPositions(limb, jointPositions);
        }
        break;
      }

      case LegMotionBase::TrajectoryType::Joints:
      {
        const auto& jointMotion = dynamic_cast<const JointTrajectory&>(legMotion);
        timer_.pinTime("writeLegMotion evalute spline");
        if (controlSetup[ControlLevel::Position]) state_->setJointPositions(limb, jointMotion.evaluatePosition(time));
//        if (controlSetup[ControlLevel::Velocity]) state_->setJointVelocities(limb, jointMotion.evaluateVelocity(time));
//        if (controlSetup[ControlLevel::Acceleration]) state_->setJointAcceleration(limb, jointMotion.evaluateAcceleration(time));
        if (controlSetup[ControlLevel::Effort]) state_->setJointEfforts(limb, jointMotion.evaluateEffort(time));
        timer_.splitTime("writeLegMotion evalute spline");
        break;
      }

      default:
        throw std::runtime_error("Executor::writeLegMotion() could not write leg motion of this type.");
        break;
    }
    timer_.splitTime("writeLegmotion for loop");
  }
  timer_.splitTime("2");

  return true;
}

bool Executor::writeTorsoMotion()
{
  if (state_->getNumberOfSupportLegs() == 0) state_->setEmptyControlSetup(BranchEnum::BASE);
  if (!queue_.active()) return true;

  if (!queue_.getCurrentStep().hasBaseMotion()) return true;
  double time = queue_.getCurrentStep().getTime();
  // TODO Add frame handling.
  const auto& baseMotion = queue_.getCurrentStep().getBaseMotion();
  ControlSetup controlSetup = baseMotion.getControlSetup();
  state_->setControlSetup(BranchEnum::BASE, controlSetup);
  if (controlSetup[ControlLevel::Position]) {
    Pose pose = baseMotion.evaluatePose(time);
    state_->setPositionWorldToBaseInWorldFrame(pose.getPosition());
    state_->setOrientationWorldToBase(pose.getRotation());
  }
  if (controlSetup[ControlLevel::Velocity]) {
    Twist twist = baseMotion.evaluateTwist(time);
    state_->setLinearVelocityBaseInWorldFrame(twist.getTranslationalVelocity());
    state_->setAngularVelocityBaseInBaseFrame(twist.getRotationalVelocity());
  }
  // TODO Set more states.
  return true;
}

} /* namespace free_gait */
<|endoftext|>


<commit_before>#include "nifpp.h"
#include <functional>
#include <utility>

class ResultSet
{
    std::unordered_map<int,std::vector<nifpp::TERM>> map_of_result_sets;
    std::unordered_map<int,std::vector<std::pair<int,int>>> current_result_index;
    std::unordered_map<int,std::vector<int>> reverse_result_index;
    int result_count;
    int total_count;
    ErlNifEnv* env;
public:
    ResultSet(int init_count)
    {
       total_count = init_count;
       result_count = 0;
       map_of_result_sets = {};
       current_result_index = {};
       std::vector<int> empty_vector = {};
       for (int i = 1; i <= init_count; ++i)
       {
           reverse_result_index.emplace(i,empty_vector);
       }
       env = NULL;
    }
    int get_result_count()
    {
        return result_count;
    }
    int get_total_count()
    {
        return total_count;
    }
    std::unordered_map<int,std::vector<nifpp::TERM>> get_map_of_results_sets()
    {
        return map_of_result_sets;
    }
    std::vector<std::vector<nifpp::TERM>> append_result_set(std::vector<nifpp::TERM> result_set,int uid, ErlNifEnv* env_outer)
    {
        if(result_count < total_count)
        {
            map_of_result_sets.emplace(uid, result_set);
            restructure_current_result_index(env_outer, uid);
            result_count++ ;
            std::vector<std::vector<nifpp::TERM>> final_result = {};
            if(result_count==total_count)
            {
                final_result = get_final_result_set(env_outer);
            }
            return final_result;
        }
        else
        {
            std::vector<std::vector<nifpp::TERM>> final_result = {};
            return final_result;
        }
    }
    void print_current_result_set()
    {
        for (auto it = current_result_index.begin(); it != current_result_index.end(); ++it)
        {
            printf("%d\n", it->first);
        }

    }
    void restructure_current_result_index(ErlNifEnv* env_outer, int uid)
    {
        int index = 0;
        ErlNifBinary ebin, bin_term;

        std::vector<nifpp::TERM> result_set = map_of_result_sets.at(uid);

        int arity;
        int hash_val;
        const ERL_NIF_TERM* tuple;
        int size = result_set.size();
        for (int i = 0; i < size; ++i)
        {
            if(enif_get_tuple(env_outer, result_set.at(i), &arity, &tuple)!=1)
                enif_make_badarg(env_outer);
            nifpp::get_throws(env_outer, tuple[0], ebin);
            enif_alloc_binary(ebin.size, &bin_term);
            memcpy(bin_term.data, ebin.data, ebin.size);
            hash_val = 0 ;
            for(int i=0; i<bin_term.size; ++i){
               hash_val = (10*hash_val) + bin_term.data[i];
            }
            std::pair<int, int> index_addr = std::make_pair(uid, index);
            std::vector<std::pair<int,int>> init_vector = {};
            init_vector.push_back(index_addr);
            auto emp_res = current_result_index.emplace (hash_val, init_vector);
            if(emp_res.second==false)
                current_result_index.at(hash_val).push_back(index_addr);
            int current_size = current_result_index.at(hash_val).size();
            reverse_result_index.at(current_size).push_back(hash_val);
            index = index + 1;
        }
    }

    std::vector<std::vector<nifpp::TERM>> get_final_result_set(ErlNifEnv* env)
    {
        std::vector<std::vector<nifpp::TERM>> final_result = {};
        int inner_index = 0;
        int arity; int comp_arity = 0;
        const ERL_NIF_TERM* tuple;
        ErlNifBinary ebin, bin_term;
        nifpp::TERM term;
        for (auto it_outer = reverse_result_index.at(total_count).begin(); it_outer != reverse_result_index.at(total_count).end(); ++it_outer)
        {
            std::vector<nifpp::TERM> appended_rows = {};
            inner_index = 0;
            for (auto it_inner = current_result_index.at(*it_outer).begin(); it_inner != current_result_index.at(*it_outer).end() ; ++it_inner)
            {
                comp_arity = 0;
                std::vector<nifpp::TERM> array_of_binaries = {};
                std::pair<int,int> curr_pair = (*it_inner);
                if(enif_get_tuple(env, map_of_result_sets.at(curr_pair.first).at(curr_pair.second), &arity, &tuple)!=1)
                    enif_make_badarg(env);

                if (inner_index==0)
                {
                    while(comp_arity != arity)
                    {
                        nifpp::get_throws(env, tuple[comp_arity], ebin);
                        enif_alloc_binary(ebin.size, &bin_term);
                        memcpy(bin_term.data, ebin.data, ebin.size);
                        term = nifpp::make(env, bin_term);
                        array_of_binaries.push_back(term);
                        comp_arity = comp_arity + 1;
                    }
                }
                else
                {
                    comp_arity =  1;
                    while(comp_arity != arity)
                    {
                        nifpp::get_throws(env, tuple[comp_arity], ebin);
                        enif_alloc_binary(ebin.size, &bin_term);
                        memcpy(bin_term.data, ebin.data, ebin.size);
                        term = nifpp::make(env, bin_term);
                        array_of_binaries.push_back(term);
                        comp_arity = comp_arity + 1;
                    }
                }
                appended_rows.insert(appended_rows.end(),array_of_binaries.begin(),array_of_binaries.end());

                inner_index = inner_index + 1;
            }
            final_result.push_back(appended_rows);
        }
        return final_result;
    }

    // ~ResultSet();

};
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
{
    nifpp::register_resource<ResultSet>(env, nullptr, "ResultSet");
    return 0;
}

static ERL_NIF_TERM initialize_result_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    try{
        int count;
        nifpp::get(env, argv[0], count);
        ERL_NIF_TERM result;
        auto map_ptr = nifpp::construct_resource<ResultSet>(count);
        result = nifpp::make(env, map_ptr);
        return result;
    }
    catch(nifpp::badarg) {}
    catch(...) {}
    return enif_make_badarg(env);
}

static ERL_NIF_TERM append_result_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    try
    {
        ERL_NIF_TERM result;
        nifpp::resource_ptr<ResultSet> ptr;
        std::vector<std::vector<nifpp::TERM>> result_set;
        std::vector<nifpp::TERM> input_result_set;
        int uid;
        nifpp::get(env, argv[0], ptr);
        nifpp::get(env, argv[1], input_result_set);
        nifpp::get(env, argv[2], uid);
        result_set = (*ptr).append_result_set(input_result_set, uid, env);
        if ((*ptr).get_total_count()==(*ptr).get_result_count())
        {
            return nifpp::make(env, result_set);
        }
        auto new_result = (*ptr).get_map_of_results_sets();
        return nifpp::make(env, new_result);
        // return result;
    }
    catch(...) {}
    return enif_make_badarg(env);
}

static ERL_NIF_TERM return_result_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    try
    {
        nifpp::resource_ptr<ResultSet> ptr;
        if(nifpp::get(env, argv[0], ptr)==1)
        {
            (*ptr) = NULL;
        }
        else
        {
            return enif_make_badarg(env);
        }
        return nifpp::make(env, 1);
    }
    catch(...) {}
    return enif_make_badarg(env);
}

static ERL_NIF_TERM nullify_result_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    try
    {
        ERL_NIF_TERM result;
        nifpp::resource_ptr<ResultSet> ptr;
        std::vector<std::vector<nifpp::TERM>> result_set;
        std::vector<nifpp::TERM> input_result_set;
        nifpp::get(env, argv[0], ptr);
        // (*ptr) = NULL;
        // free(ptr);
        return nifpp::make(env, 1);
    }
    catch(...){}
    return enif_make_badarg(env);
}

extern "C" {

static ErlNifFunc nif_funcs[] = {
                                    {"initialize_result_set", 1, initialize_result_set},
                                    {"return_result_set", 1, return_result_set},
                                    {"append_result_set", 3, append_result_set},
                                };

ERL_NIF_INIT(par_append_tuple, nif_funcs, load, NULL, NULL, NULL)

}//extern C<commit_msg>still need to test parallel merge effectively<commit_after>#include "nifpp.h"
#include <functional>
#include <utility>

class ResultSet
{
    std::unordered_map<int,std::vector<nifpp::TERM>> map_of_result_sets;
    std::unordered_map<int,std::vector<std::pair<int,int>>> current_result_index;
    std::unordered_map<int,std::vector<int>> reverse_result_index;
    std::unordered_map<int,ErlNifEnv*> env_map;
    int result_count;
    int total_count;
    ErlNifEnv* env;
public:
    ResultSet(int init_count)
    {
       total_count = init_count;
       result_count = 0;
       map_of_result_sets = {};
       current_result_index = {};
       std::vector<int> empty_vector = {};
       for (int i = 1; i <= init_count; ++i)
           reverse_result_index.emplace(i,empty_vector);
       env = NULL;
    }
    int get_result_count()
    {
        return result_count;
    }
    int get_total_count()
    {
        return total_count;
    }
    std::unordered_map<int,std::vector<nifpp::TERM>> get_map_of_results_sets()
    {
        return map_of_result_sets;
    }
    std::vector<std::vector<nifpp::TERM>> append_result_set(std::vector<nifpp::TERM> result_set,int uid, ErlNifEnv* env_outer)
    {
        std::vector<std::vector<nifpp::TERM>> final_result_set = {};
        if(result_count < total_count)
        {
            map_of_result_sets.emplace(uid, result_set);
            env_map.emplace(uid, env_outer);
            restructure_current_result_index(env_outer, uid);
            result_count++ ;
            if (result_count==total_count)
            {
                final_result_set = get_final_result_set(env_outer);
            }
        }
        return final_result_set;
    }
    void print_current_result_set()
    {
        for (auto it = current_result_index.begin(); it != current_result_index.end(); ++it)
            printf("%d\n", it->first);

    }
    void restructure_current_result_index(ErlNifEnv* env_outer, int uid)
    {
        int index = 0;
        ErlNifBinary ebin, bin_term;

        std::vector<nifpp::TERM> result_set = map_of_result_sets.at(uid);

        int arity;
        int hash_val;
        const ERL_NIF_TERM* tuple;
        int size = result_set.size();
        for (int i = 0; i < size; ++i)
        {
            if(enif_get_tuple(env_outer, result_set.at(i), &arity, &tuple)!=1)
                enif_make_badarg(env_outer);
            nifpp::get_throws(env_outer, tuple[0], ebin);
            enif_alloc_binary(ebin.size, &bin_term);
            memcpy(bin_term.data, ebin.data, ebin.size);
            hash_val = 0 ;
            for(int i=0; i<bin_term.size; ++i){
               hash_val = (10*hash_val) + bin_term.data[i];
            }
            std::pair<int, int> index_addr = std::make_pair(uid, index);
            std::vector<std::pair<int,int>> init_vector = {};
            init_vector.push_back(index_addr);
            auto emp_res = current_result_index.emplace (hash_val, init_vector);
            if(emp_res.second==false)
                current_result_index.at(hash_val).push_back(index_addr);
            int current_size = current_result_index.at(hash_val).size();
            reverse_result_index.at(current_size).push_back(hash_val);
            index = index + 1;
        }
    }

    std::vector<std::vector<nifpp::TERM>> get_final_result_set(ErlNifEnv* env)
    {
        std::vector<std::vector<nifpp::TERM>> final_result = {};
        int inner_index = 0;
        int arity; int comp_arity = 0;
        const ERL_NIF_TERM* tuple1;
        const ERL_NIF_TERM* tuple2;
        ErlNifBinary ebin, bin_term;

        nifpp::TERM term;
        for (auto it_outer = reverse_result_index.at(total_count).begin(); it_outer != reverse_result_index.at(total_count).end(); ++it_outer)
        {
            std::vector<nifpp::TERM> appended_rows = {};
            inner_index = 0;
            for (auto it_inner = current_result_index.at(*it_outer).begin(); it_inner != current_result_index.at(*it_outer).end() ; ++it_inner)
            {
                comp_arity = 0;
                std::vector<nifpp::TERM> array_of_binaries = {};
                std::pair<int,int> curr_pair = (*it_inner);
                ErlNifEnv* env_inner = env_map.at(curr_pair.first);
                if (result_count==2)
                {
                     if(enif_get_tuple(env_inner, map_of_result_sets.at(curr_pair.first).at(curr_pair.second), &arity, &tuple2)!=1)
                        enif_make_badarg(env);
                        printf("%d%d%d%d\n", curr_pair.first, curr_pair.second, arity, comp_arity);
                        nifpp::get_throws(env_inner, tuple2[comp_arity], ebin);
                }
                else
                {
                    if(enif_get_tuple(env_inner, map_of_result_sets.at(curr_pair.first).at(curr_pair.second), &arity, &tuple1)!=1)
                        enif_make_badarg(env);
                        nifpp::get_throws(env_inner, tuple1[comp_arity], ebin);
                }

                // if (inner_index==0)
                // {
                //     while(comp_arity != arity && comp_arity < arity)
                //     {
                //         printf("%s\n", "a");
                //         nifpp::get_throws(env_inner, tuple[comp_arity], ebin);
                //         printf("%s\n", "b");
                //         enif_alloc_binary(ebin.size, &bin_term);
                //         memcpy(bin_term.data, ebin.data, ebin.size);
                //         term = nifpp::make(env, bin_term);
                //         array_of_binaries.push_back(term);
                //         comp_arity = comp_arity + 1;
                //     }

                // }
                // else
                // {
                //     comp_arity =  1;
                //     while(comp_arity != arity && comp_arity < arity)
                //     {
                //         nifpp::get_throws(env_inner, tuple[comp_arity], ebin);
                //         enif_alloc_binary(ebin.size, &bin_term);
                //         memcpy(bin_term.data, ebin.data, ebin.size);
                //         term = nifpp::make(env, bin_term);
                //         array_of_binaries.push_back(term);
                //         comp_arity = comp_arity + 1;
                //     }

                // }
                appended_rows.insert(appended_rows.end(),array_of_binaries.begin(),array_of_binaries.end());
                inner_index = inner_index + 1;
            }
            final_result.push_back(appended_rows);
        }
        return final_result;
    }

    // ~ResultSet();

};
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
{
    nifpp::register_resource<ResultSet>(env, nullptr, "ResultSet");
    return 0;
}

static ERL_NIF_TERM initialize_result_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    try{
        int count;
        nifpp::get(env, argv[0], count);
        ERL_NIF_TERM result;
        auto map_ptr = nifpp::construct_resource<ResultSet>(count);
        result = nifpp::make(env, map_ptr);
        return result;
    }
    catch(nifpp::badarg) {}
    catch(...) {}
    return enif_make_badarg(env);
}

static ERL_NIF_TERM append_result_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    try
    {
        ERL_NIF_TERM result;
        nifpp::resource_ptr<ResultSet> ptr;
        std::vector<std::vector<nifpp::TERM>> result_set;
        std::vector<nifpp::TERM> input_result_set;
        int uid;
        nifpp::get(env, argv[0], ptr);
        nifpp::get(env, argv[1], input_result_set);
        nifpp::get(env, argv[2], uid);
        std::vector<std::vector<nifpp::TERM>> new_result = (*ptr).append_result_set(input_result_set, uid, env);
        return nifpp::make(env, new_result);
        // return result;
    }
    catch(...) {}
    return enif_make_badarg(env);
}

static ERL_NIF_TERM return_result_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    try
    {
        nifpp::resource_ptr<ResultSet> ptr;
        if(nifpp::get(env, argv[0], ptr)==1)
        {
            std::vector<std::vector<nifpp::TERM>> new_result = (*ptr).get_final_result_set(env);
            return nifpp::make(env, new_result);
        }
        else
            return enif_make_badarg(env);
    }
    catch(...) {}
    return enif_make_badarg(env);
}

static ERL_NIF_TERM nullify_result_set(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    try
    {
        ERL_NIF_TERM result;
        nifpp::resource_ptr<ResultSet> ptr;
        std::vector<std::vector<nifpp::TERM>> result_set;
        std::vector<nifpp::TERM> input_result_set;
        nifpp::get(env, argv[0], ptr);
        // (*ptr) = NULL;

    }
    catch(...){}
    return enif_make_badarg(env);
}

extern "C" {

static ErlNifFunc nif_funcs[] = {
                                    {"initialize_result_set", 1, initialize_result_set},
                                    {"return_result_set", 1, return_result_set},
                                    {"append_result_set", 3, append_result_set},
                                };

ERL_NIF_INIT(par_append_tuple, nif_funcs, load, NULL, NULL, NULL)

}//extern C<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_auth_cache.h"

#include "base/logging.h"
#include "base/string_util.h"

namespace {

// Helper to find the containing directory of path. In RFC 2617 this is what
// they call the "last symbolic element in the absolute path".
// Examples:
//   "/foo/bar.txt" --> "/foo/"
//   "/foo/" --> "/foo/"
std::string GetParentDirectory(const std::string& path) {
  std::string::size_type last_slash = path.rfind("/");
  if (last_slash == std::string::npos) {
    // No slash (absolute paths always start with slash, so this must be
    // the proxy case which uses empty string).
    DCHECK(path.empty());
    return path;
  }
  return path.substr(0, last_slash + 1);
}

// Debug helper to check that |path| arguments are properly formed.
// (should be absolute path, or empty string).
void CheckPathIsValid(const std::string& path) {
  DCHECK(path.empty() || path[0] == '/');
}

// Return true if |path| is a subpath of |container|. In other words, is
// |container| an ancestor of |path|?
bool IsEnclosingPath(const std::string& container, const std::string& path) {
  DCHECK(container.empty() || *(container.end() - 1) == '/');
  return ((container.empty() && path.empty()) ||
          (!container.empty() && StartsWithASCII(path, container, true)));
}

// Debug helper to check that |origin| arguments are properly formed.
void CheckOriginIsValid(const GURL& origin) {
  DCHECK(origin.is_valid());
  DCHECK(origin.SchemeIs("http") || origin.SchemeIs("https"));
  DCHECK(origin.GetOrigin() == origin);
}

// Functor used by remove_if.
struct IsEnclosedBy {
  explicit IsEnclosedBy(const std::string& path) : path(path) { }
  bool operator() (const std::string& x) {
    return IsEnclosingPath(path, x);
  }
  const std::string& path;
};

}  // namespace

namespace net {

HttpAuthCache::HttpAuthCache() {
}

HttpAuthCache::~HttpAuthCache() {
}

// Performance: O(n), where n is the number of realm entries.
HttpAuthCache::Entry* HttpAuthCache::Lookup(const GURL& origin,
                                            const std::string& realm,
                                            HttpAuth::Scheme scheme) {
  CheckOriginIsValid(origin);

  // Linear scan through the realm entries.
  for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
    if (it->origin() == origin && it->realm() == realm &&
        it->scheme() == scheme)
      return &(*it);
  }
  return NULL;  // No realm entry found.
}

// Performance: O(n*m), where n is the number of realm entries, m is the number
// of path entries per realm. Both n amd m are expected to be small; m is
// kept small because AddPath() only keeps the shallowest entry.
HttpAuthCache::Entry* HttpAuthCache::LookupByPath(const GURL& origin,
                                                  const std::string& path) {
  CheckOriginIsValid(origin);
  CheckPathIsValid(path);

  // RFC 2617 section 2:
  // A client SHOULD assume that all paths at or deeper than the depth of
  // the last symbolic element in the path field of the Request-URI also are
  // within the protection space ...
  std::string parent_dir = GetParentDirectory(path);

  // Linear scan through the realm entries.
  for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
    if (it->origin() == origin && it->HasEnclosingPath(parent_dir))
      return &(*it);
  }
  return NULL;  // No entry found.
}

HttpAuthCache::Entry* HttpAuthCache::Add(const GURL& origin,
                                         const std::string& realm,
                                         HttpAuth::Scheme scheme,
                                         const std::string& auth_challenge,
                                         const string16& username,
                                         const string16& password,
                                         const std::string& path) {
  CheckOriginIsValid(origin);
  CheckPathIsValid(path);

  // Check for existing entry (we will re-use it if present).
  HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme);
  if (!entry) {
    // Failsafe to prevent unbounded memory growth of the cache.
    if (entries_.size() >= kMaxNumRealmEntries) {
      LOG(WARNING) << "Num auth cache entries reached limit -- evicting";
      entries_.pop_back();
    }

    entries_.push_front(Entry());
    entry = &entries_.front();
    entry->origin_ = origin;
    entry->realm_ = realm;
    entry->scheme_ = scheme;
  }
  DCHECK_EQ(origin, entry->origin_);
  DCHECK_EQ(realm, entry->realm_);
  DCHECK_EQ(scheme, entry->scheme_);

  entry->auth_challenge_ = auth_challenge;
  entry->username_ = username;
  entry->password_ = password;
  entry->nonce_count_ = 1;
  entry->AddPath(path);

  return entry;
}

HttpAuthCache::Entry::~Entry() {
}

void HttpAuthCache::Entry::UpdateStaleChallenge(
    const std::string& auth_challenge) {
  auth_challenge_ = auth_challenge;
  nonce_count_ = 1;
}

HttpAuthCache::Entry::Entry()
    : nonce_count_(0) {
}

void HttpAuthCache::Entry::AddPath(const std::string& path) {
  std::string parent_dir = GetParentDirectory(path);
  if (!HasEnclosingPath(parent_dir)) {
    // Remove any entries that have been subsumed by the new entry.
    paths_.remove_if(IsEnclosedBy(parent_dir));

    // Failsafe to prevent unbounded memory growth of the cache.
    if (paths_.size() >= kMaxNumPathsPerRealmEntry) {
      LOG(WARNING) << "Num path entries for " << origin()
                   << " has grown too large -- evicting";
      paths_.pop_back();
    }

    // Add new path.
    paths_.push_front(parent_dir);
  }
}

bool HttpAuthCache::Entry::HasEnclosingPath(const std::string& dir) {
  DCHECK(GetParentDirectory(dir) == dir);
  for (PathList::const_iterator it = paths_.begin(); it != paths_.end();
       ++it) {
    if (IsEnclosingPath(*it, dir))
      return true;
  }
  return false;
}

bool HttpAuthCache::Remove(const GURL& origin,
                           const std::string& realm,
                           HttpAuth::Scheme scheme,
                           const string16& username,
                           const string16& password) {
  for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
    if (it->origin() == origin && it->realm() == realm &&
        it->scheme() == scheme) {
      if (username == it->username() && password == it->password()) {
        entries_.erase(it);
        return true;
      }
      return false;
    }
  }
  return false;
}

bool HttpAuthCache::UpdateStaleChallenge(const GURL& origin,
                                         const std::string& realm,
                                         HttpAuth::Scheme scheme,
                                         const std::string& auth_challenge) {
  HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme);
  if (!entry)
    return false;
  entry->UpdateStaleChallenge(auth_challenge);
  return true;
}

}  // namespace net
<commit_msg>Fix Coverity UNINIT_CTOR defect in the HttpAuthCache::Entry constructor.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_auth_cache.h"

#include "base/logging.h"
#include "base/string_util.h"

namespace {

// Helper to find the containing directory of path. In RFC 2617 this is what
// they call the "last symbolic element in the absolute path".
// Examples:
//   "/foo/bar.txt" --> "/foo/"
//   "/foo/" --> "/foo/"
std::string GetParentDirectory(const std::string& path) {
  std::string::size_type last_slash = path.rfind("/");
  if (last_slash == std::string::npos) {
    // No slash (absolute paths always start with slash, so this must be
    // the proxy case which uses empty string).
    DCHECK(path.empty());
    return path;
  }
  return path.substr(0, last_slash + 1);
}

// Debug helper to check that |path| arguments are properly formed.
// (should be absolute path, or empty string).
void CheckPathIsValid(const std::string& path) {
  DCHECK(path.empty() || path[0] == '/');
}

// Return true if |path| is a subpath of |container|. In other words, is
// |container| an ancestor of |path|?
bool IsEnclosingPath(const std::string& container, const std::string& path) {
  DCHECK(container.empty() || *(container.end() - 1) == '/');
  return ((container.empty() && path.empty()) ||
          (!container.empty() && StartsWithASCII(path, container, true)));
}

// Debug helper to check that |origin| arguments are properly formed.
void CheckOriginIsValid(const GURL& origin) {
  DCHECK(origin.is_valid());
  DCHECK(origin.SchemeIs("http") || origin.SchemeIs("https"));
  DCHECK(origin.GetOrigin() == origin);
}

// Functor used by remove_if.
struct IsEnclosedBy {
  explicit IsEnclosedBy(const std::string& path) : path(path) { }
  bool operator() (const std::string& x) {
    return IsEnclosingPath(path, x);
  }
  const std::string& path;
};

}  // namespace

namespace net {

HttpAuthCache::HttpAuthCache() {
}

HttpAuthCache::~HttpAuthCache() {
}

// Performance: O(n), where n is the number of realm entries.
HttpAuthCache::Entry* HttpAuthCache::Lookup(const GURL& origin,
                                            const std::string& realm,
                                            HttpAuth::Scheme scheme) {
  CheckOriginIsValid(origin);

  // Linear scan through the realm entries.
  for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
    if (it->origin() == origin && it->realm() == realm &&
        it->scheme() == scheme)
      return &(*it);
  }
  return NULL;  // No realm entry found.
}

// Performance: O(n*m), where n is the number of realm entries, m is the number
// of path entries per realm. Both n amd m are expected to be small; m is
// kept small because AddPath() only keeps the shallowest entry.
HttpAuthCache::Entry* HttpAuthCache::LookupByPath(const GURL& origin,
                                                  const std::string& path) {
  CheckOriginIsValid(origin);
  CheckPathIsValid(path);

  // RFC 2617 section 2:
  // A client SHOULD assume that all paths at or deeper than the depth of
  // the last symbolic element in the path field of the Request-URI also are
  // within the protection space ...
  std::string parent_dir = GetParentDirectory(path);

  // Linear scan through the realm entries.
  for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
    if (it->origin() == origin && it->HasEnclosingPath(parent_dir))
      return &(*it);
  }
  return NULL;  // No entry found.
}

HttpAuthCache::Entry* HttpAuthCache::Add(const GURL& origin,
                                         const std::string& realm,
                                         HttpAuth::Scheme scheme,
                                         const std::string& auth_challenge,
                                         const string16& username,
                                         const string16& password,
                                         const std::string& path) {
  CheckOriginIsValid(origin);
  CheckPathIsValid(path);

  // Check for existing entry (we will re-use it if present).
  HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme);
  if (!entry) {
    // Failsafe to prevent unbounded memory growth of the cache.
    if (entries_.size() >= kMaxNumRealmEntries) {
      LOG(WARNING) << "Num auth cache entries reached limit -- evicting";
      entries_.pop_back();
    }

    entries_.push_front(Entry());
    entry = &entries_.front();
    entry->origin_ = origin;
    entry->realm_ = realm;
    entry->scheme_ = scheme;
  }
  DCHECK_EQ(origin, entry->origin_);
  DCHECK_EQ(realm, entry->realm_);
  DCHECK_EQ(scheme, entry->scheme_);

  entry->auth_challenge_ = auth_challenge;
  entry->username_ = username;
  entry->password_ = password;
  entry->nonce_count_ = 1;
  entry->AddPath(path);

  return entry;
}

HttpAuthCache::Entry::~Entry() {
}

void HttpAuthCache::Entry::UpdateStaleChallenge(
    const std::string& auth_challenge) {
  auth_challenge_ = auth_challenge;
  nonce_count_ = 1;
}

HttpAuthCache::Entry::Entry()
    : scheme_(HttpAuth::AUTH_SCHEME_MAX),
      nonce_count_(0) {
}

void HttpAuthCache::Entry::AddPath(const std::string& path) {
  std::string parent_dir = GetParentDirectory(path);
  if (!HasEnclosingPath(parent_dir)) {
    // Remove any entries that have been subsumed by the new entry.
    paths_.remove_if(IsEnclosedBy(parent_dir));

    // Failsafe to prevent unbounded memory growth of the cache.
    if (paths_.size() >= kMaxNumPathsPerRealmEntry) {
      LOG(WARNING) << "Num path entries for " << origin()
                   << " has grown too large -- evicting";
      paths_.pop_back();
    }

    // Add new path.
    paths_.push_front(parent_dir);
  }
}

bool HttpAuthCache::Entry::HasEnclosingPath(const std::string& dir) {
  DCHECK(GetParentDirectory(dir) == dir);
  for (PathList::const_iterator it = paths_.begin(); it != paths_.end();
       ++it) {
    if (IsEnclosingPath(*it, dir))
      return true;
  }
  return false;
}

bool HttpAuthCache::Remove(const GURL& origin,
                           const std::string& realm,
                           HttpAuth::Scheme scheme,
                           const string16& username,
                           const string16& password) {
  for (EntryList::iterator it = entries_.begin(); it != entries_.end(); ++it) {
    if (it->origin() == origin && it->realm() == realm &&
        it->scheme() == scheme) {
      if (username == it->username() && password == it->password()) {
        entries_.erase(it);
        return true;
      }
      return false;
    }
  }
  return false;
}

bool HttpAuthCache::UpdateStaleChallenge(const GURL& origin,
                                         const std::string& realm,
                                         HttpAuth::Scheme scheme,
                                         const std::string& auth_challenge) {
  HttpAuthCache::Entry* entry = Lookup(origin, realm, scheme);
  if (!entry)
    return false;
  entry->UpdateStaleChallenge(auth_challenge);
  return true;
}

}  // namespace net
<|endoftext|>


<commit_before><commit_msg>always include fcntl.h<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2017 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <memory>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class tcp_client : private boost::noncopyable {
  tcp::socket socket_;

  void do_connect(tcp::resolver::iterator epiter) {
    boost::asio::async_connect(socket_, epiter,
        [this](const boost::system::error_code& ec, tcp::resolver::iterator) {
          if (!ec) {
            std::cout << "tcp.client connect to server success ..." << std::endl;

            do_read();
            do_write();
          }
          else {
            socket_.close();
          }
        });
  }

  void do_read(void) {
    char buf[1024]{};
    socket_.async_read_some(boost::asio::buffer(buf, sizeof(buf)),
        [this, &buf](const boost::system::error_code& ec, std::size_t /*n*/) {
          if (!ec)
            std::cout << "echo reply: " << buf << std::endl;

          socket_.close();
        });
  }

  void do_write(void) {
    std::string echo_msg = "Hello, world!";
    boost::asio::async_write(socket_, boost::asio::buffer(echo_msg),
        [this](boost::system::error_code ec, std::size_t /*n*/) {
          if (ec)
            socket_.close();
        });
  }
public:
  tcp_client(boost::asio::io_service& io_service)
    : socket_(io_service) {
  }

  void start(tcp::resolver::iterator epiter) {
    do_connect(epiter);
  }
};

int main(int argc, char* argv[]) {
  ((void)argc), ((void)argv);

  boost::asio::io_service io_service;

  tcp_client client(io_service);
  tcp::resolver r(io_service);
  client.start(r.resolve({"127.0.0.1", "5555"}));

  io_service.run();

  return 0;
}
<commit_msg>:bug: fix(asio.client): fixed client bug about async-handler running in other thread<commit_after>// Copyright (c) 2017 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <memory>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class tcp_client : private boost::noncopyable, public std::enable_shared_from_this<tcp_client> {
  tcp::socket socket_;

  void do_connect(tcp::resolver::iterator epiter) {
    auto self(shared_from_this());
    boost::asio::async_connect(socket_, epiter,
        [this, self](const boost::system::error_code& ec, tcp::resolver::iterator) {
          if (!ec) {
            std::cout << "tcp.client connect to server success ..." << std::endl;

            do_read();
            do_write();
          }
          else {
            socket_.close();
          }
        });
  }

  void do_read(void) {
    char buf[1024]{};
    auto self(shared_from_this());
    socket_.async_read_some(boost::asio::buffer(buf, sizeof(buf)),
        [this, self, &buf](const boost::system::error_code& ec, std::size_t /*n*/) {
          if (!ec)
            std::cout << "echo reply: " << buf << std::endl;

          socket_.close();
        });
  }

  void do_write(void) {
    std::string echo_msg = "Hello, world!";
    auto self(shared_from_this());
    boost::asio::async_write(socket_, boost::asio::buffer(echo_msg),
        [this, self](boost::system::error_code ec, std::size_t /*n*/) {
          if (ec)
            socket_.close();
        });
  }
public:
  tcp_client(boost::asio::io_service& io_service)
    : socket_(io_service) {
  }

  void start(tcp::resolver::iterator epiter) {
    do_connect(epiter);
  }
};

int main(int argc, char* argv[]) {
  ((void)argc), ((void)argv);

  boost::asio::io_service io_service;

  std::shared_ptr<tcp_client> client(new tcp_client(io_service));
  tcp::resolver r(io_service);
  client->start(r.resolve({"127.0.0.1", "5555"}));

  io_service.run();

  return 0;
}
<|endoftext|>


<commit_before>#ifndef THREAD_POOL_HPP
#define THREAD_POOL_HPP

#include <noncopyable.hpp>
#include <worker.hpp>
#include <work_distributor.hpp>
#include <memory>
#include <stdexcept>
#include <vector>

class thread_pool_t : private noncopyable_t {
public:
    enum {AUTODETECT = 0};

    inline explicit thread_pool_t(size_t threads_count = AUTODETECT);

    template <typename Handler>
    inline void post(Handler &&handler);

private:
    typedef std::unique_ptr<worker_t> worker_ptr;
    std::vector<worker_ptr> m_pool;

    work_distributor_t m_distributor;
};

/// Implementation

inline thread_pool_t::thread_pool_t(size_t threads_count)
{
    if (AUTODETECT == threads_count) {
        threads_count = std::thread::hardware_concurrency();
    }

    if (0 == threads_count) {
        threads_count = 1;
    }

    m_pool.resize(threads_count);

    for (auto &worker : m_pool) {
        worker.reset(new worker_t);
        m_distributor.add_worker(worker.get());
    }
}

template <typename Handler>
inline void thread_pool_t::post(Handler &&handler)
{
    worker_t *chosen = m_distributor.get_worker();
    if (!chosen->post(std::forward<Handler>(handler)))
    {
        throw std::overflow_error("worker queue is full");
    }
}

#endif

<commit_msg>code cleanup<commit_after>#ifndef THREAD_POOL_HPP
#define THREAD_POOL_HPP

#include <noncopyable.hpp>
#include <worker.hpp>
#include <work_distributor.hpp>
#include <memory>
#include <stdexcept>
#include <vector>

class thread_pool_t : private noncopyable_t {
public:
    enum {AUTODETECT = 0};

    explicit thread_pool_t(size_t threads_count = AUTODETECT);

    template <typename Handler>
    void post(Handler &&handler);

private:
    typedef std::unique_ptr<worker_t> worker_ptr;
    std::vector<worker_ptr> m_pool;

    work_distributor_t m_distributor;
};

/// Implementation

inline thread_pool_t::thread_pool_t(size_t threads_count)
{
    if (AUTODETECT == threads_count) {
        threads_count = std::thread::hardware_concurrency();
    }

    if (0 == threads_count) {
        threads_count = 1;
    }

    m_pool.resize(threads_count);

    for (auto &worker : m_pool) {
        worker.reset(new worker_t);
        m_distributor.add_worker(worker.get());
    }
}

template <typename Handler>
inline void thread_pool_t::post(Handler &&handler)
{
    worker_t *chosen = m_distributor.get_worker();
    if (!chosen->post(std::forward<Handler>(handler)))
    {
        throw std::overflow_error("worker queue is full");
    }
}

#endif

<|endoftext|>