<commit_before>#ifndef V_SMC_INTERNAL_COMMON_HPP
#define V_SMC_INTERNAL_COMMON_HPP

#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif // __STDC_CONSTANT_MACROS

#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdlib>
#include <utility>
#include <map>
#include <set>
#include <deque>
#include <vector>
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>

#ifdef __INTEL_COMPILER
// #pragma warning(push)
#pragma warning(disable:2196)
#pragma warning(disable:2536)
#endif // __INTEL_COMPILER

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wall"
#pragma clang diagnostic ignored "-Wunique-enum"
#endif // __clang__

#include <Eigen/Dense>

#ifdef __INTEL_COMPILER
// #pragma warning(pop)
#endif // __INTEL_COMPILER

#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__

#include <vSMC/internal/config.hpp>
#include <vSMC/internal/version.hpp>
#include <vSMC/internal/function.hpp>
#include <vSMC/internal/type_traits.hpp>
#include <vSMC/rng/random.hpp>

#ifndef V_SMC_INDEX_TYPE
#define V_SMC_INDEX_TYPE EIGEN_DEFAULT_DENSE_INDEX_TYPE
#endif // V_SMC_INDEX_TYPE

namespace vSMC {

template <typename T> class Sampler;
template <typename T> class Particle;
template <typename T> class Monitor;
template <typename T> class Path;

template <typename T> class SingleParticle;
template <typename T> class ConstSingleParticle;
template <unsigned Dim, typename T> class StateBase;

template <typename T> class InitializeSeq;
template <typename T> class MoveSeq;
template <typename T, unsigned Dim> class MonitorSeq;
template <typename T> class PathSeq;

template <typename T> class InitializeTBB;
template <typename T> class MoveTBB;
template <typename T, unsigned Dim> class MonitorTBB;
template <typename T> class PathTBB;

template <unsigned Dim, typename T> class StateCL;
template <typename T> class InitializeCL;
template <typename T> class MoveCL;
template <typename T, unsigned Dim> class MonitorCL;
template <typename T> class PathCL;

class StateBaseTrait
{
    public :

    virtual ~StateBaseTrait () {}
};

class StateSeqTrait
{
    public :

    virtual ~StateSeqTrait () {}
};

class InitializeSeqTrait
{
    public :

    virtual ~InitializeSeqTrait () {}
};

class MoveSeqTrait
{
    public :

    virtual ~MoveSeqTrait () {}
};

class MonitorSeqTrait
{
    public :

    virtual ~MonitorSeqTrait () {}
};

class PathSeqTrait
{
    public :

    virtual ~PathSeqTrait () {}
};

class StateTBBTrait
{
    public :

    virtual ~StateTBBTrait () {}

    virtual void pre_resampling () = 0;
    virtual void post_resampling () = 0;
};

class InitializeTBBTrait
{
    public :

    virtual ~InitializeTBBTrait () {}
};

class MoveTBBTrait
{
    public :

    virtual ~MoveTBBTrait () {}
};

class MonitorTBBTrait
{
    public :

    virtual ~MonitorTBBTrait () {}
};

class PathTBBTrait
{
    public :

    virtual ~PathTBBTrait () {}
};

class StateCLTrait
{
    public :

    virtual ~StateCLTrait () {}

    virtual void pre_resampling () = 0;
    virtual void post_resampling () = 0;
};

class InitializeCLTrait
{
    public :

    virtual ~InitializeCLTrait () {}
};

class MoveCLTrait
{
    public :

    virtual ~MoveCLTrait () {}
};

class MonitorCLTrait
{
    public :

    virtual ~MonitorCLTrait () {}
};

class PathCLTrait
{
    public :

    virtual ~PathCLTrait () {}
};

/// \brief Resample scheme
/// \ingroup Core
enum ResampleScheme {
    MULTINOMIAL,         ///< Multinomial resampling
    RESIDUAL,            ///< Reisudal resampling
    STRATIFIED,          ///< Startified resampling
    SYSTEMATIC,          ///< Systematic resampling
    RESIDUAL_STRATIFIED, ///< Stratified resampling on the residuals
    RESIDUAL_SYSTEMATIC  ///< Systematic resampling on the residuals
}; // enum ResamleScheme

} // namespace vSMC

#endif // V_SMC_INTERNAL_COMMON_HPP
<commit_msg>cleanup<commit_after>#ifndef V_SMC_INTERNAL_COMMON_HPP
#define V_SMC_INTERNAL_COMMON_HPP

#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif // __STDC_CONSTANT_MACROS

#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdlib>
#include <utility>
#include <map>
#include <set>
#include <deque>
#include <vector>
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>

#ifdef __INTEL_COMPILER
// #pragma warning(push)
#pragma warning(disable:2196)
#pragma warning(disable:2536)
#endif // __INTEL_COMPILER

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wall"
#pragma clang diagnostic ignored "-Wunique-enum"
#endif // __clang__

#include <Eigen/Dense>

#ifdef __INTEL_COMPILER
// #pragma warning(pop)
#endif // __INTEL_COMPILER

#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__

#include <vSMC/internal/config.hpp>
#include <vSMC/internal/version.hpp>
#include <vSMC/internal/function.hpp>
#include <vSMC/internal/type_traits.hpp>
#include <vSMC/rng/random.hpp>

#ifndef V_SMC_INDEX_TYPE
#define V_SMC_INDEX_TYPE EIGEN_DEFAULT_DENSE_INDEX_TYPE
#endif // V_SMC_INDEX_TYPE

namespace vSMC {

template <typename T> class Sampler;
template <typename T> class Particle;
template <typename T> class Monitor;
template <typename T> class Path;

template <typename T> class SingleParticle;
template <typename T> class ConstSingleParticle;
template <unsigned Dim, typename T> class StateBase;

template <typename T> class InitializeSeq;
template <typename T> class MoveSeq;
template <typename T, unsigned Dim> class MonitorSeq;
template <typename T> class PathSeq;

template <typename T> class InitializeTBB;
template <typename T> class MoveTBB;
template <typename T, unsigned Dim> class MonitorTBB;
template <typename T> class PathTBB;

template <unsigned Dim, typename T> class StateCL;
template <typename T> class InitializeCL;
template <typename T> class MoveCL;
template <typename T, unsigned Dim> class MonitorCL;
template <typename T> class PathCL;

class StateBaseTrait
{
    public :

    virtual ~StateBaseTrait () {}
};

class StateSeqTrait
{
    public :

    virtual ~StateSeqTrait () {}
};

class InitializeSeqTrait
{
    public :

    virtual ~InitializeSeqTrait () {}
};

class MoveSeqTrait
{
    public :

    virtual ~MoveSeqTrait () {}
};

class MonitorSeqTrait
{
    public :

    virtual ~MonitorSeqTrait () {}
};

class PathSeqTrait
{
    public :

    virtual ~PathSeqTrait () {}
};

class StateTBBTrait
{
    public :

    virtual ~StateTBBTrait () {}

    virtual void pre_resampling () = 0;
    virtual void post_resampling () = 0;
};

class InitializeTBBTrait
{
    public :

    virtual ~InitializeTBBTrait () {}
};

class MoveTBBTrait
{
    public :

    virtual ~MoveTBBTrait () {}
};

class MonitorTBBTrait
{
    public :

    virtual ~MonitorTBBTrait () {}
};

class PathTBBTrait
{
    public :

    virtual ~PathTBBTrait () {}
};

class StateCLTrait
{
    public :

    virtual ~StateCLTrait () {}

    virtual void pre_resampling () = 0;
    virtual void post_resampling () = 0;
};

class InitializeCLTrait
{
    public :

    virtual ~InitializeCLTrait () {}
};

class MoveCLTrait
{
    public :

    virtual ~MoveCLTrait () {}
};

class MonitorCLTrait
{
    public :

    virtual ~MonitorCLTrait () {}
};

class PathCLTrait
{
    public :

    virtual ~PathCLTrait () {}
};

/// \brief Resample scheme
/// \ingroup Core
enum ResampleScheme {
    MULTINOMIAL,         ///< Multinomial resampling
    RESIDUAL,            ///< Reisudal resampling
    STRATIFIED,          ///< Startified resampling
    SYSTEMATIC,          ///< Systematic resampling
    RESIDUAL_STRATIFIED, ///< Stratified resampling on the residuals
    RESIDUAL_SYSTEMATIC  ///< Systematic resampling on the residuals
}; // enum ResamleScheme

} // namespace vSMC

#endif // V_SMC_INTERNAL_COMMON_HPP
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016 DeepCortex GmbH <legal@eventql.io>
 * Authors:
 *   - Paul Asmuth <paul@eventql.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include "eventql/transport/native/server.h"
#include "eventql/transport/native/connection.h"
#include "eventql/util/logging.h"
#include "eventql/server/session.h"

namespace eventql {
namespace native_transport {

ReturnCode performOperation_META_PERFORMOP(
    Database* database,
    NativeConnection* conn,
    const char* payload,
    size_t payload_size) {
  auto session = database->getSession();
  auto dbctx = session->getDatabaseContext();

  /* check internal */
  if (!session->isInternal()) {
    return conn->sendErrorFrame("internal method called");
  }

  return ReturnCode::success();
}

} // namespace native_transport
} // namespace eventql

<commit_msg>performOperation_META_PERFORMOP<commit_after>/**
 * Copyright (c) 2016 DeepCortex GmbH <legal@eventql.io>
 * Authors:
 *   - Paul Asmuth <paul@eventql.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include "eventql/transport/native/server.h"
#include "eventql/transport/native/connection.h"
#include "eventql/transport/native/frames/meta_performop.h"
#include "eventql/util/logging.h"
#include "eventql/server/session.h"
#include "eventql/db/metadata_service.h"

namespace eventql {
namespace native_transport {

ReturnCode performOperation_META_PERFORMOP(
    Database* database,
    NativeConnection* conn,
    const char* payload,
    size_t payload_size) {
  auto session = database->getSession();
  auto dbctx = session->getDatabaseContext();

  /* check internal */
  if (!session->isInternal()) {
    return conn->sendErrorFrame("internal method called");
  }

  /* parse request */
  MetaPerformopFrame m_frame;
  {
    MemoryInputStream is(payload, payload_size);
    auto rc = m_frame.parseFrom(&is);
    if (!rc.isSuccess()) {
      return conn->sendErrorFrame("invalid frame");
    }
  }

  MetadataOperation op;
  {
    auto is = StringInputStream::fromString(m_frame.getOperation());
    auto rc = op.decode(is.get());
    if (!rc.isSuccess()) {
      return conn->sendErrorFrame("invalid frame");
    }
  }

  /* execute operation */
  MetadataOperationResult result;
  auto rc = dbctx->metadata_service->performMetadataOperation(
      m_frame.getDatabase(),
      m_frame.getTable(),
      op,
      &result);

  /* send response */
  if (rc.isSuccess()) {
    auto payload = *msg::encode(result);

    return conn->sendFrame(
        EVQL_OP_META_PERFORMOP_RESULT,
        EVQL_ENDOFREQUEST,
        payload.data(),
        payload.size());
  } else {
    return conn->sendErrorFrame(rc.message());
  }

  return ReturnCode::success();
}

} // namespace native_transport
} // namespace eventql

<|endoftext|>


<commit_before>#include "entitysystem.h"
#include "systems/movementsystem.h"
#include "systems/updatesystem.h"
#include "systems/chatsystem.h"
#include "systems/inventorysystem.h"
#include "systems/partysystem.h"
#include "systems/mapsystem.h"
#include "connection.h"
#include "cmapclient.h"

#include <vector>
#include <set>

using namespace RoseCommon;
EntitySystem::EntitySystem() : systemManager_(*this) {
    systemManager_.add<Systems::MovementSystem>();
    systemManager_.add<Systems::UpdateSystem>();
    systemManager_.add<Systems::ChatSystem>();
    systemManager_.add<Systems::InventorySystem>();
    systemManager_.add<Systems::PartySystem>();
    systemManager_.add<Systems::MapSystem>();
}

EntityManager &EntitySystem::getEntityManager() {
    return entityManager_;
}

void EntitySystem::registerEntity(Entity entity) {
    if (!entity)
        return;
    auto basic = entity.component<BasicInfo>();
    if (!basic || basic->name_ == "" || !basic->id_)
        return;
    nameToEntity_[basic->name_] = entity;
    idToEntity_[basic->id_] = entity;
}

Entity EntitySystem::getEntity(const std::string &name) {
    return nameToEntity_[name];
}

Entity EntitySystem::getEntity(uint32_t charId) {
    return idToEntity_[charId];
}

void EntitySystem::update(double dt) {
    std::lock_guard<std::mutex> lock(access_);
    while (toDispatch_.size()) {
        auto tmp = std::move(toDispatch_.front());
        systemManager_.dispatch(tmp.first, *tmp.second);
        toDispatch_.pop();
    }
    systemManager_.update(dt);
    for (auto it : toDestroy_) {
        if (it) {
            saveCharacter(it.component<CharacterInfo>()->charId_, it);
          auto basic = it.component<BasicInfo>();
          nameToEntity_.erase(basic->name_);
          idToEntity_.erase(basic->id_);
          it.destroy();
        }
    }
    toDestroy_.clear();
}

void EntitySystem::destroy(Entity entity) {
    if (!entity)
        return;
    std::lock_guard<std::mutex> lock(access_);
    toDestroy_.push_back(entity);
}

Entity EntitySystem::create() {
    return entityManager_.create();
}

bool EntitySystem::isNearby(Entity a, Entity b) {
    return true; // FIXME : actually implement the sight calculation instead of the distance
    if (!a || !b)
        return false;
    auto posa = a.component<Position>();
    auto posb = b.component<Position>();
    if (!posa || !posb)
        return false; // FIXME : is it a bug if there is no position?
    if (posa->map_ != posb->map_)
        return false;
    double dist = (posa->x_ - posb->x_) * (posa->x_ - posb->x_) + (posa->y_ - posb->y_) * (posa->y_ - posb->y_);
    if (dist > NEARBY_DIST)
        return false;
    return true;
}

bool EntitySystem::dispatch(Entity entity, std::unique_ptr<RoseCommon::CRosePacket> packet) {
    if (!entity)
        return false;
    if (systemManager_.wouldDispatch(*packet)) {
        std::lock_guard<std::mutex> lock(access_);
        toDispatch_.emplace(std::make_pair(entity, std::move(packet)));
        return true;
    }
    return false;
}

Entity EntitySystem::loadCharacter(uint32_t charId, bool platinium, uint32_t id) {
    auto conn = Core::connectionPool.getConnection(Core::osirose);
    Core::CharacterTable characters;
    Core::InventoryTable inventoryTable;
    Core::SkillTable skillsTable;

    auto charRes = conn(sqlpp::select(sqlpp::count(characters.id), sqlpp::all_of(characters))
                .from(characters)
                .where(characters.id == charId));

    std::lock_guard<std::mutex> lock(access_);
    auto entity = create();
    if (static_cast<long>(charRes.front().count) != 1L) {
        entity.destroy();
        return Entity();
    }
    const auto &charRow = charRes.front();

    entity.assign<Position>(charRow);
    entity.assign<BasicInfo>(charRow, id);
    entity.assign<Stats>(charRow);
    entity.assign<AdvancedInfo>(charRow);
    entity.assign<CharacterGraphics>(charRow);
    entity.assign<CharacterInfo>(charRow, platinium, charId);

    // TODO : write the pat initialization code
    auto skills = entity.assign<Skills>();
    auto skillRes = conn(sqlpp::select(skillsTable.id, skillsTable.level)
            .from(skillsTable)
            .where(skillsTable.charId == charId));
    skills->loadFromResult(skillRes);

    // TODO : write the hotbar table and loading code
    entity.assign<Hotbar>();
    entity.assign<StatusEffects>();
    entity.assign<RidingItems>();
    entity.assign<BulletItems>();

    // TODO : write the inventory code
    auto inventory = entity.assign<Inventory>();

    auto invRes = conn(sqlpp::select(sqlpp::all_of(inventoryTable))
                .from(inventoryTable)
                .where(inventoryTable.charId == charId));
    inventory->loadFromResult(invRes);

    Systems::UpdateSystem::calculateSpeed(entity);

    entity.assign<Quests>();

    Core::WishTable wish;
    auto wishRes = conn(sqlpp::select(sqlpp::all_of(wish))
                        .from(wish)
                        .where(wish.charId == charId));
    auto wishlist = entity.assign<Wishlist>();
    wishlist->loadFromResult(wishRes);

    registerEntity(entity);
    return entity;
}

void EntitySystem::saveCharacter(uint32_t charId, Entity entity) {
    if (!entity)
        return;
    auto conn = Core::connectionPool.getConnection(Core::osirose);
    Core::CharacterTable characters;

    using sqlpp::parameter;

    auto update = sqlpp::dynamic_update(conn.get(), characters).dynamic_set().where(characters.id == charId);
    entity.component<Position>()->commitToUpdate<decltype(characters)>(update);
    entity.component<BasicInfo>()->commitToUpdate<decltype(characters)>(update);
    entity.component<Stats>()->commitToUpdate<decltype(characters)>(update);
    entity.component<AdvancedInfo>()->commitToUpdate<decltype(characters)>(update);
    //entity.component<CharacterGraphics>()->commitToUpdate(update);
    entity.component<CharacterInfo>()->commitToUpdate<decltype(characters)>(update);
    //entity.component<Hotbar>()->commitToUpdate(update);
    //entity.component<StatusEffects>()->commitToUpdate(update);
    //entity.component<RidingItems>()->commitToUpdate(update);
    //entity.component<BulletItems>()->commitToUpdate(update);

    conn->run(update);

    //entity.component<Skills>()->commitToUpdate(updateSkills);

    Core::InventoryTable inv;
    auto invRes = conn(sqlpp::select(sqlpp::all_of(inv))
                       .from(inv)
                       .where(inv.charId == charId));

    const auto& items = entity.component<Inventory>()->items_;

    std::vector<size_t> toDelete;
    std::vector<size_t> toUpdate;
    std::set<size_t> modified;
    std::vector<size_t> toInsert;

    for (const auto& row : invRes) {
      if (row.slot >= Inventory::maxItems)
        toDelete.emplace_back(row.slot); //FIXME: that should never happen
      else if (!items[row.slot])
        toDelete.emplace_back(row.slot);
      else if (items[row.slot] != Item(row))
        toUpdate.emplace_back(row.slot);
      modified.insert(row.slot);
    }
    size_t i = 0;
    for (const auto& item : items) {
      if (item && modified.find(i) == modified.end())
        toInsert.emplace_back(i);
      ++i;
    }

    for (auto it : toDelete)
      conn(sqlpp::remove_from(inv).where(inv.charId == charId and inv.slot == it));
    for (auto it : toUpdate) {
      auto update = sqlpp::dynamic_update(conn.get(), inv).dynamic_set().where(inv.charId == charId and inv.slot == it);
      items[it].commitToUpdate<decltype(inv)>(update);
      conn->run(update);
    }
    for (auto it : toInsert) {
      auto insert = sqlpp::dynamic_insert_into(conn.get(), inv).dynamic_set();
      items[it].commitToInsert<decltype(inv)>(insert);
      insert.insert_list.add(inv.slot = it);
      insert.insert_list.add(inv.charId = charId);
      conn->run(insert);
    }
}
<commit_msg>Update entitysystem.cpp<commit_after>#include "entitysystem.h"
#include "systems/movementsystem.h"
#include "systems/updatesystem.h"
#include "systems/chatsystem.h"
#include "systems/inventorysystem.h"
#include "systems/partysystem.h"
#include "systems/mapsystem.h"
#include "systems/luasystem.h"
#include "connection.h"
#include "cmapclient.h"

#include <vector>
#include <set>

using namespace RoseCommon;
EntitySystem::EntitySystem() : systemManager_(*this) {
    systemManager_.add<Systems::MovementSystem>();
    systemManager_.add<Systems::UpdateSystem>();
    systemManager_.add<Systems::ChatSystem>();
    systemManager_.add<Systems::InventorySystem>();
    systemManager_.add<Systems::PartySystem>();
    systemManager_.add<Systems::MapSystem>();
    systemManager_.add<Systems::LuaSystem>();
}

EntityManager &EntitySystem::getEntityManager() {
    return entityManager_;
}

void EntitySystem::registerEntity(Entity entity) {
    if (!entity)
        return;
    auto basic = entity.component<BasicInfo>();
    if (!basic || basic->name_ == "" || !basic->id_)
        return;
    nameToEntity_[basic->name_] = entity;
    idToEntity_[basic->id_] = entity;
}

Entity EntitySystem::getEntity(const std::string &name) {
    return nameToEntity_[name];
}

Entity EntitySystem::getEntity(uint32_t charId) {
    return idToEntity_[charId];
}

void EntitySystem::update(double dt) {
    std::lock_guard<std::mutex> lock(access_);
    while (toDispatch_.size()) {
        auto tmp = std::move(toDispatch_.front());
        systemManager_.dispatch(tmp.first, *tmp.second);
        toDispatch_.pop();
    }
    systemManager_.update(dt);
    for (auto it : toDestroy_) {
        if (it) {
            saveCharacter(it.component<CharacterInfo>()->charId_, it);
          auto basic = it.component<BasicInfo>();
          nameToEntity_.erase(basic->name_);
          idToEntity_.erase(basic->id_);
          systemManager_.get<Systems::LuaSystem>()->unregisterEntity(it);
          it.destroy();
        }
    }
    toDestroy_.clear();
}

void EntitySystem::destroy(Entity entity) {
    if (!entity)
        return;
    std::lock_guard<std::mutex> lock(access_);
    toDestroy_.push_back(entity);
}

Entity EntitySystem::create() {
    return entityManager_.create();
}

bool EntitySystem::isNearby(Entity a, Entity b) {
    return true; // FIXME : actually implement the sight calculation instead of the distance
    if (!a || !b)
        return false;
    auto posa = a.component<Position>();
    auto posb = b.component<Position>();
    if (!posa || !posb)
        return false; // FIXME : is it a bug if there is no position?
    if (posa->map_ != posb->map_)
        return false;
    double dist = (posa->x_ - posb->x_) * (posa->x_ - posb->x_) + (posa->y_ - posb->y_) * (posa->y_ - posb->y_);
    if (dist > NEARBY_DIST)
        return false;
    return true;
}

bool EntitySystem::dispatch(Entity entity, std::unique_ptr<RoseCommon::CRosePacket> packet) {
    if (!entity)
        return false;
    if (systemManager_.wouldDispatch(*packet)) {
        std::lock_guard<std::mutex> lock(access_);
        toDispatch_.emplace(std::make_pair(entity, std::move(packet)));
        return true;
    }
    return false;
}

Entity EntitySystem::loadCharacter(uint32_t charId, bool platinium, uint32_t id) {
    auto conn = Core::connectionPool.getConnection(Core::osirose);
    Core::CharacterTable characters;
    Core::InventoryTable inventoryTable;
    Core::SkillTable skillsTable;

    auto charRes = conn(sqlpp::select(sqlpp::count(characters.id), sqlpp::all_of(characters))
                .from(characters)
                .where(characters.id == charId));

    std::lock_guard<std::mutex> lock(access_);
    auto entity = create();
    if (static_cast<long>(charRes.front().count) != 1L) {
        entity.destroy();
        return Entity();
    }
    const auto &charRow = charRes.front();

    entity.assign<Position>(charRow);
    entity.assign<BasicInfo>(charRow, id);
    entity.assign<Stats>(charRow);
    entity.assign<AdvancedInfo>(charRow);
    entity.assign<CharacterGraphics>(charRow);
    entity.assign<CharacterInfo>(charRow, platinium, charId);

    // TODO : write the pat initialization code
    auto skills = entity.assign<Skills>();
    auto skillRes = conn(sqlpp::select(skillsTable.id, skillsTable.level)
            .from(skillsTable)
            .where(skillsTable.charId == charId));
    skills->loadFromResult(skillRes);

    // TODO : write the hotbar table and loading code
    entity.assign<Hotbar>();
    entity.assign<StatusEffects>();
    entity.assign<RidingItems>();
    entity.assign<BulletItems>();

    // TODO : write the inventory code
    auto inventory = entity.assign<Inventory>();

    auto invRes = conn(sqlpp::select(sqlpp::all_of(inventoryTable))
                .from(inventoryTable)
                .where(inventoryTable.charId == charId));
    inventory->loadFromResult(invRes);

    Systems::UpdateSystem::calculateSpeed(entity);

    entity.assign<Quests>();

    Core::WishTable wish;
    auto wishRes = conn(sqlpp::select(sqlpp::all_of(wish))
                        .from(wish)
                        .where(wish.charId == charId));
    auto wishlist = entity.assign<Wishlist>();
    wishlist->loadFromResult(wishRes);

    registerEntity(entity);
    return entity;
}

void EntitySystem::saveCharacter(uint32_t charId, Entity entity) {
    if (!entity)
        return;
    auto conn = Core::connectionPool.getConnection(Core::osirose);
    Core::CharacterTable characters;

    using sqlpp::parameter;

    auto update = sqlpp::dynamic_update(conn.get(), characters).dynamic_set().where(characters.id == charId);
    entity.component<Position>()->commitToUpdate<decltype(characters)>(update);
    entity.component<BasicInfo>()->commitToUpdate<decltype(characters)>(update);
    entity.component<Stats>()->commitToUpdate<decltype(characters)>(update);
    entity.component<AdvancedInfo>()->commitToUpdate<decltype(characters)>(update);
    //entity.component<CharacterGraphics>()->commitToUpdate(update);
    entity.component<CharacterInfo>()->commitToUpdate<decltype(characters)>(update);
    //entity.component<Hotbar>()->commitToUpdate(update);
    //entity.component<StatusEffects>()->commitToUpdate(update);
    //entity.component<RidingItems>()->commitToUpdate(update);
    //entity.component<BulletItems>()->commitToUpdate(update);

    conn->run(update);

    //entity.component<Skills>()->commitToUpdate(updateSkills);

    Core::InventoryTable inv;
    auto invRes = conn(sqlpp::select(sqlpp::all_of(inv))
                       .from(inv)
                       .where(inv.charId == charId));

    const auto& items = entity.component<Inventory>()->items_;

    std::vector<size_t> toDelete;
    std::vector<size_t> toUpdate;
    std::set<size_t> modified;
    std::vector<size_t> toInsert;

    for (const auto& row : invRes) {
      if (row.slot >= Inventory::maxItems)
        toDelete.emplace_back(row.slot); //FIXME: that should never happen
      else if (!items[row.slot])
        toDelete.emplace_back(row.slot);
      else if (items[row.slot] != Item(row))
        toUpdate.emplace_back(row.slot);
      modified.insert(row.slot);
    }
    size_t i = 0;
    for (const auto& item : items) {
      if (item && modified.find(i) == modified.end())
        toInsert.emplace_back(i);
      ++i;
    }

    for (auto it : toDelete)
      conn(sqlpp::remove_from(inv).where(inv.charId == charId and inv.slot == it));
    for (auto it : toUpdate) {
      auto update = sqlpp::dynamic_update(conn.get(), inv).dynamic_set().where(inv.charId == charId and inv.slot == it);
      items[it].commitToUpdate<decltype(inv)>(update);
      conn->run(update);
    }
    for (auto it : toInsert) {
      auto insert = sqlpp::dynamic_insert_into(conn.get(), inv).dynamic_set();
      items[it].commitToInsert<decltype(inv)>(insert);
      insert.insert_list.add(inv.slot = it);
      insert.insert_list.add(inv.charId = charId);
      conn->run(insert);
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013,2016-2018 ARM Limited
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * 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 of conditions 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 materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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
 * OWNER 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.
 *
 * Authors: Erik Hallnor
 *          Nikos Nikoleris
 */

/**
 * @file
 * Definitions a fully associative LRU tagstore.
 */

#include "mem/cache/tags/fa_lru.hh"

#include <cassert>
#include <sstream>

#include "base/intmath.hh"
#include "base/logging.hh"

FALRU::FALRU(const Params *p)
    : BaseTags(p),

      cacheTracking(p->min_tracked_cache_size, size, blkSize)
{
    if (!isPowerOf2(blkSize))
        fatal("cache block size (in bytes) `%d' must be a power of two",
              blkSize);
    if (!isPowerOf2(size))
        fatal("Cache Size must be power of 2 for now");

    blks = new FALRUBlk[numBlocks];

    head = &(blks[0]);
    head->prev = nullptr;
    head->next = &(blks[1]);
    head->set = 0;
    head->way = 0;
    head->data = &dataBlks[0];

    for (unsigned i = 1; i < numBlocks - 1; i++) {
        blks[i].prev = &(blks[i-1]);
        blks[i].next = &(blks[i+1]);
        blks[i].set = 0;
        blks[i].way = i;

        // Associate a data chunk to the block
        blks[i].data = &dataBlks[blkSize*i];
    }

    tail = &(blks[numBlocks - 1]);
    tail->prev = &(blks[numBlocks - 2]);
    tail->next = nullptr;
    tail->set = 0;
    tail->way = numBlocks - 1;
    tail->data = &dataBlks[(numBlocks - 1) * blkSize];

    cacheTracking.init(head, tail);
}

FALRU::~FALRU()
{
    delete[] blks;
}

void
FALRU::regStats()
{
    BaseTags::regStats();
    cacheTracking.regStats(name());
}

FALRUBlk *
FALRU::hashLookup(Addr addr) const
{
    tagIterator iter = tagHash.find(addr);
    if (iter != tagHash.end()) {
        return (*iter).second;
    }
    return nullptr;
}

void
FALRU::invalidate(CacheBlk *blk)
{
    BaseTags::invalidate(blk);

    // Move the block to the tail to make it the next victim
    moveToTail((FALRUBlk*)blk);

    // Erase block entry in the hash table
    tagHash.erase(blk->tag);
}

CacheBlk*
FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat)
{
    return accessBlock(addr, is_secure, lat, 0);
}

CacheBlk*
FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat,
                   CachesMask *in_caches_mask)
{
    CachesMask mask = 0;
    Addr blkAddr = blkAlign(addr);
    FALRUBlk* blk = hashLookup(blkAddr);

    if (blk && blk->isValid()) {
        // If a cache hit
        lat = accessLatency;
        // Check if the block to be accessed is available. If not,
        // apply the accessLatency on top of block->whenReady.
        if (blk->whenReady > curTick() &&
            cache->ticksToCycles(blk->whenReady - curTick()) >
            accessLatency) {
            lat = cache->ticksToCycles(blk->whenReady - curTick()) +
            accessLatency;
        }
        assert(blk->tag == blkAddr);
        mask = blk->inCachesMask;
        moveToHead(blk);
    } else {
        // If a cache miss
        lat = lookupLatency;
        blk = nullptr;
    }
    if (in_caches_mask) {
        *in_caches_mask = mask;
    }

    cacheTracking.recordAccess(blk);

    return blk;
}

CacheBlk*
FALRU::findBlock(Addr addr, bool is_secure) const
{
    Addr blkAddr = blkAlign(addr);
    FALRUBlk* blk = hashLookup(blkAddr);

    if (blk && blk->isValid()) {
        assert(blk->tag == blkAddr);
    } else {
        blk = nullptr;
    }
    return blk;
}

CacheBlk*
FALRU::findBlockBySetAndWay(int set, int way) const
{
    assert(set == 0);
    return &blks[way];
}

CacheBlk*
FALRU::findVictim(Addr addr)
{
    return tail;
}

void
FALRU::insertBlock(PacketPtr pkt, CacheBlk *blk)
{
    FALRUBlk* falruBlk = static_cast<FALRUBlk*>(blk);

    // Make sure block is not present in the cache
    assert(falruBlk->inCachesMask == 0);

    // Do common block insertion functionality
    BaseTags::insertBlock(pkt, blk);

    // New block is the MRU
    moveToHead(falruBlk);

    // Insert new block in the hash table
    tagHash[falruBlk->tag] = falruBlk;
}

void
FALRU::moveToHead(FALRUBlk *blk)
{
    // If block is not already head, do the moving
    if (blk != head) {
        cacheTracking.moveBlockToHead(blk);
        // If block is tail, set previous block as new tail
        if (blk == tail){
            assert(blk->next == nullptr);
            tail = blk->prev;
            tail->next = nullptr;
        // Inform block's surrounding blocks that it has been moved
        } else {
            blk->prev->next = blk->next;
            blk->next->prev = blk->prev;
        }

        // Swap pointers
        blk->next = head;
        blk->prev = nullptr;
        head->prev = blk;
        head = blk;

        cacheTracking.check(head, tail);
    }
}

void
FALRU::moveToTail(FALRUBlk *blk)
{
    // If block is not already tail, do the moving
    if (blk != tail) {
        cacheTracking.moveBlockToTail(blk);
        // If block is head, set next block as new head
        if (blk == head){
            assert(blk->prev == nullptr);
            head = blk->next;
            head->prev = nullptr;
        // Inform block's surrounding blocks that it has been moved
        } else {
            blk->prev->next = blk->next;
            blk->next->prev = blk->prev;
        }

        // Swap pointers
        blk->prev = tail;
        blk->next = nullptr;
        tail->next = blk;
        tail = blk;

        cacheTracking.check(head, tail);
    }
}

FALRU *
FALRUParams::create()
{
    return new FALRU(this);
}

void
FALRU::CacheTracking::check(FALRUBlk *head, FALRUBlk *tail)
{
#ifdef FALRU_DEBUG
    FALRUBlk* blk = head;
    unsigned curr_size = 0;
    unsigned tracked_cache_size = minTrackedSize;
    CachesMask in_caches_mask = inAllCachesMask;
    int j = 0;

    while (blk) {
        panic_if(blk->inCachesMask != in_caches_mask, "Expected cache mask "
                 "%x found %x", blk->inCachesMask, in_caches_mask);

        curr_size += blkSize;
        if (curr_size == tracked_cache_size && blk != tail) {
            panic_if(boundaries[j] != blk, "Unexpected boundary for the %d-th "
                     "cache", j);
            tracked_cache_size <<= 1;
            // from this point, blocks fit only in the larger caches
            in_caches_mask &= ~(1U << j);
            ++j;
        }
        blk = blk->next;
    }
#endif // FALRU_DEBUG
}

void
FALRU::CacheTracking::init(FALRUBlk *head, FALRUBlk *tail)
{
    // early exit if we are not tracking any extra caches
    FALRUBlk* blk = numTrackedCaches ? head : nullptr;
    unsigned curr_size = 0;
    unsigned tracked_cache_size = minTrackedSize;
    CachesMask in_caches_mask = inAllCachesMask;
    int j = 0;

    while (blk) {
        blk->inCachesMask = in_caches_mask;

        curr_size += blkSize;
        if (curr_size == tracked_cache_size && blk != tail) {
            boundaries[j] = blk;

            tracked_cache_size <<= 1;
            // from this point, blocks fit only in the larger caches
            in_caches_mask &= ~(1U << j);
            ++j;
        }
        blk = blk->next;
    }
}

void
FALRU::CacheTracking::moveBlockToHead(FALRUBlk *blk)
{
    // Get the mask of all caches, in which the block didn't fit
    // before moving it to the head
    CachesMask update_caches_mask = inAllCachesMask ^ blk->inCachesMask;

    for (int i = 0; i < numTrackedCaches; i++) {
        CachesMask current_cache_mask = 1U << i;
        if (current_cache_mask & update_caches_mask) {
            // if the ith cache didn't fit the block (before it is moved to
            // the head), move the ith boundary 1 block closer to the
            // MRU
            boundaries[i]->inCachesMask &= ~current_cache_mask;
            boundaries[i] = boundaries[i]->prev;
        } else if (boundaries[i] == blk) {
            // Make sure the boundary doesn't point to the block
            // we are about to move
            boundaries[i] = blk->prev;
        }
    }

    // Make block reside in all caches
    blk->inCachesMask = inAllCachesMask;
}

void
FALRU::CacheTracking::moveBlockToTail(FALRUBlk *blk)
{
    CachesMask update_caches_mask = blk->inCachesMask;

    for (int i = 0; i < numTrackedCaches; i++) {
        CachesMask current_cache_mask = 1U << i;
        if (current_cache_mask & update_caches_mask) {
            // if the ith cache fitted the block (before it is moved to
            // the tail), move the ith boundary 1 block closer to the
            // LRU
            boundaries[i] = boundaries[i]->next;
            if (boundaries[i] == blk) {
                // Make sure the boundary doesn't point to the block
                // we are about to move
                boundaries[i] = blk->next;
            }
            boundaries[i]->inCachesMask |= current_cache_mask;
        }
    }

    // The block now fits only in the actual cache
    blk->inCachesMask = 0;
}

void
FALRU::CacheTracking::recordAccess(FALRUBlk *blk)
{
    for (int i = 0; i < numTrackedCaches; i++) {
        if (blk && ((1U << i) & blk->inCachesMask)) {
            hits[i]++;
        } else {
            misses[i]++;
        }
    }

    // Record stats for the actual cache too
    if (blk) {
        hits[numTrackedCaches]++;
    } else {
        misses[numTrackedCaches]++;
    }

    accesses++;
}

void
printSize(std::ostream &stream, size_t size)
{
    static const char *SIZES[] = { "B", "kB", "MB", "GB", "TB", "ZB" };
    int div = 0;
    while (size >= 1024 && div < (sizeof SIZES / sizeof *SIZES)) {
        div++;
        size >>= 10;
    }
    stream << size << SIZES[div];
}

void
FALRU::CacheTracking::regStats(std::string name)
{
    hits
        .init(numTrackedCaches + 1)
        .name(name + ".falru_hits")
        .desc("The number of hits in each cache size.")
        ;
    misses
        .init(numTrackedCaches + 1)
        .name(name + ".falru_misses")
        .desc("The number of misses in each cache size.")
        ;
    accesses
        .name(name + ".falru_accesses")
        .desc("The number of accesses to the FA LRU cache.")
        ;

    for (unsigned i = 0; i < numTrackedCaches + 1; ++i) {
        std::stringstream size_str;
        printSize(size_str, minTrackedSize << i);
        hits.subname(i, size_str.str());
        hits.subdesc(i, "Hits in a " + size_str.str() + " cache");
        misses.subname(i, size_str.str());
        misses.subdesc(i, "Misses in a " + size_str.str() + " cache");
    }
}
<commit_msg>mem-cache: Use secure flag in FALRU's findBlock<commit_after>/*
 * Copyright (c) 2013,2016-2018 ARM Limited
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * 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 of conditions 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 materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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
 * OWNER 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.
 *
 * Authors: Erik Hallnor
 *          Nikos Nikoleris
 */

/**
 * @file
 * Definitions a fully associative LRU tagstore.
 */

#include "mem/cache/tags/fa_lru.hh"

#include <cassert>
#include <sstream>

#include "base/intmath.hh"
#include "base/logging.hh"

FALRU::FALRU(const Params *p)
    : BaseTags(p),

      cacheTracking(p->min_tracked_cache_size, size, blkSize)
{
    if (!isPowerOf2(blkSize))
        fatal("cache block size (in bytes) `%d' must be a power of two",
              blkSize);
    if (!isPowerOf2(size))
        fatal("Cache Size must be power of 2 for now");

    blks = new FALRUBlk[numBlocks];

    head = &(blks[0]);
    head->prev = nullptr;
    head->next = &(blks[1]);
    head->set = 0;
    head->way = 0;
    head->data = &dataBlks[0];

    for (unsigned i = 1; i < numBlocks - 1; i++) {
        blks[i].prev = &(blks[i-1]);
        blks[i].next = &(blks[i+1]);
        blks[i].set = 0;
        blks[i].way = i;

        // Associate a data chunk to the block
        blks[i].data = &dataBlks[blkSize*i];
    }

    tail = &(blks[numBlocks - 1]);
    tail->prev = &(blks[numBlocks - 2]);
    tail->next = nullptr;
    tail->set = 0;
    tail->way = numBlocks - 1;
    tail->data = &dataBlks[(numBlocks - 1) * blkSize];

    cacheTracking.init(head, tail);
}

FALRU::~FALRU()
{
    delete[] blks;
}

void
FALRU::regStats()
{
    BaseTags::regStats();
    cacheTracking.regStats(name());
}

FALRUBlk *
FALRU::hashLookup(Addr addr) const
{
    tagIterator iter = tagHash.find(addr);
    if (iter != tagHash.end()) {
        return (*iter).second;
    }
    return nullptr;
}

void
FALRU::invalidate(CacheBlk *blk)
{
    BaseTags::invalidate(blk);

    // Move the block to the tail to make it the next victim
    moveToTail((FALRUBlk*)blk);

    // Erase block entry in the hash table
    tagHash.erase(blk->tag);
}

CacheBlk*
FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat)
{
    return accessBlock(addr, is_secure, lat, 0);
}

CacheBlk*
FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat,
                   CachesMask *in_caches_mask)
{
    CachesMask mask = 0;
    Addr blkAddr = blkAlign(addr);
    FALRUBlk* blk = hashLookup(blkAddr);

    if (blk && blk->isValid()) {
        // If a cache hit
        lat = accessLatency;
        // Check if the block to be accessed is available. If not,
        // apply the accessLatency on top of block->whenReady.
        if (blk->whenReady > curTick() &&
            cache->ticksToCycles(blk->whenReady - curTick()) >
            accessLatency) {
            lat = cache->ticksToCycles(blk->whenReady - curTick()) +
            accessLatency;
        }
        assert(blk->tag == blkAddr);
        mask = blk->inCachesMask;
        moveToHead(blk);
    } else {
        // If a cache miss
        lat = lookupLatency;
        blk = nullptr;
    }
    if (in_caches_mask) {
        *in_caches_mask = mask;
    }

    cacheTracking.recordAccess(blk);

    return blk;
}

CacheBlk*
FALRU::findBlock(Addr addr, bool is_secure) const
{
    Addr blkAddr = blkAlign(addr);
    FALRUBlk* blk = hashLookup(blkAddr);

    if (blk && blk->isValid()) {
        assert(blk->tag == blkAddr);
        assert(blk->isSecure() == is_secure);
    } else {
        blk = nullptr;
    }
    return blk;
}

CacheBlk*
FALRU::findBlockBySetAndWay(int set, int way) const
{
    assert(set == 0);
    return &blks[way];
}

CacheBlk*
FALRU::findVictim(Addr addr)
{
    return tail;
}

void
FALRU::insertBlock(PacketPtr pkt, CacheBlk *blk)
{
    FALRUBlk* falruBlk = static_cast<FALRUBlk*>(blk);

    // Make sure block is not present in the cache
    assert(falruBlk->inCachesMask == 0);

    // Do common block insertion functionality
    BaseTags::insertBlock(pkt, blk);

    // New block is the MRU
    moveToHead(falruBlk);

    // Insert new block in the hash table
    tagHash[falruBlk->tag] = falruBlk;
}

void
FALRU::moveToHead(FALRUBlk *blk)
{
    // If block is not already head, do the moving
    if (blk != head) {
        cacheTracking.moveBlockToHead(blk);
        // If block is tail, set previous block as new tail
        if (blk == tail){
            assert(blk->next == nullptr);
            tail = blk->prev;
            tail->next = nullptr;
        // Inform block's surrounding blocks that it has been moved
        } else {
            blk->prev->next = blk->next;
            blk->next->prev = blk->prev;
        }

        // Swap pointers
        blk->next = head;
        blk->prev = nullptr;
        head->prev = blk;
        head = blk;

        cacheTracking.check(head, tail);
    }
}

void
FALRU::moveToTail(FALRUBlk *blk)
{
    // If block is not already tail, do the moving
    if (blk != tail) {
        cacheTracking.moveBlockToTail(blk);
        // If block is head, set next block as new head
        if (blk == head){
            assert(blk->prev == nullptr);
            head = blk->next;
            head->prev = nullptr;
        // Inform block's surrounding blocks that it has been moved
        } else {
            blk->prev->next = blk->next;
            blk->next->prev = blk->prev;
        }

        // Swap pointers
        blk->prev = tail;
        blk->next = nullptr;
        tail->next = blk;
        tail = blk;

        cacheTracking.check(head, tail);
    }
}

FALRU *
FALRUParams::create()
{
    return new FALRU(this);
}

void
FALRU::CacheTracking::check(FALRUBlk *head, FALRUBlk *tail)
{
#ifdef FALRU_DEBUG
    FALRUBlk* blk = head;
    unsigned curr_size = 0;
    unsigned tracked_cache_size = minTrackedSize;
    CachesMask in_caches_mask = inAllCachesMask;
    int j = 0;

    while (blk) {
        panic_if(blk->inCachesMask != in_caches_mask, "Expected cache mask "
                 "%x found %x", blk->inCachesMask, in_caches_mask);

        curr_size += blkSize;
        if (curr_size == tracked_cache_size && blk != tail) {
            panic_if(boundaries[j] != blk, "Unexpected boundary for the %d-th "
                     "cache", j);
            tracked_cache_size <<= 1;
            // from this point, blocks fit only in the larger caches
            in_caches_mask &= ~(1U << j);
            ++j;
        }
        blk = blk->next;
    }
#endif // FALRU_DEBUG
}

void
FALRU::CacheTracking::init(FALRUBlk *head, FALRUBlk *tail)
{
    // early exit if we are not tracking any extra caches
    FALRUBlk* blk = numTrackedCaches ? head : nullptr;
    unsigned curr_size = 0;
    unsigned tracked_cache_size = minTrackedSize;
    CachesMask in_caches_mask = inAllCachesMask;
    int j = 0;

    while (blk) {
        blk->inCachesMask = in_caches_mask;

        curr_size += blkSize;
        if (curr_size == tracked_cache_size && blk != tail) {
            boundaries[j] = blk;

            tracked_cache_size <<= 1;
            // from this point, blocks fit only in the larger caches
            in_caches_mask &= ~(1U << j);
            ++j;
        }
        blk = blk->next;
    }
}

void
FALRU::CacheTracking::moveBlockToHead(FALRUBlk *blk)
{
    // Get the mask of all caches, in which the block didn't fit
    // before moving it to the head
    CachesMask update_caches_mask = inAllCachesMask ^ blk->inCachesMask;

    for (int i = 0; i < numTrackedCaches; i++) {
        CachesMask current_cache_mask = 1U << i;
        if (current_cache_mask & update_caches_mask) {
            // if the ith cache didn't fit the block (before it is moved to
            // the head), move the ith boundary 1 block closer to the
            // MRU
            boundaries[i]->inCachesMask &= ~current_cache_mask;
            boundaries[i] = boundaries[i]->prev;
        } else if (boundaries[i] == blk) {
            // Make sure the boundary doesn't point to the block
            // we are about to move
            boundaries[i] = blk->prev;
        }
    }

    // Make block reside in all caches
    blk->inCachesMask = inAllCachesMask;
}

void
FALRU::CacheTracking::moveBlockToTail(FALRUBlk *blk)
{
    CachesMask update_caches_mask = blk->inCachesMask;

    for (int i = 0; i < numTrackedCaches; i++) {
        CachesMask current_cache_mask = 1U << i;
        if (current_cache_mask & update_caches_mask) {
            // if the ith cache fitted the block (before it is moved to
            // the tail), move the ith boundary 1 block closer to the
            // LRU
            boundaries[i] = boundaries[i]->next;
            if (boundaries[i] == blk) {
                // Make sure the boundary doesn't point to the block
                // we are about to move
                boundaries[i] = blk->next;
            }
            boundaries[i]->inCachesMask |= current_cache_mask;
        }
    }

    // The block now fits only in the actual cache
    blk->inCachesMask = 0;
}

void
FALRU::CacheTracking::recordAccess(FALRUBlk *blk)
{
    for (int i = 0; i < numTrackedCaches; i++) {
        if (blk && ((1U << i) & blk->inCachesMask)) {
            hits[i]++;
        } else {
            misses[i]++;
        }
    }

    // Record stats for the actual cache too
    if (blk) {
        hits[numTrackedCaches]++;
    } else {
        misses[numTrackedCaches]++;
    }

    accesses++;
}

void
printSize(std::ostream &stream, size_t size)
{
    static const char *SIZES[] = { "B", "kB", "MB", "GB", "TB", "ZB" };
    int div = 0;
    while (size >= 1024 && div < (sizeof SIZES / sizeof *SIZES)) {
        div++;
        size >>= 10;
    }
    stream << size << SIZES[div];
}

void
FALRU::CacheTracking::regStats(std::string name)
{
    hits
        .init(numTrackedCaches + 1)
        .name(name + ".falru_hits")
        .desc("The number of hits in each cache size.")
        ;
    misses
        .init(numTrackedCaches + 1)
        .name(name + ".falru_misses")
        .desc("The number of misses in each cache size.")
        ;
    accesses
        .name(name + ".falru_accesses")
        .desc("The number of accesses to the FA LRU cache.")
        ;

    for (unsigned i = 0; i < numTrackedCaches + 1; ++i) {
        std::stringstream size_str;
        printSize(size_str, minTrackedSize << i);
        hits.subname(i, size_str.str());
        hits.subdesc(i, "Hits in a " + size_str.str() + " cache");
        misses.subname(i, size_str.str());
        misses.subdesc(i, "Misses in a " + size_str.str() + " cache");
    }
}
<|endoftext|>


<commit_before>/*
 * This file is part of the UnTech Editor Suite.
 * Copyright (c) 2016 - 2018, Marcus Rowe <undisbeliever@gmail.com>.
 * Distributed under The MIT License: https://opensource.org/licenses/MIT
 */

#include "multipleselectiontableview.h"
#include "abstractaccessors.h"
#include "accessor.h"
#include "listaccessortablemanager.h"
#include "gui-qt/common/properties/propertydelegate.h"
#include "gui-qt/common/properties/propertytablemodel.h"

#include <QContextMenuEvent>
#include <QCoreApplication>
#include <QIcon>
#include <QLocale>
#include <QMenu>

using namespace UnTech;
using namespace UnTech::GuiQt::Accessor;

MultipleSelectionTableView::MultipleSelectionTableView(QWidget* parent)
    : QTreeView(parent)
    , _actions(new MultiListActions(this))
    , _delegate(new PropertyDelegate(this))
    , _selectedContextMenu(new QMenu(this))
    , _noSelectionContextMenu(new QMenu(this))
    , _model(nullptr)
    , _accessors()
{
    setItemDelegate(_delegate);

    setEditTriggers(EditTrigger::AllEditTriggers);

    setSelectionMode(SelectionMode::ExtendedSelection);
    setSelectionBehavior(SelectionBehavior::SelectRows);

    rebuildMenus();
}

void MultipleSelectionTableView::setPropertyManagers(const QList<ListAccessorTableManager*>& managers,
                                                     const QStringList& columns)
{
    if (auto* sm = selectionModel()) {
        sm->deleteLater();
    }
    if (_model) {
        _model->deleteLater();

        for (auto* m : _model->managers()) {
            m->disconnect(this);
        }
    }

    if (!managers.isEmpty()) {
        QList<GuiQt::PropertyTableManager*> pManagers;
        pManagers.reserve(managers.size());
        for (auto* m : managers) {
            pManagers.append(m);
        }
        _model = new PropertyTableModel(pManagers, columns, this);
    }
    else {
        _model = nullptr;
    }
    QTreeView::setModel(_model);

    _actions->setNAccessors(managers.size());

    onAccessorsChanged();

    rebuildMenus();

    if (_model) {
        connect(this->selectionModel(), &QItemSelectionModel::selectionChanged,
                this, &MultipleSelectionTableView::onViewSelectionChanged);
    }
    for (auto* manager : managers) {
        connect(manager, &ListAccessorTableManager::accessorChanged,
                this, &MultipleSelectionTableView::onAccessorsChanged);
    }
}

void MultipleSelectionTableView::onAccessorsChanged()
{
    auto newAccessors = buildAccessorsList();

    if (_accessors.empty() && newAccessors.empty()) {
        return;
    }

    for (auto* a : _accessors) {
        a->disconnect(this);
    }
    _accessors = newAccessors;

    _actions->setAccessors(_accessors);
    onAccessorSelectedIndexesChanged();

    for (auto* a : newAccessors) {
        connect(a, &AbstractListMultipleSelectionAccessor::selectedIndexesChanged,
                this, &MultipleSelectionTableView::onAccessorSelectedIndexesChanged);
    }
}

QList<AbstractListMultipleSelectionAccessor*> MultipleSelectionTableView::buildAccessorsList()
{
    QList<AbstractListMultipleSelectionAccessor*> ret;

    if (_model == nullptr) {
        return ret;
    }

    const auto& managers = _model->managers();
    ret.reserve(managers.size());

    for (auto* manager : managers) {
        auto* laManager = qobject_cast<ListAccessorTableManager*>(manager);
        auto* accessor = laManager ? laManager->accessor() : nullptr;
        auto* multiSelectionAccessor = qobject_cast<AbstractListMultipleSelectionAccessor*>(accessor);

        if (multiSelectionAccessor == nullptr) {
            ret.clear();
            break;
        }
        ret.append(multiSelectionAccessor);
    }

    return ret;
}

void MultipleSelectionTableView::onAccessorSelectedIndexesChanged()
{
    QItemSelection sel;

    for (int aId = 0; aId < _accessors.size(); aId++) {
        if (auto* accessor = _accessors.at(aId)) {
            for (auto si : accessor->selectedIndexes()) {
                QModelIndex index = _model->toModelIndex(aId, si);
                if (index.isValid()) {
                    sel.select(index, index);
                }
            }
        }
    }
    selectionModel()->select(
        sel, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);

    // BUGFIX: Sometimes the view will not hightlight the new selection
    viewport()->update();
}

void MultipleSelectionTableView::onViewSelectionChanged()
{
    const auto selectedRows = selectionModel()->selectedRows();

    for (int aId = 0; aId < _accessors.size(); aId++) {
        if (auto* accessor = _accessors.at(aId)) {
            std::vector<size_t> selected;
            selected.reserve(selectedRows.size());

            for (const auto& index : selectedRows) {
                auto mi = _model->toManagerIdAndIndex(index);
                if (mi.first == aId) {
                    selected.push_back(mi.second);
                }
            }
            accessor->setSelectedIndexes(std::move(selected));
        }
    }
}

void MultipleSelectionTableView::setModel(QAbstractItemModel*)
{
    qCritical("Must not call setModel in MultipleSelectionTableView.");
}

void MultipleSelectionTableView::rebuildMenus()
{
    _selectedContextMenu->clear();
    _noSelectionContextMenu->clear();

    _actions->populateMenu(_selectedContextMenu, true);
    _actions->populateMenuWithAddActions(_noSelectionContextMenu);
}

void MultipleSelectionTableView::contextMenuEvent(QContextMenuEvent* event)
{
    if (_model == nullptr) {
        return;
    }

    if (_actions->remove->isEnabled()) {
        _selectedContextMenu->exec(event->globalPos());
    }
    else {
        _noSelectionContextMenu->exec(event->globalPos());
    }
}
<commit_msg>Change MultipleSelectionTableView settings to match ListAccessorTableView<commit_after>/*
 * This file is part of the UnTech Editor Suite.
 * Copyright (c) 2016 - 2018, Marcus Rowe <undisbeliever@gmail.com>.
 * Distributed under The MIT License: https://opensource.org/licenses/MIT
 */

#include "multipleselectiontableview.h"
#include "abstractaccessors.h"
#include "accessor.h"
#include "listaccessortablemanager.h"
#include "gui-qt/common/properties/propertydelegate.h"
#include "gui-qt/common/properties/propertytablemodel.h"

#include <QContextMenuEvent>
#include <QCoreApplication>
#include <QIcon>
#include <QLocale>
#include <QMenu>

using namespace UnTech;
using namespace UnTech::GuiQt::Accessor;

MultipleSelectionTableView::MultipleSelectionTableView(QWidget* parent)
    : QTreeView(parent)
    , _actions(new MultiListActions(this))
    , _delegate(new PropertyDelegate(this))
    , _selectedContextMenu(new QMenu(this))
    , _noSelectionContextMenu(new QMenu(this))
    , _model(nullptr)
    , _accessors()
{
    setItemDelegate(_delegate);

    setDragDropMode(QTreeView::InternalMove);

    setEditTriggers(EditTriggers(AllEditTriggers).setFlag(CurrentChanged, false));
    setAlternatingRowColors(true);

    setSelectionMode(SelectionMode::ExtendedSelection);
    setSelectionBehavior(SelectionBehavior::SelectRows);

    rebuildMenus();
}

void MultipleSelectionTableView::setPropertyManagers(const QList<ListAccessorTableManager*>& managers,
                                                     const QStringList& columns)
{
    if (auto* sm = selectionModel()) {
        sm->deleteLater();
    }
    if (_model) {
        _model->deleteLater();

        for (auto* m : _model->managers()) {
            m->disconnect(this);
        }
    }

    if (!managers.isEmpty()) {
        QList<GuiQt::PropertyTableManager*> pManagers;
        pManagers.reserve(managers.size());
        for (auto* m : managers) {
            pManagers.append(m);
        }
        _model = new PropertyTableModel(pManagers, columns, this);
    }
    else {
        _model = nullptr;
    }
    QTreeView::setModel(_model);

    _actions->setNAccessors(managers.size());

    onAccessorsChanged();

    rebuildMenus();

    if (_model) {
        connect(this->selectionModel(), &QItemSelectionModel::selectionChanged,
                this, &MultipleSelectionTableView::onViewSelectionChanged);
    }
    for (auto* manager : managers) {
        connect(manager, &ListAccessorTableManager::accessorChanged,
                this, &MultipleSelectionTableView::onAccessorsChanged);
    }
}

void MultipleSelectionTableView::onAccessorsChanged()
{
    auto newAccessors = buildAccessorsList();

    if (_accessors.empty() && newAccessors.empty()) {
        return;
    }

    for (auto* a : _accessors) {
        a->disconnect(this);
    }
    _accessors = newAccessors;

    _actions->setAccessors(_accessors);
    onAccessorSelectedIndexesChanged();

    for (auto* a : newAccessors) {
        connect(a, &AbstractListMultipleSelectionAccessor::selectedIndexesChanged,
                this, &MultipleSelectionTableView::onAccessorSelectedIndexesChanged);
    }
}

QList<AbstractListMultipleSelectionAccessor*> MultipleSelectionTableView::buildAccessorsList()
{
    QList<AbstractListMultipleSelectionAccessor*> ret;

    if (_model == nullptr) {
        return ret;
    }

    const auto& managers = _model->managers();
    ret.reserve(managers.size());

    for (auto* manager : managers) {
        auto* laManager = qobject_cast<ListAccessorTableManager*>(manager);
        auto* accessor = laManager ? laManager->accessor() : nullptr;
        auto* multiSelectionAccessor = qobject_cast<AbstractListMultipleSelectionAccessor*>(accessor);

        if (multiSelectionAccessor == nullptr) {
            ret.clear();
            break;
        }
        ret.append(multiSelectionAccessor);
    }

    return ret;
}

void MultipleSelectionTableView::onAccessorSelectedIndexesChanged()
{
    QItemSelection sel;

    for (int aId = 0; aId < _accessors.size(); aId++) {
        if (auto* accessor = _accessors.at(aId)) {
            for (auto si : accessor->selectedIndexes()) {
                QModelIndex index = _model->toModelIndex(aId, si);
                if (index.isValid()) {
                    sel.select(index, index);
                }
            }
        }
    }
    selectionModel()->select(
        sel, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);

    // BUGFIX: Sometimes the view will not hightlight the new selection
    viewport()->update();
}

void MultipleSelectionTableView::onViewSelectionChanged()
{
    const auto selectedRows = selectionModel()->selectedRows();

    for (int aId = 0; aId < _accessors.size(); aId++) {
        if (auto* accessor = _accessors.at(aId)) {
            std::vector<size_t> selected;
            selected.reserve(selectedRows.size());

            for (const auto& index : selectedRows) {
                auto mi = _model->toManagerIdAndIndex(index);
                if (mi.first == aId) {
                    selected.push_back(mi.second);
                }
            }
            accessor->setSelectedIndexes(std::move(selected));
        }
    }
}

void MultipleSelectionTableView::setModel(QAbstractItemModel*)
{
    qCritical("Must not call setModel in MultipleSelectionTableView.");
}

void MultipleSelectionTableView::rebuildMenus()
{
    _selectedContextMenu->clear();
    _noSelectionContextMenu->clear();

    _actions->populateMenu(_selectedContextMenu, true);
    _actions->populateMenuWithAddActions(_noSelectionContextMenu);
}

void MultipleSelectionTableView::contextMenuEvent(QContextMenuEvent* event)
{
    if (_model == nullptr) {
        return;
    }

    if (_actions->remove->isEnabled()) {
        _selectedContextMenu->exec(event->globalPos());
    }
    else {
        _noSelectionContextMenu->exec(event->globalPos());
    }
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2015-2017 Advanced Micro Devices, Inc. All rights reserved.

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.
*/

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp
 * RUN: %t
 * HIT_END
 */

#include"test_common.h"

struct {
  float a;
  int b;
  void *c;
} Struct ;

int main(){
  int *iPtr;
  float *fPtr;
  struct Struct *sPtr;
  size_t sSetSize = 1024, sGetSize;
  hipMalloc(&iPtr, sSetSize);
  hipMalloc(&fPtr, sSetSize);
  hipMalloc(&sPtr, sSetSize);
  hipMemPtrGetInfo(iPtr, &sGetSize);
  assert(sGetSize == sSetSize);
  hipMemPtrGetInfo(fPtr, &sGetSize);
  assert(sGetSize == sSetSize);
  hipMemPtrGetInfo(sPtr, &sGetSize);
  assert(sGetSize == sSetSize);
  passed();
}
<commit_msg>Disable hipMemPtrGetInfo test on nvcc path<commit_after>/*
Copyright (c) 2015-2017 Advanced Micro Devices, Inc. All rights reserved.

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.
*/

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp EXCLUDE_HIP_PLATFORM nvcc
 * RUN: %t
 * HIT_END
 */

#include"test_common.h"

struct {
  float a;
  int b;
  void *c;
} Struct ;

int main(){
  int *iPtr;
  float *fPtr;
  struct Struct *sPtr;
  size_t sSetSize = 1024, sGetSize;
  hipMalloc(&iPtr, sSetSize);
  hipMalloc(&fPtr, sSetSize);
  hipMalloc(&sPtr, sSetSize);
  hipMemPtrGetInfo(iPtr, &sGetSize);
  assert(sGetSize == sSetSize);
  hipMemPtrGetInfo(fPtr, &sGetSize);
  assert(sGetSize == sSetSize);
  hipMemPtrGetInfo(sPtr, &sGetSize);
  assert(sGetSize == sSetSize);
  passed();
}
<|endoftext|>


<commit_before>//===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===//
//
// This utility provides a way to execute LLVM bytecode without static
// compilation.  This consists of a very simple and slow (but portable)
// interpreter, along with capability for system specific dynamic compilers.  At
// runtime, the fastest (stable) execution engine is selected to run the
// program.  This means the JIT compiler for the current platform if it's
// available.
//
//===----------------------------------------------------------------------===//

#include "ExecutionEngine.h"
#include "Support/CommandLine.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetMachineImpls.h"

namespace {
  cl::opt<std::string>
  InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));

  cl::list<std::string>
  InputArgv(cl::ConsumeAfter, cl::desc("<program arguments>..."));

  cl::opt<std::string>
  MainFunction ("f", cl::desc("Function to execute"), cl::init("main"),
		cl::value_desc("function name"));

  cl::opt<bool> DebugMode("d", cl::desc("Start program in debugger"));

  cl::opt<bool> TraceMode("trace", cl::desc("Enable Tracing"));

  cl::opt<bool> ForceInterpreter("force-interpreter",
				 cl::desc("Force interpretation: disable JIT"),
				 cl::init(false));
}

//===----------------------------------------------------------------------===//
// ExecutionEngine Class Implementation
//

ExecutionEngine::~ExecutionEngine() {
  delete &CurMod;
}

//===----------------------------------------------------------------------===//
// main Driver function
//
int main(int argc, char** argv, const char ** envp) {
  cl::ParseCommandLineOptions(argc, argv,
			      " llvm interpreter & dynamic compiler\n");

  // Load the bytecode...
  std::string ErrorMsg;
  Module *M = ParseBytecodeFile(InputFile, &ErrorMsg);
  if (M == 0) {
    std::cout << "Error parsing '" << InputFile << "': "
              << ErrorMsg << "\n";
    exit(1);
  }

#if 0
  // Link in the runtime library for LLI...
  std::string RuntimeLib = getCurrentExecutablePath();
  if (!RuntimeLib.empty()) RuntimeLib += "/";
  RuntimeLib += "RuntimeLib.bc";

  if (Module *SupportLib = ParseBytecodeFile(RuntimeLib, &ErrorMsg)) {
    if (LinkModules(M, SupportLib, &ErrorMsg))
      std::cerr << "Error Linking runtime library into current module: "
                << ErrorMsg << "\n";
  } else {
    std::cerr << "Error loading runtime library '"+RuntimeLib+"': "
              << ErrorMsg << "\n";
  }
#endif

  ExecutionEngine *EE = 0;

  // If there is nothing that is forcing us to use the interpreter, make a JIT.
  if (!ForceInterpreter && !DebugMode && !TraceMode)
    EE = ExecutionEngine::createJIT(M);

  // If we can't make a JIT, make an interpreter instead.
  if (EE == 0)
    EE = ExecutionEngine::createInterpreter(M, DebugMode, TraceMode);

  // Add the module name to the start of the argv vector...
  // But delete .bc first, since programs (and users) might not expect to
  // see it.
  const std::string ByteCodeFileSuffix (".bc");
  if (InputFile.rfind (ByteCodeFileSuffix) ==
      InputFile.length () - ByteCodeFileSuffix.length ()) {
    InputFile.erase (InputFile.length () - ByteCodeFileSuffix.length ());
  }
  InputArgv.insert(InputArgv.begin(), InputFile);

  // Run the main function!
  int ExitCode = EE->run(MainFunction, InputArgv, envp);

  // Now that we are done executing the program, shut down the execution engine
  delete EE;
  return ExitCode;
}
<commit_msg>Remove some long-dead code<commit_after>//===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===//
//
// This utility provides a way to execute LLVM bytecode without static
// compilation.  This consists of a very simple and slow (but portable)
// interpreter, along with capability for system specific dynamic compilers.  At
// runtime, the fastest (stable) execution engine is selected to run the
// program.  This means the JIT compiler for the current platform if it's
// available.
//
//===----------------------------------------------------------------------===//

#include "ExecutionEngine.h"
#include "Support/CommandLine.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetMachineImpls.h"

namespace {
  cl::opt<std::string>
  InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));

  cl::list<std::string>
  InputArgv(cl::ConsumeAfter, cl::desc("<program arguments>..."));

  cl::opt<std::string>
  MainFunction ("f", cl::desc("Function to execute"), cl::init("main"),
		cl::value_desc("function name"));

  cl::opt<bool> DebugMode("d", cl::desc("Start program in debugger"));

  cl::opt<bool> TraceMode("trace", cl::desc("Enable Tracing"));

  cl::opt<bool> ForceInterpreter("force-interpreter",
				 cl::desc("Force interpretation: disable JIT"),
				 cl::init(false));
}

//===----------------------------------------------------------------------===//
// ExecutionEngine Class Implementation
//

ExecutionEngine::~ExecutionEngine() {
  delete &CurMod;
}

//===----------------------------------------------------------------------===//
// main Driver function
//
int main(int argc, char** argv, const char ** envp) {
  cl::ParseCommandLineOptions(argc, argv,
			      " llvm interpreter & dynamic compiler\n");

  // Load the bytecode...
  std::string ErrorMsg;
  Module *M = ParseBytecodeFile(InputFile, &ErrorMsg);
  if (M == 0) {
    std::cout << "Error parsing '" << InputFile << "': "
              << ErrorMsg << "\n";
    exit(1);
  }

  ExecutionEngine *EE = 0;

  // If there is nothing that is forcing us to use the interpreter, make a JIT.
  if (!ForceInterpreter && !DebugMode && !TraceMode)
    EE = ExecutionEngine::createJIT(M);

  // If we can't make a JIT, make an interpreter instead.
  if (EE == 0)
    EE = ExecutionEngine::createInterpreter(M, DebugMode, TraceMode);

  // Add the module name to the start of the argv vector...
  // But delete .bc first, since programs (and users) might not expect to
  // see it.
  const std::string ByteCodeFileSuffix (".bc");
  if (InputFile.rfind (ByteCodeFileSuffix) ==
      InputFile.length () - ByteCodeFileSuffix.length ()) {
    InputFile.erase (InputFile.length () - ByteCodeFileSuffix.length ());
  }
  InputArgv.insert(InputArgv.begin(), InputFile);

  // Run the main function!
  int ExitCode = EE->run(MainFunction, InputArgv, envp);

  // Now that we are done executing the program, shut down the execution engine
  delete EE;
  return ExitCode;
}
<|endoftext|>


<commit_before>#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkCannyEdgeDetectionImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"
#include <itkNeighborhoodIterator.h>

#include "antsUtilities.h"
#include <algorithm>

#include <iomanip>
#include <iostream>
#include <ostream>
#include <sstream>

namespace ants
{
template <unsigned int ImageDimension>
int LesionFilling( int argc, char * argv[] )
{
  typedef int                                   LesionType;
  typedef itk::Image<LesionType, ImageDimension> LesionImageType;
  typedef itk::ImageFileReader<LesionImageType>  LesionReaderType;

  typedef int                                   T1Type;
  typedef itk::Image<LesionType, ImageDimension> T1ImageType;
  typedef itk::ImageFileReader<LesionImageType>  T1ReaderType;

  typedef double           RealPixelType;  //  Operations

  const int * ImageDimension = argv[1];
  const char * method = argv[2];
  const char * LesionMapFileName = argv[3];
  if (method == "-neighbourVoxels")
  {
         const char * T1FileName = argv[4]
  }
  else
  {
         const char * WMFileName = argv[4]
         const char * T1FileName = argv[5]
  }

  typename LesionReaderType::Pointer LesionReader = LesionReaderType::New();
  LesionReader->SetFileName( LesionMapFileName );
  LesionReader->Update();

  if (method == "-neighbourVoxels")
  {

         //Neighbouring voxel
         //filling lesions with the voxels surrounding them
         //first finding the edges of lesions

         typedef itk::BinaryDilateImageFilter<
                                   InputImageType,
                                   OutputImageType,
                                   StructuringElementType >  DilateFilterType;

         DilateFilterType::Pointer binaryDilate = DilateFilterType::New();

         binaryDilate->SetKernel( structuringElement );

         float variance = 1.0;
         float upperThreshold = 0.0;
         float lowerThreshold = 0.0;
         typedef itk::CastImageFilter< LesionImageType, RealImageType>
                                                                CastToRealFilterType;
         typedef itk::CannyEdgeDetectionImageFilter<RealImageType, RealImageType> CannyFilter;

         CastToRealFilterType::Pointer toReal = CastToRealFilterType::New();
         toReal->SetInput( LesionReader->GetOutput() );
         CannyFilter::Pointer cannyFilter = CannyFilter::New();

         cannyFilter->SetInput( toReal->GetOutput() );

         cannyFilter->SetVariance( variance );
         cannyFilter->SetUpperThreshold( upperThreshold );
         cannyFilter->SetLowerThreshold( lowerThreshold );

  /* LesionFilling d -neighbourVoxels binaryLeisonMap T1
   * LesionFilling d -mean binaryLesionMap AtroposWM T1
   * LesionFilling d -median binaryLesionmap AtroposWM T1
   * LesionFilling d -randomSample binaryLesionMap AtroposWM T1
   */
<commit_msg>neighbourhood voxel detection with binary dilation filter<commit_after>#include <algorithm>
#include <iomanip>
#include <iostream>
#include <ostream>
#include <sstream>
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSubtractImageFilter.h"
#include "itkBinaryDilateImageFilter.h"
#include "itkBinaryBallStructuringElement.h"
#include "antsUtilities.h"
#include "itkMaskImageFilter.h"

namespace ants
{
template <unsigned int ImageDimension>
int LesionFilling( int argc, char * argv[] )
{
  typedef int                                   LesionType;
  typedef itk::Image<LesionType, ImageDimension> LesionImageType;
  typedef itk::ImageFileReader<LesionImageType>  LesionReaderType;

  typedef int                                   T1Type;
  typedef itk::Image<LesionType, ImageDimension> T1ImageType;
  typedef itk::ImageFileReader<LesionImageType>  T1ReaderType;

  typedef double           RealPixelType;  //  Operations

  const int * ImageDimension = argv[1];
  const char * method = argv[2];
  const char * LesionMapFileName = argv[3];
  if (method == "-neighbourVoxels")
  {
         const char * T1FileName = argv[4]
  }
  else
  {
         const char * WMFileName = argv[4]
         const char * T1FileName = argv[5]
  }

  typename LesionReaderType::Pointer LesionReader = LesionReaderType::New();
  LesionReader->SetFileName( LesionMapFileName );
  LesionReader->Update();

  if (method == "-neighbourVoxels")
  {
         typedef itk::BinaryBallStructuringElement<
                             InputPixelType,
                             Dimension  >             StructuringElementType;
         //Neighbouring voxel
         //filling lesions with the voxels surrounding them
         //first finding the edges of lesions
         //by subtracting dilated lesion map from lesion map itself
         typedef itk::BinaryDilateImageFilter<
                                   InputImageType,
                                   OutputImageType,
                                   StructuringElementType >  DilateFilterType;
         DilateFilterType::Pointer binaryDilate = DilateFilterType::New();
         structuringElement.SetRadius( 1 );  // 3x3 structuring element
         structuringElement.CreateStructuringElement();
         binaryDilate->SetKernel( structuringElement );
         typedef itk::CastImageFilter< LesionImageType, RealImageType>
                                                                CastToRealFilterType;
         CastToRealFilterType::Pointer toReal = CastToRealFilterType::New();
         toReal->SetInput( LesionReader->GetOutput() );
         binaryDilate->SetInput( toReal->GetOutput() );
         binaryDilate->SetDilateValue( 1 );
         // subtract dilated image form non-dilated one
         typedef itk::SubtractImageFilter <ImageType, ImageType >
                     SubtractImageFilterType;
         SubtractImageFilterType::Pointer subtractFilter
                       = SubtractImageFilterType::New ();
         //output = image1 - image2
         subtractFilter->SetInput1(toReal->GetOutput() );
         subtractFilter->SetInput2(binaryDilate->GetOutput());
         subtractFilter->Update();
         //multiply the outer lesion mask with T1 to get only the neighbouring voxels

  /* LesionFilling d -neighbourVoxels binaryLeisonMap T1
   * LesionFilling d -mean binaryLesionMap AtroposWM T1
   * LesionFilling d -median binaryLesionmap AtroposWM T1
   * LesionFilling d -randomSample binaryLesionMap AtroposWM T1
   */
<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#pragma once

#include <string>
#include <utility>
#include <functional>

#include "caf/fwd.hpp"
#include "caf/none.hpp"
#include "caf/group_module.hpp"
#include "caf/intrusive_ptr.hpp"
#include "caf/abstract_group.hpp"

#include "caf/detail/comparable.hpp"
#include "caf/detail/type_traits.hpp"

namespace caf {

struct invalid_group_t {
  constexpr invalid_group_t() = default;
};

/// Identifies an invalid {@link group}.
/// @relates group
constexpr invalid_group_t invalid_group = invalid_group_t{};

class group : detail::comparable<group>,
              detail::comparable<group, invalid_group_t> {
public:
  template <class, class, int>
  friend class actor_cast_access;

  using signatures = none_t;

  group() = default;

  group(group&&) = default;

  group(const group&) = default;

  group(const invalid_group_t&);

  group& operator=(group&&) = default;

  group& operator=(const group&) = default;

  group& operator=(const invalid_group_t&);

  group(abstract_group*);

  group(intrusive_ptr<abstract_group> gptr);

  inline explicit operator bool() const noexcept {
    return static_cast<bool>(ptr_);
  }

  inline bool operator!() const noexcept {
    return !ptr_;
  }

  static intptr_t compare(const abstract_group* lhs, const abstract_group* rhs);

  intptr_t compare(const group& other) const noexcept;

  inline intptr_t compare(const invalid_group_t&) const noexcept {
    return ptr_ ? 1 : 0;
  }

  template <class Inspector>
  friend typename Inspector::result_type inspect(Inspector& f, group& x) {
    std::string x_id;
    std::string x_mod;
    auto ptr = x.get();
    if (ptr) {
      x_id = ptr->identifier();
      x_mod = ptr->module().name();
    }
    return f(meta::type_name("group"),
             meta::omittable_if_empty(), x_id,
             meta::omittable_if_empty(), x_mod);
  }

  friend error inspect(serializer&, group&);

  friend error inspect(deserializer&, group&);

  inline abstract_group* get() const noexcept {
    return ptr_.get();
  }

  /// @cond PRIVATE

  template <class... Ts>
  void eq_impl(message_id mid, strong_actor_ptr sender,
               execution_unit* ctx, Ts&&... xs) const {
    CAF_ASSERT(!mid.is_request());
    if (ptr_)
      ptr_->enqueue(std::move(sender), mid,
                    make_message(std::forward<Ts>(xs)...), ctx);
  }

  inline bool subscribe(strong_actor_ptr who) const {
    if (!ptr_)
      return false;
    return ptr_->subscribe(std::move(who));
  }

  inline void unsubscribe(const actor_control_block* who) const {
    if (ptr_)
      ptr_->unsubscribe(who);
  }

  /// CAF's messaging primitives assume a non-null guarantee. A group
  /// object indirects pointer-like access to a group to prevent UB.
  inline const group* operator->() const noexcept {
    return this;
  }

  /// @endcond

private:
  inline abstract_group* release() noexcept {
    return ptr_.release();
  }

  group(abstract_group*, bool);

  abstract_group_ptr ptr_;
};

/// @relates group
std::string to_string(const group& x);

} // namespace caf

namespace std {
template <>
struct hash<caf::group> {
  inline size_t operator()(const caf::group& x) const {
    // groups are singleton objects, the address is thus the best possible hash
    return !x ? 0 : reinterpret_cast<size_t>(x.get());
  }
};
} // namespace std

<commit_msg>Remove unnecessary friend declaration<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#pragma once

#include <string>
#include <utility>
#include <functional>

#include "caf/fwd.hpp"
#include "caf/none.hpp"
#include "caf/group_module.hpp"
#include "caf/intrusive_ptr.hpp"
#include "caf/abstract_group.hpp"

#include "caf/detail/comparable.hpp"
#include "caf/detail/type_traits.hpp"

namespace caf {

struct invalid_group_t {
  constexpr invalid_group_t() = default;
};

/// Identifies an invalid {@link group}.
/// @relates group
constexpr invalid_group_t invalid_group = invalid_group_t{};

class group : detail::comparable<group>,
              detail::comparable<group, invalid_group_t> {
public:
  using signatures = none_t;

  group() = default;

  group(group&&) = default;

  group(const group&) = default;

  group(const invalid_group_t&);

  group& operator=(group&&) = default;

  group& operator=(const group&) = default;

  group& operator=(const invalid_group_t&);

  group(abstract_group*);

  group(intrusive_ptr<abstract_group> gptr);

  inline explicit operator bool() const noexcept {
    return static_cast<bool>(ptr_);
  }

  inline bool operator!() const noexcept {
    return !ptr_;
  }

  static intptr_t compare(const abstract_group* lhs, const abstract_group* rhs);

  intptr_t compare(const group& other) const noexcept;

  inline intptr_t compare(const invalid_group_t&) const noexcept {
    return ptr_ ? 1 : 0;
  }

  template <class Inspector>
  friend typename Inspector::result_type inspect(Inspector& f, group& x) {
    std::string x_id;
    std::string x_mod;
    auto ptr = x.get();
    if (ptr) {
      x_id = ptr->identifier();
      x_mod = ptr->module().name();
    }
    return f(meta::type_name("group"),
             meta::omittable_if_empty(), x_id,
             meta::omittable_if_empty(), x_mod);
  }

  friend error inspect(serializer&, group&);

  friend error inspect(deserializer&, group&);

  inline abstract_group* get() const noexcept {
    return ptr_.get();
  }

  /// @cond PRIVATE

  template <class... Ts>
  void eq_impl(message_id mid, strong_actor_ptr sender,
               execution_unit* ctx, Ts&&... xs) const {
    CAF_ASSERT(!mid.is_request());
    if (ptr_)
      ptr_->enqueue(std::move(sender), mid,
                    make_message(std::forward<Ts>(xs)...), ctx);
  }

  inline bool subscribe(strong_actor_ptr who) const {
    if (!ptr_)
      return false;
    return ptr_->subscribe(std::move(who));
  }

  inline void unsubscribe(const actor_control_block* who) const {
    if (ptr_)
      ptr_->unsubscribe(who);
  }

  /// CAF's messaging primitives assume a non-null guarantee. A group
  /// object indirects pointer-like access to a group to prevent UB.
  inline const group* operator->() const noexcept {
    return this;
  }

  /// @endcond

private:
  inline abstract_group* release() noexcept {
    return ptr_.release();
  }

  group(abstract_group*, bool);

  abstract_group_ptr ptr_;
};

/// @relates group
std::string to_string(const group& x);

} // namespace caf

namespace std {
template <>
struct hash<caf::group> {
  inline size_t operator()(const caf::group& x) const {
    // groups are singleton objects, the address is thus the best possible hash
    return !x ? 0 : reinterpret_cast<size_t>(x.get());
  }
};
} // namespace std

<|endoftext|>