<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
//
// 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.
//

// appleseed.foundation headers.
#include "foundation/math/knn.h"
#include "foundation/math/rng.h"
#include "foundation/math/vector.h"
#include "foundation/platform/timer.h"
#include "foundation/platform/types.h"
#include "foundation/utility/autoreleaseptr.h"
#include "foundation/utility/benchmark.h"
#include "foundation/utility/bufferedfile.h"
#include "foundation/utility/log.h"
#include "foundation/utility/statistics.h"
#include "foundation/utility/string.h"

// Standard headers.
#include <cassert>
#include <cstddef>
#include <string>
#include <vector>

using namespace foundation;
using namespace std;

BENCHMARK_SUITE(Foundation_Math_Knn_Answer)
{
    template <size_t EntryCount>
    struct Fixture
    {
        Xorshift            m_rng;
        knn::Answer<float>  m_answer;

        Fixture()
          : m_answer(EntryCount)
        {
            for (size_t i = 0; i < EntryCount; ++i)
            {
                const float distance = rand_float1(m_rng);
                m_answer.array_insert(0, distance);
            }

            m_answer.make_heap();
        }

        void insert_into_heap()
        {
            for (size_t i = 0; i < EntryCount; ++i)
            {
                const float distance = rand_float1(m_rng);
                m_answer.heap_insert(0, distance);
            }
        }
    };

    BENCHMARK_CASE_F(InsertIntoHeap_K5, Fixture<5>)         { insert_into_heap(); }
    BENCHMARK_CASE_F(InsertIntoHeap_K20, Fixture<20>)       { insert_into_heap(); }
    BENCHMARK_CASE_F(InsertIntoHeap_K100, Fixture<100>)     { insert_into_heap(); }
    BENCHMARK_CASE_F(InsertIntoHeap_K500, Fixture<500>)     { insert_into_heap(); }

    BENCHMARK_CASE_F(Sort_K5, Fixture<5>)                   { m_answer.make_heap(); m_answer.sort(); }
    BENCHMARK_CASE_F(Sort_K20, Fixture<20>)                 { m_answer.make_heap(); m_answer.sort(); }
    BENCHMARK_CASE_F(Sort_K100, Fixture<100>)               { m_answer.make_heap(); m_answer.sort(); }
    BENCHMARK_CASE_F(Sort_K500, Fixture<500>)               { m_answer.make_heap(); m_answer.sort(); }
}

BENCHMARK_SUITE(Foundation_Math_Knn_Query)
{
    namespace
    {
        bool load_points_from_disk(const char* filename, vector<Vector3f>& points)
        {
            assert(filename);
            assert(points.empty());

            BufferedFile file(filename, BufferedFile::BinaryType, BufferedFile::ReadMode);

            if (!file.is_open())
                return false;

            uint32 point_count;
            if (file.read(point_count) != sizeof(uint32))
                return false;

            if (point_count > 0)
            {
                points.resize(point_count);

                const size_t bytes = point_count * sizeof(Vector3f);

                if (file.read(&points[0], bytes) != bytes)
                    return false;
            }

            return true;
        }
    }

    const size_t QueryCount = 10;

    template <size_t AnswerSize>
    class FixtureBase
    {
      protected:
        vector<Vector3f>    m_points;
        vector<Vector3f>    m_query_points;

        FixtureBase(const string& name)
          : m_accumulator(0)
          , m_answer(AnswerSize)
        {
            configure_logger(name);
        }

#ifdef FOUNDATION_KNN_ENABLE_QUERY_STATS

        ~FixtureBase()
        {
            LOG_DEBUG(
                m_logger, "%s",
                StatisticsVector::make(
                    "query statistics",
                    m_query_stats.get_statistics()).to_string().c_str());
        }

#endif

        void prepare()
        {
            if (!m_points.empty())
            {
                build_tree();
                find_query_points();
            }
        }

        void run_queries()
        {
            const size_t query_point_count = m_query_points.size();

            knn::Query3f query(m_tree, m_answer);

            for (size_t i = 0; i < query_point_count; ++i)
            {
                query.run(
                    m_query_points[i]
#ifdef FOUNDATION_KNN_ENABLE_QUERY_STATS
                    , m_query_stats
#endif
                    );

                m_accumulator += m_answer.size();
            }
        }

      private:
        Logger                              m_logger;
        auto_release_ptr<FileLogTarget>     m_log_target;

        knn::Tree3f                         m_tree;
        knn::Answer<float>                  m_answer;
        size_t                              m_accumulator;

#ifdef FOUNDATION_KNN_ENABLE_QUERY_STATS
        knn::QueryStatistics                m_query_stats;
#endif

        void configure_logger(const string& name)
        {
            m_log_target.reset(create_file_log_target());
            m_log_target->open(("unit benchmarks/outputs/test_knn_" + name + "_stats.txt").c_str());
            m_logger.add_target(m_log_target.get());
        }

        void build_tree()
        {
            knn::Builder3f builder(m_tree);
            builder.build<DefaultWallclockTimer>(&m_points[0], m_points.size());

            LOG_DEBUG(
                m_logger, "%s",
                StatisticsVector::make(
                    "tree statistics",
                    knn::TreeStatistics<knn::Tree3f>(m_tree)).to_string().c_str());
        }

        void find_query_points()
        {
            knn::Answer<float> answer(4);
            knn::Query3f query(m_tree, answer);

            const int32 point_count = static_cast<int32>(m_points.size());
            MersenneTwister rng;

            m_query_points.reserve(QueryCount);

            for (size_t i = 0; i < QueryCount; ++i)
            {
                // Choose a random point from the original point cloud.
                const size_t seed_point_index = rand_int1(rng, 0, point_count - 1);
                const Vector3f& seed_point = m_points[seed_point_index];

                // Find its neighboring points.
                query.run(seed_point);

                // Let the barycenter of these points be a query point.
                Vector3f query_point(0.0f);
                for (size_t j = 0; j < answer.size(); ++j)
                    query_point += m_points[m_tree.remap(answer.get(j).m_index)];
                query_point /= static_cast<float>(answer.size());
                m_query_points.push_back(query_point);
            }
        }
    };

    template <size_t AnswerSize>
    struct ParticlesFixture
      : public FixtureBase<AnswerSize>
    {
        typedef FixtureBase<AnswerSize> FixtureBaseType;

        ParticlesFixture()
          : FixtureBaseType("particles_k" + to_string(AnswerSize))
        {
            load_points_from_disk("unit benchmarks/inputs/test_knn_particles.bin", FixtureBaseType::m_points);
            FixtureBaseType::prepare();
        }
    };

    template <size_t AnswerSize>
    struct PhotonMapFixture
      : public FixtureBase<AnswerSize>
    {
        typedef FixtureBase<AnswerSize> FixtureBaseType;

        PhotonMapFixture()
          : FixtureBaseType("photons_k" + to_string(AnswerSize))
        {
            load_points_from_disk("unit benchmarks/inputs/test_knn_photons.bin", FixtureBaseType::m_points);
            FixtureBaseType::prepare();
        }
    };

    BENCHMARK_CASE_F(Particles_K1, ParticlesFixture<1>)      { run_queries(); }
    BENCHMARK_CASE_F(Particles_K5, ParticlesFixture<5>)      { run_queries(); }
    BENCHMARK_CASE_F(Particles_K20, ParticlesFixture<20>)    { run_queries(); }
    BENCHMARK_CASE_F(Particles_K100, ParticlesFixture<100>)  { run_queries(); }
    BENCHMARK_CASE_F(Particles_K500, ParticlesFixture<500>)  { run_queries(); }

    BENCHMARK_CASE_F(PhotonMap_K1, PhotonMapFixture<1>)      { run_queries(); }
    BENCHMARK_CASE_F(PhotonMap_K5, PhotonMapFixture<5>)      { run_queries(); }
    BENCHMARK_CASE_F(PhotonMap_K20, PhotonMapFixture<20>)    { run_queries(); }
    BENCHMARK_CASE_F(PhotonMap_K100, PhotonMapFixture<100>)  { run_queries(); }
    BENCHMARK_CASE_F(PhotonMap_K500, PhotonMapFixture<500>)  { run_queries(); }
}
<commit_msg>fixed unit benchmarks.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
//
// 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.
//

// appleseed.foundation headers.
#include "foundation/math/knn.h"
#include "foundation/math/rng.h"
#include "foundation/math/vector.h"
#include "foundation/platform/timer.h"
#include "foundation/platform/types.h"
#include "foundation/utility/autoreleaseptr.h"
#include "foundation/utility/benchmark.h"
#include "foundation/utility/bufferedfile.h"
#include "foundation/utility/log.h"
#include "foundation/utility/statistics.h"
#include "foundation/utility/string.h"

// Standard headers.
#include <cassert>
#include <cstddef>
#include <string>
#include <vector>

using namespace foundation;
using namespace std;

BENCHMARK_SUITE(Foundation_Math_Knn_Answer)
{
    template <size_t EntryCount>
    struct Fixture
    {
        Xorshift            m_rng;
        knn::Answer<float>  m_answer;

        Fixture()
          : m_answer(EntryCount)
        {
            for (size_t i = 0; i < EntryCount; ++i)
            {
                const float distance = rand_float1(m_rng);
                m_answer.array_insert(0, distance);
            }

            m_answer.make_heap();
        }

        void insert_into_heap()
        {
            for (size_t i = 0; i < EntryCount; ++i)
            {
                const float distance = rand_float1(m_rng);
                m_answer.heap_insert(0, distance);
            }
        }
    };

    BENCHMARK_CASE_F(InsertIntoHeap_K5, Fixture<5>)         { insert_into_heap(); }
    BENCHMARK_CASE_F(InsertIntoHeap_K20, Fixture<20>)       { insert_into_heap(); }
    BENCHMARK_CASE_F(InsertIntoHeap_K100, Fixture<100>)     { insert_into_heap(); }
    BENCHMARK_CASE_F(InsertIntoHeap_K500, Fixture<500>)     { insert_into_heap(); }

    BENCHMARK_CASE_F(Sort_K5, Fixture<5>)                   { m_answer.sort(); }
    BENCHMARK_CASE_F(Sort_K20, Fixture<20>)                 { m_answer.sort(); }
    BENCHMARK_CASE_F(Sort_K100, Fixture<100>)               { m_answer.sort(); }
    BENCHMARK_CASE_F(Sort_K500, Fixture<500>)               { m_answer.sort(); }
}

BENCHMARK_SUITE(Foundation_Math_Knn_Query)
{
    namespace
    {
        bool load_points_from_disk(const char* filename, vector<Vector3f>& points)
        {
            assert(filename);
            assert(points.empty());

            BufferedFile file(filename, BufferedFile::BinaryType, BufferedFile::ReadMode);

            if (!file.is_open())
                return false;

            uint32 point_count;
            if (file.read(point_count) != sizeof(uint32))
                return false;

            if (point_count > 0)
            {
                points.resize(point_count);

                const size_t bytes = point_count * sizeof(Vector3f);

                if (file.read(&points[0], bytes) != bytes)
                    return false;
            }

            return true;
        }
    }

    const size_t QueryCount = 10;

    template <size_t AnswerSize>
    class FixtureBase
    {
      protected:
        vector<Vector3f>    m_points;
        vector<Vector3f>    m_query_points;

        FixtureBase(const string& name)
          : m_accumulator(0)
          , m_answer(AnswerSize)
        {
            configure_logger(name);
        }

#ifdef FOUNDATION_KNN_ENABLE_QUERY_STATS

        ~FixtureBase()
        {
            LOG_DEBUG(
                m_logger, "%s",
                StatisticsVector::make(
                    "query statistics",
                    m_query_stats.get_statistics()).to_string().c_str());
        }

#endif

        void prepare()
        {
            if (!m_points.empty())
            {
                build_tree();
                find_query_points();
            }
        }

        void run_queries()
        {
            const size_t query_point_count = m_query_points.size();

            knn::Query3f query(m_tree, m_answer);

            for (size_t i = 0; i < query_point_count; ++i)
            {
                query.run(
                    m_query_points[i]
#ifdef FOUNDATION_KNN_ENABLE_QUERY_STATS
                    , m_query_stats
#endif
                    );

                m_accumulator += m_answer.size();
            }
        }

      private:
        Logger                              m_logger;
        auto_release_ptr<FileLogTarget>     m_log_target;

        knn::Tree3f                         m_tree;
        knn::Answer<float>                  m_answer;
        size_t                              m_accumulator;

#ifdef FOUNDATION_KNN_ENABLE_QUERY_STATS
        knn::QueryStatistics                m_query_stats;
#endif

        void configure_logger(const string& name)
        {
            m_log_target.reset(create_file_log_target());
            m_log_target->open(("unit benchmarks/outputs/test_knn_" + name + "_stats.txt").c_str());
            m_logger.add_target(m_log_target.get());
        }

        void build_tree()
        {
            knn::Builder3f builder(m_tree);
            builder.build<DefaultWallclockTimer>(&m_points[0], m_points.size());

            LOG_DEBUG(
                m_logger, "%s",
                StatisticsVector::make(
                    "tree statistics",
                    knn::TreeStatistics<knn::Tree3f>(m_tree)).to_string().c_str());
        }

        void find_query_points()
        {
            knn::Answer<float> answer(4);
            knn::Query3f query(m_tree, answer);

            const int32 point_count = static_cast<int32>(m_points.size());
            MersenneTwister rng;

            m_query_points.reserve(QueryCount);

            for (size_t i = 0; i < QueryCount; ++i)
            {
                // Choose a random point from the original point cloud.
                const size_t seed_point_index = rand_int1(rng, 0, point_count - 1);
                const Vector3f& seed_point = m_points[seed_point_index];

                // Find its neighboring points.
                query.run(seed_point);

                // Let the barycenter of these points be a query point.
                Vector3f query_point(0.0f);
                for (size_t j = 0; j < answer.size(); ++j)
                    query_point += m_points[m_tree.remap(answer.get(j).m_index)];
                query_point /= static_cast<float>(answer.size());
                m_query_points.push_back(query_point);
            }
        }
    };

    template <size_t AnswerSize>
    struct ParticlesFixture
      : public FixtureBase<AnswerSize>
    {
        typedef FixtureBase<AnswerSize> FixtureBaseType;

        ParticlesFixture()
          : FixtureBaseType("particles_k" + to_string(AnswerSize))
        {
            load_points_from_disk("unit benchmarks/inputs/test_knn_particles.bin", FixtureBaseType::m_points);
            FixtureBaseType::prepare();
        }
    };

    template <size_t AnswerSize>
    struct PhotonMapFixture
      : public FixtureBase<AnswerSize>
    {
        typedef FixtureBase<AnswerSize> FixtureBaseType;

        PhotonMapFixture()
          : FixtureBaseType("photons_k" + to_string(AnswerSize))
        {
            load_points_from_disk("unit benchmarks/inputs/test_knn_photons.bin", FixtureBaseType::m_points);
            FixtureBaseType::prepare();
        }
    };

    BENCHMARK_CASE_F(Particles_K1, ParticlesFixture<1>)      { run_queries(); }
    BENCHMARK_CASE_F(Particles_K5, ParticlesFixture<5>)      { run_queries(); }
    BENCHMARK_CASE_F(Particles_K20, ParticlesFixture<20>)    { run_queries(); }
    BENCHMARK_CASE_F(Particles_K100, ParticlesFixture<100>)  { run_queries(); }
    BENCHMARK_CASE_F(Particles_K500, ParticlesFixture<500>)  { run_queries(); }

    BENCHMARK_CASE_F(PhotonMap_K1, PhotonMapFixture<1>)      { run_queries(); }
    BENCHMARK_CASE_F(PhotonMap_K5, PhotonMapFixture<5>)      { run_queries(); }
    BENCHMARK_CASE_F(PhotonMap_K20, PhotonMapFixture<20>)    { run_queries(); }
    BENCHMARK_CASE_F(PhotonMap_K100, PhotonMapFixture<100>)  { run_queries(); }
    BENCHMARK_CASE_F(PhotonMap_K500, PhotonMapFixture<500>)  { run_queries(); }
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// transaction_manager.cpp
//
// Identification: src/backend/concurrency/optimistic_transaction_manager.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "optimistic_transaction_manager.h"

#include "backend/common/platform.h"
#include "backend/logging/log_manager.h"
#include "backend/logging/records/transaction_record.h"
#include "backend/concurrency/transaction.h"
#include "backend/catalog/manager.h"
#include "backend/common/exception.h"
#include "backend/common/logger.h"
#include "backend/storage/data_table.h"
#include "backend/storage/tile_group.h"
#include "backend/storage/tile_group_header.h"

namespace peloton {
namespace concurrency {

OptimisticTransactionManager &OptimisticTransactionManager::GetInstance() {
  static OptimisticTransactionManager txn_manager;
  return txn_manager;
}

// Visibility check
bool OptimisticTransactionManager::IsVisible(const txn_id_t &tuple_txn_id,
                                             const cid_t &tuple_begin_cid,
                                             const cid_t &tuple_end_cid) {
  if (tuple_txn_id == INVALID_TXN_ID) {
    // the tuple is not available.
    return false;
  }
  bool own = (current_txn->GetTransactionId() == tuple_txn_id);

  // there are exactly two versions that can be owned by a transaction.
  if (own == true) {
    if (tuple_begin_cid == MAX_CID && tuple_end_cid != INVALID_CID) {
      assert(tuple_end_cid == MAX_CID);
      // the only version that is visible is the newly inserted one.
      return true;
    } else {
      // the older version is not visible.
      return false;
    }
  } else {
    bool activated = (current_txn->GetStartCommitId() >= tuple_begin_cid);
    bool invalidated = (current_txn->GetStartCommitId() >= tuple_end_cid);
    if (tuple_txn_id != INITIAL_TXN_ID) {
      // if the tuple is owned by other transactions.
      if (tuple_begin_cid == MAX_CID) {
        // currently, we do not handle cascading abort. so never read an
        // uncommitted version.
        return false;
      } else {
        // the older version may be visible.
        if (activated && !invalidated) {
          return true;
        } else {
          return false;
        }
      }
    } else {
      // if the tuple is not owned by any transaction.
      if (activated && !invalidated) {
        return true;
      } else {
        return false;
      }
    }
  }
}

bool OptimisticTransactionManager::RecordRead(const oid_t &tile_group_id, const oid_t &tuple_id) {
  current_txn->RecordRead(tile_group_id, tuple_id);
  return true;
}

bool OptimisticTransactionManager::RecordWrite(const oid_t &tile_group_id, const oid_t &tuple_id) {
  current_txn->RecordWrite(tile_group_id, tuple_id);
  return true;
}

bool OptimisticTransactionManager::RecordInsert(const oid_t &tile_group_id, const oid_t &tuple_id) {
  current_txn->RecordInsert(tile_group_id, tuple_id);
  return true;
}

bool OptimisticTransactionManager::RecordDelete(const oid_t &tile_group_id, const oid_t &tuple_id) {
  current_txn->RecordDelete(tile_group_id, tuple_id);
  return true;
}

void OptimisticTransactionManager::CommitTransaction() {
  LOG_INFO("Committing peloton txn : %lu ", current_txn->GetTransactionId());

  auto &manager = catalog::Manager::GetInstance();

  // generate transaction id.
  cid_t end_commit_id = GetNextCommitId();

  // validate read set.
  auto read_tuples = current_txn->GetReadTuples();
  for (auto entry : read_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      if (tile_group_header->GetTransactionId(tuple_slot) ==
          current_txn->GetTransactionId()) {
        // the version is owned by the transaction.
        continue;
      } else {
        if (tile_group_header->GetTransactionId(tuple_slot) == INITIAL_TXN_ID &&
          tile_group_header->GetBeginCommitId(tuple_slot) <= end_commit_id &&
          tile_group_header->GetEndCommitId(tuple_slot) >= end_commit_id) {
          // the version is not locked and still visible.
          continue;
        }
      }
      // otherwise, validation fails. abort transaction.
      AbortTransaction();
      return;
    }
  }

  auto written_tuples = current_txn->GetWrittenTuples();
  // install all updates.
  for (auto entry : written_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      // we must guarantee that, at any time point, only one version is visible.
      tile_group_header->SetEndCommitId(tuple_slot, end_commit_id);
      ItemPointer new_version =
          tile_group_header->GetNextItemPointer(tuple_slot);

      auto new_tile_group_header =
          manager.GetTileGroup(new_version.block)->GetHeader();
      new_tile_group_header->SetBeginCommitId(new_version.offset,
                                              end_commit_id);
      new_tile_group_header->SetEndCommitId(new_version.offset, MAX_CID);

      COMPILER_MEMORY_FENCE;

      new_tile_group_header->SetTransactionId(new_version.offset,
                                              INITIAL_TXN_ID);
      tile_group_header->UnlockTupleSlot(
          tuple_slot, current_txn->GetTransactionId());
    }
  }

  // commit insert set.
  auto inserted_tuples = current_txn->GetInsertedTuples();
  for (auto entry : inserted_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    for (auto tuple_slot : entry.second) {
      tile_group->CommitInsertedTuple(
          tuple_slot, current_txn->GetTransactionId(), end_commit_id);
    }
  }

  // commit delete set.
  auto deleted_tuples = current_txn->GetDeletedTuples();
  for (auto entry : deleted_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      // we must guarantee that, at any time point, only one version is visible.

      tile_group_header->SetEndCommitId(tuple_slot, end_commit_id);
      ItemPointer new_version =
          tile_group_header->GetNextItemPointer(tuple_slot);

      auto new_tile_group_header =
          manager.GetTileGroup(new_version.block)->GetHeader();
      new_tile_group_header->SetBeginCommitId(new_version.offset,
                                              end_commit_id);
      new_tile_group_header->SetEndCommitId(new_version.offset, MAX_CID);

      COMPILER_MEMORY_FENCE;

      new_tile_group_header->SetTransactionId(new_version.offset,
                                              INVALID_TXN_ID);
      tile_group_header->UnlockTupleSlot(
          tuple_slot, current_txn->GetTransactionId());
    }
  }
  delete current_txn;
  current_txn = nullptr;
}

void OptimisticTransactionManager::AbortTransaction() {
  LOG_INFO("Aborting peloton txn : %lu ", current_txn->GetTransactionId());
  auto &manager = catalog::Manager::GetInstance();
  auto written_tuples = current_txn->GetWrittenTuples();

  // recover write set.
  for (auto entry : written_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      tile_group_header->UnlockTupleSlot(
          tuple_slot, current_txn->GetTransactionId());
      tile_group_header->SetEndCommitId(tuple_slot, MAX_CID);
      ItemPointer new_version =
          tile_group_header->GetNextItemPointer(tuple_slot);
      auto new_tile_group_header =
          manager.GetTileGroup(new_version.block)->GetHeader();
      new_tile_group_header->SetTransactionId(new_version.offset,
                                              INVALID_TXN_ID);
      new_tile_group_header->SetBeginCommitId(new_version.offset, MAX_CID);
      new_tile_group_header->SetEndCommitId(new_version.offset, MAX_CID);
    }
  }

  // recover delete set.
  auto deleted_tuples = current_txn->GetDeletedTuples();
  for (auto entry : deleted_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      tile_group_header->UnlockTupleSlot(
          tuple_slot, current_txn->GetTransactionId());
      tile_group_header->SetEndCommitId(tuple_slot, MAX_CID);
      ItemPointer new_version =
          tile_group_header->GetNextItemPointer(tuple_slot);
      auto new_tile_group_header =
          manager.GetTileGroup(new_version.block)->GetHeader();
      new_tile_group_header->SetTransactionId(new_version.offset,
                                              INVALID_TXN_ID);
      new_tile_group_header->SetBeginCommitId(new_version.offset, MAX_CID);
      new_tile_group_header->SetEndCommitId(new_version.offset, MAX_CID);
    }
  }

  delete current_txn;
  current_txn = null_ptr;
}

}  // End storage namespace
}  // End peloton namespace<commit_msg>fix typo in occ txn manager<commit_after>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// transaction_manager.cpp
//
// Identification: src/backend/concurrency/optimistic_transaction_manager.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "optimistic_transaction_manager.h"

#include "backend/common/platform.h"
#include "backend/logging/log_manager.h"
#include "backend/logging/records/transaction_record.h"
#include "backend/concurrency/transaction.h"
#include "backend/catalog/manager.h"
#include "backend/common/exception.h"
#include "backend/common/logger.h"
#include "backend/storage/data_table.h"
#include "backend/storage/tile_group.h"
#include "backend/storage/tile_group_header.h"

namespace peloton {
namespace concurrency {

OptimisticTransactionManager &OptimisticTransactionManager::GetInstance() {
  static OptimisticTransactionManager txn_manager;
  return txn_manager;
}

// Visibility check
bool OptimisticTransactionManager::IsVisible(const txn_id_t &tuple_txn_id,
                                             const cid_t &tuple_begin_cid,
                                             const cid_t &tuple_end_cid) {
  if (tuple_txn_id == INVALID_TXN_ID) {
    // the tuple is not available.
    return false;
  }
  bool own = (current_txn->GetTransactionId() == tuple_txn_id);

  // there are exactly two versions that can be owned by a transaction.
  if (own == true) {
    if (tuple_begin_cid == MAX_CID && tuple_end_cid != INVALID_CID) {
      assert(tuple_end_cid == MAX_CID);
      // the only version that is visible is the newly inserted one.
      return true;
    } else {
      // the older version is not visible.
      return false;
    }
  } else {
    bool activated = (current_txn->GetStartCommitId() >= tuple_begin_cid);
    bool invalidated = (current_txn->GetStartCommitId() >= tuple_end_cid);
    if (tuple_txn_id != INITIAL_TXN_ID) {
      // if the tuple is owned by other transactions.
      if (tuple_begin_cid == MAX_CID) {
        // currently, we do not handle cascading abort. so never read an
        // uncommitted version.
        return false;
      } else {
        // the older version may be visible.
        if (activated && !invalidated) {
          return true;
        } else {
          return false;
        }
      }
    } else {
      // if the tuple is not owned by any transaction.
      if (activated && !invalidated) {
        return true;
      } else {
        return false;
      }
    }
  }
}

bool OptimisticTransactionManager::RecordRead(const oid_t &tile_group_id, const oid_t &tuple_id) {
  current_txn->RecordRead(tile_group_id, tuple_id);
  return true;
}

bool OptimisticTransactionManager::RecordWrite(const oid_t &tile_group_id, const oid_t &tuple_id) {
  current_txn->RecordWrite(tile_group_id, tuple_id);
  return true;
}

bool OptimisticTransactionManager::RecordInsert(const oid_t &tile_group_id, const oid_t &tuple_id) {
  current_txn->RecordInsert(tile_group_id, tuple_id);
  return true;
}

bool OptimisticTransactionManager::RecordDelete(const oid_t &tile_group_id, const oid_t &tuple_id) {
  current_txn->RecordDelete(tile_group_id, tuple_id);
  return true;
}

void OptimisticTransactionManager::CommitTransaction() {
  LOG_INFO("Committing peloton txn : %lu ", current_txn->GetTransactionId());

  auto &manager = catalog::Manager::GetInstance();

  // generate transaction id.
  cid_t end_commit_id = GetNextCommitId();

  // validate read set.
  auto read_tuples = current_txn->GetReadTuples();
  for (auto entry : read_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      if (tile_group_header->GetTransactionId(tuple_slot) ==
          current_txn->GetTransactionId()) {
        // the version is owned by the transaction.
        continue;
      } else {
        if (tile_group_header->GetTransactionId(tuple_slot) == INITIAL_TXN_ID &&
          tile_group_header->GetBeginCommitId(tuple_slot) <= end_commit_id &&
          tile_group_header->GetEndCommitId(tuple_slot) >= end_commit_id) {
          // the version is not locked and still visible.
          continue;
        }
      }
      // otherwise, validation fails. abort transaction.
      AbortTransaction();
      return;
    }
  }

  auto written_tuples = current_txn->GetWrittenTuples();
  // install all updates.
  for (auto entry : written_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      // we must guarantee that, at any time point, only one version is visible.
      tile_group_header->SetEndCommitId(tuple_slot, end_commit_id);
      ItemPointer new_version =
          tile_group_header->GetNextItemPointer(tuple_slot);

      auto new_tile_group_header =
          manager.GetTileGroup(new_version.block)->GetHeader();
      new_tile_group_header->SetBeginCommitId(new_version.offset,
                                              end_commit_id);
      new_tile_group_header->SetEndCommitId(new_version.offset, MAX_CID);

      COMPILER_MEMORY_FENCE;

      new_tile_group_header->SetTransactionId(new_version.offset,
                                              INITIAL_TXN_ID);
      tile_group_header->UnlockTupleSlot(
          tuple_slot, current_txn->GetTransactionId());
    }
  }

  // commit insert set.
  auto inserted_tuples = current_txn->GetInsertedTuples();
  for (auto entry : inserted_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    for (auto tuple_slot : entry.second) {
      tile_group->CommitInsertedTuple(
          tuple_slot, current_txn->GetTransactionId(), end_commit_id);
    }
  }

  // commit delete set.
  auto deleted_tuples = current_txn->GetDeletedTuples();
  for (auto entry : deleted_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      // we must guarantee that, at any time point, only one version is visible.

      tile_group_header->SetEndCommitId(tuple_slot, end_commit_id);
      ItemPointer new_version =
          tile_group_header->GetNextItemPointer(tuple_slot);

      auto new_tile_group_header =
          manager.GetTileGroup(new_version.block)->GetHeader();
      new_tile_group_header->SetBeginCommitId(new_version.offset,
                                              end_commit_id);
      new_tile_group_header->SetEndCommitId(new_version.offset, MAX_CID);

      COMPILER_MEMORY_FENCE;

      new_tile_group_header->SetTransactionId(new_version.offset,
                                              INVALID_TXN_ID);
      tile_group_header->UnlockTupleSlot(
          tuple_slot, current_txn->GetTransactionId());
    }
  }
  delete current_txn;
  current_txn = nullptr;
}

void OptimisticTransactionManager::AbortTransaction() {
  LOG_INFO("Aborting peloton txn : %lu ", current_txn->GetTransactionId());
  auto &manager = catalog::Manager::GetInstance();
  auto written_tuples = current_txn->GetWrittenTuples();

  // recover write set.
  for (auto entry : written_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      tile_group_header->UnlockTupleSlot(
          tuple_slot, current_txn->GetTransactionId());
      tile_group_header->SetEndCommitId(tuple_slot, MAX_CID);
      ItemPointer new_version =
          tile_group_header->GetNextItemPointer(tuple_slot);
      auto new_tile_group_header =
          manager.GetTileGroup(new_version.block)->GetHeader();
      new_tile_group_header->SetTransactionId(new_version.offset,
                                              INVALID_TXN_ID);
      new_tile_group_header->SetBeginCommitId(new_version.offset, MAX_CID);
      new_tile_group_header->SetEndCommitId(new_version.offset, MAX_CID);
    }
  }

  // recover delete set.
  auto deleted_tuples = current_txn->GetDeletedTuples();
  for (auto entry : deleted_tuples) {
    oid_t tile_group_id = entry.first;
    auto tile_group = manager.GetTileGroup(tile_group_id);
    auto tile_group_header = tile_group->GetHeader();
    for (auto tuple_slot : entry.second) {
      tile_group_header->UnlockTupleSlot(
          tuple_slot, current_txn->GetTransactionId());
      tile_group_header->SetEndCommitId(tuple_slot, MAX_CID);
      ItemPointer new_version =
          tile_group_header->GetNextItemPointer(tuple_slot);
      auto new_tile_group_header =
          manager.GetTileGroup(new_version.block)->GetHeader();
      new_tile_group_header->SetTransactionId(new_version.offset,
                                              INVALID_TXN_ID);
      new_tile_group_header->SetBeginCommitId(new_version.offset, MAX_CID);
      new_tile_group_header->SetEndCommitId(new_version.offset, MAX_CID);
    }
  }

  delete current_txn;
  current_txn = nullptr;
}

}  // End storage namespace
}  // End peloton namespace<|endoftext|>


<commit_before><commit_msg>Firecracker item<commit_after><|endoftext|>


<commit_before>/**\file
 * \ingroup example-programmes
 * \brief FaaS: Fortune as a Service
 *
 * Call it like this:
 * \code
 * $ ./fortuned http:localhost:8080
 * \endcode
 *
 * With localhost and 8080 being a host name and port of your choosing. Then,
 * while the programme is running.
 *
 * \copyright
 * Copyright (c) 2015, ef.gy Project Members
 * \copyright
 * 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:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * 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.
 *
 * \see Project Documentation: https://ef.gy/documentation/libefgy
 * \see Project Source Code: https://github.com/ef-gy/libefgy
 */

#define ASIO_DISABLE_THREADS
#include <ef.gy/httpd.h>

#include <cstdlib>
#include <dirent.h>
#include <iostream>
#include <fstream>

using namespace efgy;
using namespace std;

map<string, string> fortuneData;

class cookie {
public:
  enum encoding { ePlain, eROT13 } encoding;
  string file;
  size_t offset;
  size_t length;

  cookie(enum encoding pE, const string &pFile, size_t pOffset, size_t pLength)
      : encoding(pE), file(pFile), offset(pOffset), length(pLength) {}

  operator string(void) const {
    string r(fortuneData[file].data() + offset, length);

    if (encoding == eROT13) {
      for (size_t i = 0; i < r.size(); i++) {
        char c = r[i];

        switch (c) {
        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'e':
        case 'f':
        case 'g':
        case 'h':
        case 'i':
        case 'j':
        case 'k':
        case 'l':
        case 'm':
        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
        case 'G':
        case 'H':
        case 'I':
        case 'J':
        case 'K':
        case 'L':
        case 'M':
          r[i] = c + 13;
          break;
        case 'n':
        case 'o':
        case 'p':
        case 'q':
        case 'r':
        case 's':
        case 't':
        case 'u':
        case 'v':
        case 'w':
        case 'x':
        case 'y':
        case 'z':
        case 'N':
        case 'O':
        case 'P':
        case 'Q':
        case 'R':
        case 'S':
        case 'T':
        case 'U':
        case 'V':
        case 'W':
        case 'X':
        case 'Y':
        case 'Z':
          r[i] = c - 13;
          break;
        default:
          break;
        }
      }
    }

    return r;
  }
};

vector<cookie> cookies;

static bool prepareFortunes(const string &dir, const bool doROT13 = false) {
  static const regex dataFile(".*/[a-zA-Z-]+");
  smatch matches;

  DIR *d = opendir(dir.c_str());
  if (!d) {
    return false;
  }
  struct dirent *en;
  while ((en = readdir(d)) != 0) {
    string e = dir + en->d_name;

    if (regex_match(e, matches, dataFile)) {
      std::ifstream t(e);
      std::stringstream buffer;
      buffer << t.rdbuf();

      fortuneData[e] = buffer.str();

      const string &p = fortuneData[e];
      const char *data = p.c_str();
      size_t start = 0;
      enum { stN, stNL, stNLP } state = stN;

      for (size_t c = 0; c < p.size(); c++) {
        switch (data[c]) {
        case '\n':
          switch (state) {
          case stN:
            state = stNL;
            break;
          case stNLP:
            cookies.push_back(
                cookie((doROT13 ? cookie::eROT13 : cookie::ePlain), e, start,
                       c - start - 1));
            start = c + 1;
          default:
            state = stN;
            break;
          }
          break;

        case '%':
          switch (state) {
          case stNL:
            state = stNLP;
            break;
          default:
            state = stN;
            break;
          }
          break;

        case '\r':
          break;

        default:
          state = stN;
          break;
        }
      }
    }
  }
  closedir(d);

  return true;
}

template <class transport>
static bool fortune(typename net::http::server<transport>::session &session,
                    std::smatch &) {
  const int id = rand() % cookies.size();
  const cookie &c = cookies[id];
  char nbuf[20];
  snprintf(nbuf, 20, "%i", id);
  string sc = string(c);

  /* note: this escaping is not exactly efficient, but it's fairly simple
     and the strings are fairly short, so it shouldn't be much of an issue. */
  for (char i = 0; i < 0x20; i++) {
    if ((i == '\n') || (i == '\t')) {
      continue;
    }
    const char org[2] = {i, 0};
    const char rep[3] = {'^', (char)(('A' - 1) + i), 0};
    for (size_t pos = sc.find(org, pos); pos != std::string::npos;
         pos = sc.find(org, pos)) {
      sc.replace(pos, 2, rep);
      pos += 3;
    }
  }

  sc = "<![CDATA[" + sc + "]]>";

  session.reply(200, "Content-Type: text/xml; charset=utf-8\r\n",
                string("<?xml version='1.0' encoding='utf-8'?>"
                       "<fortune xmlns='http://ef.gy/2012/fortune' quoteID='") +
                    nbuf + "' sourceFile='" + c.file + "'>" + sc +
                    "</fortune>");

  return true;
}

namespace tcp {
using asio::ip::tcp;
static httpd::servlet<tcp> fortune("^/fortune$", ::fortune<tcp>);
static httpd::servlet<tcp> quit("^/quit$", httpd::quit<tcp>);
}

namespace unix {
using asio::local::stream_protocol;
static httpd::servlet<stream_protocol> fortune("^/fortune$",
                                               ::fortune<stream_protocol>);
static httpd::servlet<stream_protocol> quit("^/quit$",
                                            httpd::quit<stream_protocol>);
}

static cli::option
    count("count", [](std::smatch &m) -> bool {
                     std::cout << cookies.size() << " cookie(s) loaded\n";

                     return true;
                   },
          "prints the number of fortune cookies in the database.");

static cli::option print("print(:([0-9]+))?",
                         [](std::smatch &m) -> bool {
                           if (m[1] != "") {
                             std::stringstream s(m[2]);
                             std::size_t n;
                             s >> n;
                             if (n < cookies.size()) {
                               std::cout << std::string(cookies[n]);
                             } else {
                               return false;
                             }
                           } else {
                             std::cout << std::string(
                                 cookies[(rand() % cookies.size())]);
                           }

                           return true;
                         },
                         "print a fortune to stdout - a numerical parameter "
                         "selects a specific cookie.");

int main(int argc, char *argv[]) {
  prepareFortunes("/usr/share/games/fortunes/");
  prepareFortunes("/usr/share/games/fortunes/off/", true);

  srand(time(0));

  return io::main(argc, argv);
}
<commit_msg>wrap things up neatly in a class.<commit_after>/**\file
 * \ingroup example-programmes
 * \brief FaaS: Fortune as a Service
 *
 * Call it like this:
 * \code
 * $ ./fortuned http:localhost:8080
 * \endcode
 *
 * With localhost and 8080 being a host name and port of your choosing. Then,
 * while the programme is running.
 *
 * \copyright
 * Copyright (c) 2015, ef.gy Project Members
 * \copyright
 * 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:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * 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.
 *
 * \see Project Documentation: https://ef.gy/documentation/libefgy
 * \see Project Source Code: https://github.com/ef-gy/libefgy
 */

#define ASIO_DISABLE_THREADS
#include <ef.gy/httpd.h>

#include <cstdlib>
#include <dirent.h>
#include <iostream>
#include <fstream>

using namespace efgy;

class fortune {
public:
  fortune(void) : cookies(), data() {}

  static fortune &common(void) {
    static fortune f;
    return f;
  }

protected:
  class cookie {
  public:
    const std::string file;

    cookie(bool pROT13, const std::string &pData, const std::string &pFile)
        : rot13(pROT13), data(pData), file(pFile) {}

    operator std::string(void) const {
      std::string r = data;

      if (rot13) {
        for (size_t i = 0; i < r.size(); i++) {
          char c = r[i];

          switch (c) {
          case 'a':
          case 'b':
          case 'c':
          case 'd':
          case 'e':
          case 'f':
          case 'g':
          case 'h':
          case 'i':
          case 'j':
          case 'k':
          case 'l':
          case 'm':
          case 'A':
          case 'B':
          case 'C':
          case 'D':
          case 'E':
          case 'F':
          case 'G':
          case 'H':
          case 'I':
          case 'J':
          case 'K':
          case 'L':
          case 'M':
            r[i] = c + 13;
            break;
          case 'n':
          case 'o':
          case 'p':
          case 'q':
          case 'r':
          case 's':
          case 't':
          case 'u':
          case 'v':
          case 'w':
          case 'x':
          case 'y':
          case 'z':
          case 'N':
          case 'O':
          case 'P':
          case 'Q':
          case 'R':
          case 'S':
          case 'T':
          case 'U':
          case 'V':
          case 'W':
          case 'X':
          case 'Y':
          case 'Z':
            r[i] = c - 13;
            break;
          default:
            break;
          }
        }
      }

      return r;
    }

  protected:
    bool rot13;
    const std::string data;
  };

  std::vector<cookie> cookies;
  std::map<std::string, std::string> data;

public:
  bool prepare(const std::string &dir, const bool doROT13 = false) {
    static const std::regex dataFile(".*/[a-zA-Z-]+");
    std::smatch matches;
    DIR *d = opendir(dir.c_str());

    if (!d) {
      return false;
    }

    struct dirent *en;

    while ((en = readdir(d)) != 0) {
      std::string e = dir + en->d_name;

      if (regex_match(e, matches, dataFile)) {
        std::ifstream t(e);
        std::stringstream buffer;
        buffer << t.rdbuf();

        data[e] = buffer.str();

        const std::string &p = data[e];
        const char *data = p.c_str();
        size_t start = 0;
        enum { stN, stNL, stNLP } state = stN;

        for (size_t c = 0; c < p.size(); c++) {
          switch (data[c]) {
          case '\n':
            switch (state) {
            case stN:
              state = stNL;
              break;
            case stNLP:
              cookies.push_back(cookie(
                  doROT13, std::string(p.data() + start, c - start - 1), e));
              start = c + 1;
            default:
              state = stN;
              break;
            }
            break;

          case '%':
            switch (state) {
            case stNL:
              state = stNLP;
              break;
            default:
              state = stN;
              break;
            }
            break;

          case '\r':
            break;

          default:
            state = stN;
            break;
          }
        }
      }
    }
    closedir(d);

    return true;
  }

  const std::size_t size(void) const { return cookies.size(); }

  const cookie &get(std::size_t i) const {
    if (i < cookies.size()) {
      return cookies[i];
    }

    return get();
  }

  const cookie &get(void) const { return get((rand() % size())); }
};

template <class transport>
static bool fortune(typename net::http::server<transport>::session &session,
                    std::smatch &) {
  const auto &c = fortune::common().get();
  std::string sc = std::string(c);

  /* note: this escaping is not exactly efficient, but it's fairly simple
     and the std::strings are fairly short, so it shouldn't be much of an issue.
     */
  for (char i = 0; i < 0x20; i++) {
    if ((i == '\n') || (i == '\t')) {
      continue;
    }
    const char org[2] = {i, 0};
    const char rep[3] = {'^', (char)(('A' - 1) + i), 0};
    for (size_t pos = sc.find(org, pos); pos != std::string::npos;
         pos = sc.find(org, pos)) {
      sc.replace(pos, 2, rep);
      pos += 3;
    }
  }

  sc = "<![CDATA[" + sc + "]]>";

  session.reply(
      200, "Content-Type: text/xml; charset=utf-8\r\n",
      std::string("<?xml version='1.0' encoding='utf-8'?>"
                  "<fortune xmlns='http://ef.gy/2012/fortune' sourceFile='" +
                  c.file + "'>" + sc + "</fortune>"));

  return true;
}

namespace tcp {
using asio::ip::tcp;
static httpd::servlet<tcp> fortune("^/fortune$", ::fortune<tcp>);
static httpd::servlet<tcp> quit("^/quit$", httpd::quit<tcp>);
}

namespace unix {
using asio::local::stream_protocol;
static httpd::servlet<stream_protocol> fortune("^/fortune$",
                                               ::fortune<stream_protocol>);
static httpd::servlet<stream_protocol> quit("^/quit$",
                                            httpd::quit<stream_protocol>);
}

static cli::option
    count("count", [](std::smatch &m) -> bool {
                     std::cout << fortune::common().size()
                               << " cookie(s) loaded\n";

                     return true;
                   },
          "prints the number of fortune cookies in the database.");

static cli::option print("print(:([0-9]+))?",
                         [](std::smatch &m) -> bool {
                           if (m[1] != "") {
                             std::stringstream s(m[2]);
                             std::size_t n;
                             s >> n;
                             std::cout << std::string(fortune::common().get(n));
                           } else {
                             std::cout << std::string(fortune::common().get());
                           }

                           return true;
                         },
                         "print a fortune to stdout - a numerical parameter "
                         "selects a specific cookie.");

int main(int argc, char *argv[]) {
  fortune::common().prepare("/usr/share/games/fortunes/");
  fortune::common().prepare("/usr/share/games/fortunes/off/", true);

  srand(time(0));

  return io::main(argc, argv);
}
<|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2017 Ryo Suzuki
//	Copyright (c) 2016-2017 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# pragma once
# include "Fwd.hpp"
# include "Array.hpp"
# include "String.hpp"
# include "Rectangle.hpp"

namespace s3d
{
	struct Monitor
	{
		String name;
		String id;
		String displayDeviceName;
		Rect displayRect;
		Rect workArea;
		bool isPrimary;
	};

	namespace System
	{
		// [x] Windows | [x] macOS | [ ] Linux
		Array<Monitor> EnumActiveMonitors();

		// [x] Windows | [x] macOS | [ ] Linux
		size_t GetCurrentMonitorIndex();
	}
}
<commit_msg>Monitor.hpp<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2017 Ryo Suzuki
//	Copyright (c) 2016-2017 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# pragma once
# include "Fwd.hpp"
# include "Array.hpp"
# include "String.hpp"
# include "Rectangle.hpp"

namespace s3d
{
	struct Monitor
	{
		/// ディスプレイの名前
		String name;
		String id;
		/// 内部的に使われているディスプレイの名前
		String displayDeviceName;
		/// ディスプレイ全体の位置とサイズ
		Rect displayRect;
		/// タスクバーなどを除いた利用可能な領域の位置とサイズ
		Rect workArea;
		/// メインディスプレイかどうか
		bool isPrimary;
	};

	namespace System
	{
		///
		/// 使用可能なモニターの一覧を取得します。
		///
		/// <remarks>
		/// [x] Windows | [x] macOS | [ ] Linux
		/// </remarks>
		Array<Monitor> EnumActiveMonitors();

		///
		/// ウィンドウが配置されているモニターのインデックスを取得します。
		///
		/// <remarks>
		/// [x] Windows | [x] macOS | [ ] Linux
		/// </remarks>
		size_t GetCurrentMonitorIndex();
	}
}
<|endoftext|>


<commit_before>#include "function.h"
#include "math/epsilon.h"

using namespace nano;

function_t::function_t(const char* name,
        const tensor_size_t size, const tensor_size_t min_size, const tensor_size_t max_size,
        const convexity convex,
        const scalar_t domain) :
        m_name(name),
        m_size(size), m_min_size(min_size), m_max_size(max_size),
        m_convex(convex),
        m_domain(domain),
        m_fcalls(0), m_stoch_fcalls(0),
        m_gcalls(0), m_stoch_gcalls(0)
{
}

scalar_t function_t::eval(const vector_t& x, vector_t* gx) const
{
        assert(x.size() == size());

        m_fcalls ++;
        if (gx)
        {
                m_gcalls ++;
                gx->resize(size());
        }

        const auto f = vgrad(x, gx);
        assert(!gx || gx->size() == size());
        return f;
}

scalar_t function_t::stoch_eval(const vector_t& x, vector_t* gx) const
{
        assert(x.size() == size());

        m_stoch_fcalls ++;
        if (gx)
        {
                m_stoch_gcalls ++;
                gx->resize(size());
        }

        const auto f = stoch_vgrad(x, gx);
        assert(!gx || gx->size() == size());
        return f;
}

scalar_t function_t::grad_accuracy(const vector_t& x) const
{
        assert(x.size() == size());

        const auto n = size();

        vector_t gx(n);
        vector_t gx_approx(n);
        vector_t xp = x, xn = x;

        // analytical gradient
        const auto fx = vgrad(x, &gx);
        assert(gx.size() == size());

        // finite-difference approximated gradient
        //      see "Numerical optimization", Nocedal & Wright, 2nd edition, p.197
        const auto finite_difference = [&] (const scalar_t dx)
        {
                for (auto i = 0; i < n; i ++)
                {
                        xp = x; xp(i) += dx;
                        xn = x; xn(i) -= dx;

                        const auto dfi = vgrad(xp, nullptr) - vgrad(xn, nullptr);
                        const auto dxi = xp(i) - xn(i);
                        gx_approx(i) = dfi / dxi;

                        assert(std::isfinite(gx(i)));
                        assert(std::isfinite(gx_approx(i)));
                }

                return (gx - gx_approx).lpNorm<Eigen::Infinity>() / (1 + std::fabs(fx));
        };

        return finite_difference(epsilon2<scalar_t>());
}

bool function_t::is_convex(const vector_t& x1, const vector_t& x2, const int steps) const
{
        assert(steps > 2);
        assert(x1.size() == size());
        assert(x2.size() == size());

        const auto f1 = vgrad(x1, nullptr);
        assert(std::isfinite(f1));

        const auto f2 = vgrad(x2, nullptr);
        assert(std::isfinite(f2));

        for (int step = 1; step < steps; step ++)
        {
                const auto t1 = scalar_t(step) / scalar_t(steps);
                const auto t2 = scalar_t(1) - t1;
                const auto ftc = t1 * f1 + t2 * f2;

                const auto ft = vgrad(t1 * x1 + t2 * x2, nullptr);
                if (std::isfinite(ft) && ft > ftc + epsilon0<scalar_t>() * (1 + std::fabs(ftc)))
                {
                        return false;
                }
        }

        return true;
}

size_t function_t::fcalls() const
{
        return m_fcalls + m_stoch_fcalls / stoch_ratio();
}

size_t function_t::gcalls() const
{
        return m_gcalls + m_stoch_gcalls / stoch_ratio();
}

string_t function_t::name() const
{
        return string_t(m_name) + "[" + std::to_string(size()) + "D]";
}

bool function_t::is_valid(const vector_t& x) const
{
        return x.lpNorm<Eigen::Infinity>() < m_domain;
}
<commit_msg>use relative epsilon to check the gradient's accuracy<commit_after>#include "function.h"
#include "math/epsilon.h"

using namespace nano;

function_t::function_t(const char* name,
        const tensor_size_t size, const tensor_size_t min_size, const tensor_size_t max_size,
        const convexity convex,
        const scalar_t domain) :
        m_name(name),
        m_size(size), m_min_size(min_size), m_max_size(max_size),
        m_convex(convex),
        m_domain(domain),
        m_fcalls(0), m_stoch_fcalls(0),
        m_gcalls(0), m_stoch_gcalls(0)
{
}

scalar_t function_t::eval(const vector_t& x, vector_t* gx) const
{
        assert(x.size() == size());

        m_fcalls ++;
        if (gx)
        {
                m_gcalls ++;
                gx->resize(size());
        }

        const auto f = vgrad(x, gx);
        assert(!gx || gx->size() == size());
        return f;
}

scalar_t function_t::stoch_eval(const vector_t& x, vector_t* gx) const
{
        assert(x.size() == size());

        m_stoch_fcalls ++;
        if (gx)
        {
                m_stoch_gcalls ++;
                gx->resize(size());
        }

        const auto f = stoch_vgrad(x, gx);
        assert(!gx || gx->size() == size());
        return f;
}

scalar_t function_t::grad_accuracy(const vector_t& x) const
{
        assert(x.size() == size());

        const auto n = size();

        vector_t gx(n);
        vector_t gx_approx(n);
        vector_t xp = x, xn = x;

        // analytical gradient
        const auto fx = vgrad(x, &gx);
        assert(gx.size() == size());

        // finite-difference approximated gradient
        //      see "Numerical optimization", Nocedal & Wright, 2nd edition, p.197
        const auto finite_difference = [&] (const scalar_t dx)
        {
                for (auto i = 0; i < n; i ++)
                {
                        xp = x; xp(i) += dx * (1 + std::fabs(x(i)));
                        xn = x; xn(i) -= dx * (1 + std::fabs(x(i)));

                        const auto dfi = vgrad(xp, nullptr) - vgrad(xn, nullptr);
                        const auto dxi = xp(i) - xn(i);
                        gx_approx(i) = dfi / dxi;

                        assert(std::isfinite(gx(i)));
                        assert(std::isfinite(gx_approx(i)));
                }

                return (gx - gx_approx).lpNorm<Eigen::Infinity>() / (1 + std::fabs(fx));
        };

        return finite_difference(epsilon2<scalar_t>());
}

bool function_t::is_convex(const vector_t& x1, const vector_t& x2, const int steps) const
{
        assert(steps > 2);
        assert(x1.size() == size());
        assert(x2.size() == size());

        const auto f1 = vgrad(x1, nullptr);
        assert(std::isfinite(f1));

        const auto f2 = vgrad(x2, nullptr);
        assert(std::isfinite(f2));

        for (int step = 1; step < steps; step ++)
        {
                const auto t1 = scalar_t(step) / scalar_t(steps);
                const auto t2 = scalar_t(1) - t1;
                const auto ftc = t1 * f1 + t2 * f2;

                const auto ft = vgrad(t1 * x1 + t2 * x2, nullptr);
                if (std::isfinite(ft) && ft > ftc + epsilon0<scalar_t>() * (1 + std::fabs(ftc)))
                {
                        return false;
                }
        }

        return true;
}

size_t function_t::fcalls() const
{
        return m_fcalls + m_stoch_fcalls / stoch_ratio();
}

size_t function_t::gcalls() const
{
        return m_gcalls + m_stoch_gcalls / stoch_ratio();
}

string_t function_t::name() const
{
        return string_t(m_name) + "[" + std::to_string(size()) + "D]";
}

bool function_t::is_valid(const vector_t& x) const
{
        return x.lpNorm<Eigen::Infinity>() < m_domain;
}
<|endoftext|>


<commit_before>#include "Thermostat.h"
#include "Nose_Hoover_Chain.h"
#include "Andersen.h"
#include "Lowe_Andersen.h"
#include "Gaussian.h"
#include "Nose_Hoover.h"
#include "Thermostat_None.h"
#include "Berendsen.h"
#include "Bussi.h"

#include "Functions.h"
#include "consts.h"
using namespace consts;

#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;

/* ######################### */
int main(int argc, char* argv[]) {
	//default für  p,Temp,dtime,runs,warmlauf,ausgabe   :jedes xte wird ausgegeben
	double a_para[]{4, 20, 1E-15, 1E6, 1E3, 1};
	int			i_para{ 1 };
	string s_para{}, s_therm{};
	string	s_temp{}, s_pos_vel{};
	ofstream dat_temp{}, dat_pos_vel{};
	Thermostat *thermostat{};

	// Bestimmen der Parameter zur Initialisierung von Poly und Thermostat
	for (i_para = 1; i_para < min(7, argc); ++i_para) {
		if (is_number(argv[i_para])) a_para[i_para - 1] = stod(argv[i_para]);
		else break;
	}
	a_para[2] /= ref_time;

	while (i_para < argc - 1 && is_number(argv[i_para])) ++i_para;
	int i_thermos = i_para;

	while (++i_para < argc - 1 && is_number(argv[i_para])) ++i_para;
	int i_poly_init = min(argc - 1, i_para);

	Polymer poly{ static_cast<unsigned> (a_para[0]), a_para[1] };
	if (strcmp(argv[i_poly_init], "one") == 0)
		poly.initiate_monomers_one();
	else
		poly.initiate_monomers_random();

	// Auswählen des Thermostats
	if (argc > 1 && i_thermos < argc) {
		if (strcmp(argv[i_thermos], "Andersen") == 0) {
			double nu{ set_param(1. / a_para[2] / a_para[0], argv, argc, i_thermos + 1) };
			thermostat = new Andersen{ poly, a_para[2], nu };
			s_therm = "Andersen";
		}
		else if (strcmp(argv[i_thermos], "Lowe_Andersen") == 0) {
			double nu{ set_param(1. / a_para[2] / a_para[0], argv, argc, i_thermos + 1) };
			thermostat = new Lowe_Andersen{ poly, a_para[2], nu };
			s_therm = "Lowe_Andersen";
		}
		else if (strcmp(argv[i_thermos], "Gaussian") == 0) {
			thermostat = new Gaussian{ poly, a_para[2] };
			s_therm = "Gaussian";
		}
		else if (strcmp(argv[i_thermos], "Nose_Hoover") == 0) {
			double q_def{ poly.monomers.size()*poly.target_temperature()*ref_time / 1E-14 };
			double q{ set_param(q_def, argv, argc, i_thermos + 1) };
			thermostat = new Nose_Hoover{ poly, a_para[2], q };
			s_therm = "Nose_Hoover";
		}
		else if (strcmp(argv[i_thermos], "Nose_Hoover_Chain") == 0) {
			double q_def{ poly.monomers.size()*poly.target_temperature()*ref_time / 1E-14 };
			double q{ set_param(q_def, argv, argc, i_thermos + 1) };
			double q2 = 0; //changemeplease
			thermostat = new Nose_Hoover_Chain{ poly, a_para[2], q, q2 };
			s_therm = "Nose_Hoover_Chain";
		}
		else if (strcmp(argv[i_thermos], "Berendsen") == 0) {
			double couplingtime = 10 * a_para[2];
			thermostat = new Berendsen{ poly, a_para[2], couplingtime };
			s_therm = "Berendsen";
		}
		else if (strcmp(argv[i_thermos], "Bussi") == 0) {
			double couplingtime = 10 * a_para[2];
			thermostat = new Bussi{ poly, a_para[2], couplingtime };
			s_therm = "Bussi";
		}
		else {
			thermostat = new Thermostat_None{ poly, a_para[2] };
			s_therm = "None";
		}
	}
	else {
		thermostat = new Thermostat_None{ poly, a_para[2] };
		s_therm = "None";
	}
	cout << "Thermostat:\t" << s_therm << endl;
	s_para = "_p"; s_para += to_string((int)a_para[0]);
	s_para += "_T"; s_para += to_string((int)a_para[1]);

	s_temp = s_therm + "_temp" + s_para + ".dat";
	dat_temp.open(s_temp, ios::out | ios::trunc);

	s_pos_vel = s_therm + "_pos_vel" + s_para + ".dat";
	dat_pos_vel.open(s_pos_vel, ios::out | ios::trunc);

	// Simulation
	for (int i = 0; i < a_para[4]; ++i) thermostat->propagate();
	cout << "Warmlauf abgeschlossen" << endl;

	int index_print{ (int)(a_para[3] * 4E-1) };
	int index_to_file{ (int)a_para[5] };
	for (int i = 0; i < a_para[3]; i++) {
		if (!(i % index_to_file)) {
			dat_temp << i*a_para[2] << " " << poly.calculate_temp() << endl;
			dat_pos_vel << poly;
		}

		if (!(i % index_print)) {
			cout << i*a_para[2] << endl;
			cout << "Ekin: " << poly.update_ekin() << endl;
			cout << "T: " << poly.calculate_temp() << endl;
		}
		thermostat->propagate();
	}
	delete thermostat;

	cout << "<< Die Datei '" << s_temp << "' wurde erstellt." << endl;
	cout << "<< Die Datei '" << s_pos_vel << "' wurde erstellt." << endl;

	dat_temp.close();
	dat_pos_vel.close();
	return 0;
}

<commit_msg>NHC richtig initialisiert<commit_after>#include "Thermostat.h"
#include "Nose_Hoover_Chain.h"
#include "Andersen.h"
#include "Lowe_Andersen.h"
#include "Gaussian.h"
#include "Nose_Hoover.h"
#include "Thermostat_None.h"
#include "Berendsen.h"
#include "Bussi.h"

#include "Functions.h"
#include "consts.h"
using namespace consts;

#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;

/* ######################### */
int main(int argc, char* argv[]) {
	//default für  p,Temp,dtime,runs,warmlauf,ausgabe   :jedes xte wird ausgegeben
	double a_para[]{4, 20, 1E-15, 1E6, 1E3, 1};
	int			i_para{ 1 };
	string s_para{}, s_therm{};
	string	s_temp{}, s_pos_vel{};
	ofstream dat_temp{}, dat_pos_vel{};
	Thermostat *thermostat{};

	// Bestimmen der Parameter zur Initialisierung von Poly und Thermostat
	for (i_para = 1; i_para < min(7, argc); ++i_para) {
		if (is_number(argv[i_para])) a_para[i_para - 1] = stod(argv[i_para]);
		else break;
	}
	a_para[2] /= ref_time;

	while (i_para < argc - 1 && is_number(argv[i_para])) ++i_para;
	int i_thermos = i_para;

	while (++i_para < argc - 1 && is_number(argv[i_para])) ++i_para;
	int i_poly_init = min(argc - 1, i_para);

	Polymer poly{ static_cast<unsigned> (a_para[0]), a_para[1] };
	if (strcmp(argv[i_poly_init], "one") == 0)
		poly.initiate_monomers_one();
	else
		poly.initiate_monomers_random();

	// Auswählen des Thermostats
	if (argc > 1 && i_thermos < argc) {
		if (strcmp(argv[i_thermos], "Andersen") == 0) {
			double nu{ set_param(1. / a_para[2] / a_para[0], argv, argc, i_thermos + 1) };
			thermostat = new Andersen{ poly, a_para[2], nu };
			s_therm = "Andersen";
		}
		else if (strcmp(argv[i_thermos], "Lowe_Andersen") == 0) {
			double nu{ set_param(1. / a_para[2] / a_para[0], argv, argc, i_thermos + 1) };
			thermostat = new Lowe_Andersen{ poly, a_para[2], nu };
			s_therm = "Lowe_Andersen";
		}
		else if (strcmp(argv[i_thermos], "Gaussian") == 0) {
			thermostat = new Gaussian{ poly, a_para[2] };
			s_therm = "Gaussian";
		}
		else if (strcmp(argv[i_thermos], "Nose_Hoover") == 0) {
			double q_def{ poly.monomers.size()*poly.target_temperature()*ref_time / 1E-12 };
			double q{ set_param(q_def, argv, argc, i_thermos + 1) };
			thermostat = new Nose_Hoover{ poly, a_para[2], q };
			s_therm = "Nose_Hoover";
		}
		else if (strcmp(argv[i_thermos], "Nose_Hoover_Chain") == 0) {
		  double q_def{ poly.monomers.size()*poly.monomer_mass*poly.target_temperature()/poly.feder_konst() };
			double q{ set_param(q_def, argv, argc, i_thermos + 1) };
			double q2 = poly.monomer_mass*poly.target_temperature()/poly.feder_konst(); //changemeplease
			thermostat = new Nose_Hoover_Chain{ poly, a_para[2], q, q2 };
			s_therm = "Nose_Hoover_Chain";
		}
		else if (strcmp(argv[i_thermos], "Berendsen") == 0) {
			double couplingtime = 10 * a_para[2];
			thermostat = new Berendsen{ poly, a_para[2], couplingtime };
			s_therm = "Berendsen";
		}
		else if (strcmp(argv[i_thermos], "Bussi") == 0) {
			double couplingtime = 10 * a_para[2];
			thermostat = new Bussi{ poly, a_para[2], couplingtime };
			s_therm = "Bussi";
		}
		else {
			thermostat = new Thermostat_None{ poly, a_para[2] };
			s_therm = "None";
		}
	}
	else {
		thermostat = new Thermostat_None{ poly, a_para[2] };
		s_therm = "None";
	}
	cout << "Thermostat:\t" << s_therm << endl;
	s_para = "_p"; s_para += to_string((int)a_para[0]);
	s_para += "_T"; s_para += to_string((int)a_para[1]);

	s_temp = s_therm + "_temp" + s_para + ".dat";
	dat_temp.open(s_temp, ios::out | ios::trunc);

	s_pos_vel = s_therm + "_pos_vel" + s_para + ".dat";
	dat_pos_vel.open(s_pos_vel, ios::out | ios::trunc);

	// Simulation
	for (int i = 0; i < a_para[4]; ++i) thermostat->propagate();
	cout << "Warmlauf abgeschlossen" << endl;

	int index_print{ (int)(a_para[3] * 4E-1) };
	int index_to_file{ (int)a_para[5] };
	for (int i = 0; i < a_para[3]; i++) {
		if (!(i % index_to_file)) {
			dat_temp << i*a_para[2] << " " << poly.calculate_temp() << endl;
			dat_pos_vel << poly;
		}

		if (!(i % index_print)) {
			cout << i*a_para[2] << endl;
			cout << "Ekin: " << poly.update_ekin() << endl;
			cout << "T: " << poly.calculate_temp() << endl;
		}
		thermostat->propagate();
	}
	delete thermostat;

	cout << "<< Die Datei '" << s_temp << "' wurde erstellt." << endl;
	cout << "<< Die Datei '" << s_pos_vel << "' wurde erstellt." << endl;

	dat_temp.close();
	dat_pos_vel.close();
	return 0;
}

<|endoftext|>


<commit_before>#ifndef _ENTITY_SPRITE_HPP_
#define _ENTITY_SPRITE_HPP_

// ------------------------------------------------------------------------------------------------
#include "Entity.hpp"

// ------------------------------------------------------------------------------------------------
namespace SqMod {

/* ------------------------------------------------------------------------------------------------
 * ...
*/
class CSprite : public Reference< CSprite >
{
public:
    // --------------------------------------------------------------------------------------------
    using RefType::Reference;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void ShowAll() const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void ShowFor(const Reference< CPlayer > & player) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void ShowRange(SQInt32 first, SQInt32 last) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void HideAll() const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void HideFor(const Reference< CPlayer > & player) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void HideRange(SQInt32 first, SQInt32 last) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetPositionAll(const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetPositionAllEx(SQUint32 x, SQUint32 y) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetPositionFor(const Reference< CPlayer > & player, const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetPositionForEx(const Reference< CPlayer > & player, SQUint32 x, SQUint32 y) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetPositionRange(SQInt32 first, SQInt32 last, const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetCenterAll(const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetCenterAllEx(SQUint32 x, SQUint32 y) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetCenterFor(const Reference< CPlayer > & player, const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetCenterForEx(const Reference< CPlayer > & player, SQUint32 x, SQUint32 y) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetCenterRange(SQInt32 first, SQInt32 last, const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetRotationAll(SQFloat rot) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetRotationFor(const Reference< CPlayer > & player, SQFloat rot) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetRotationRange(SQInt32 first, SQInt32 last, SQFloat rot) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetAlphaAll(Uint8 alpha) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetAlphaFor(const Reference< CPlayer > & player, Uint8 alpha) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    void SetAlphaRange(SQInt32 first, SQInt32 last, Uint8 alpha) const noexcept;

    /* --------------------------------------------------------------------------------------------
     *
    */
    const SQChar * GetFilePath() const noexcept;
};

} // Namespace:: SqMod

#endif // _ENTITY_SPRITE_HPP_<commit_msg>Documented the Sprite type.<commit_after>#ifndef _ENTITY_SPRITE_HPP_
#define _ENTITY_SPRITE_HPP_

// ------------------------------------------------------------------------------------------------
#include "Entity.hpp"

// ------------------------------------------------------------------------------------------------
namespace SqMod {

/* ------------------------------------------------------------------------------------------------
 * Class responsible for managing the referenced sprite instance.
*/
class CSprite : public Reference< CSprite >
{
public:

    /* --------------------------------------------------------------------------------------------
     * Import the constructors, destructors and assignment operators from the base class.
    */
    using RefType::Reference;

    /* --------------------------------------------------------------------------------------------
     * Show the referenced sprite instance to all players on the server.
    */
    void ShowAll() const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Show the referenced sprite instance to the specified player instance.
    */
    void ShowFor(const Reference< CPlayer > & player) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Show the referenced sprite instance to all players in the specified range.
    */
    void ShowRange(SQInt32 first, SQInt32 last) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Hide the referenced sprite instance from all players on the server.
    */
    void HideAll() const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Hide the referenced sprite instance from the specified player instance.
    */
    void HideFor(const Reference< CPlayer > & player) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Hide the referenced sprite instance from all players in the specified range.
    */
    void HideRange(SQInt32 first, SQInt32 last) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the position of the referenced sprite instance for all players on the server.
    */
    void SetPositionAll(const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the position of the referenced sprite instance for all players on the server.
    */
    void SetPositionAllEx(SQUint32 x, SQUint32 y) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the position of the referenced sprite instance for the specified player instance.
    */
    void SetPositionFor(const Reference< CPlayer > & player, const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the position of the referenced sprite instance for the specified player instance.
    */
    void SetPositionForEx(const Reference< CPlayer > & player, SQUint32 x, SQUint32 y) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the position of the referenced sprite instance for all players in the specified range.
    */
    void SetPositionRange(SQInt32 first, SQInt32 last, const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the center of the referenced sprite instance for all players on the server.
    */
    void SetCenterAll(const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the center of the referenced sprite instance for all players on the server.
    */
    void SetCenterAllEx(SQUint32 x, SQUint32 y) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the center of the referenced sprite instance for the specified player instance.
    */
    void SetCenterFor(const Reference< CPlayer > & player, const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the center of the referenced sprite instance for the specified player instance.
    */
    void SetCenterForEx(const Reference< CPlayer > & player, SQUint32 x, SQUint32 y) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the center of the referenced sprite instance for all players in the specified range.
    */
    void SetCenterRange(SQInt32 first, SQInt32 last, const Vector2u & pos) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the rotation of the referenced sprite instance for all players on the server.
    */
    void SetRotationAll(SQFloat rot) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the rotation of the referenced sprite instance for the specified player instance.
    */
    void SetRotationFor(const Reference< CPlayer > & player, SQFloat rot) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the rotation of the referenced sprite instance for all players in the specified range.
    */
    void SetRotationRange(SQInt32 first, SQInt32 last, SQFloat rot) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the rotation of the referenced sprite instance for all players on the server.
    */
    void SetAlphaAll(Uint8 alpha) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the rotation of the referenced sprite instance for the specified player instance.
    */
    void SetAlphaFor(const Reference< CPlayer > & player, Uint8 alpha) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Set the rotation of the referenced sprite instance for all players in the specified range.
    */
    void SetAlphaRange(SQInt32 first, SQInt32 last, Uint8 alpha) const noexcept;

    /* --------------------------------------------------------------------------------------------
     * Retrieve the file path of the texture used by the referenced sprite instance.
    */
    const SQChar * GetFilePath() const noexcept;
};

} // Namespace:: SqMod

#endif // _ENTITY_SPRITE_HPP_<|endoftext|>


<commit_before>// -*- c++ -*-
/*
 * Copyright (C) 2017 Kuhn & Völkel GmbH
 *
 * 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 distribted 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.
 */

//
// ex-pcicclient_set_io.cpp
//
// Shows how to use the PCICClient module to control the IOs state
// of the camera.
//

#include <iostream>
#include <string>
#include <thread>
#include <o3d3xx_camera.h>
#include <o3d3xx_pcicclient.h>

// Camera configuration string:
// * Create and activate application with index 1
// * Set LogicGraph to control IOs state via PCIC interface
const char *config = R"CONFIG(
{
    "o3d3xx":
    {
        "Device":
        {
            "ActiveApplication": "1"
        },
        "Apps":
        [
            {
                "Name": "PCICClient Example",
                "Description": "Manipulates digital IOs",
                "Index" : "1",
                "LogicGraph": "{\n    \"IOMap\": {\n        \"OUT1\": \"PCIC_OUT\",\n        \"OUT2\": \"PCIC_OUT\"\n    },\n    \"blocks\": {\n        \"B00001\": {\n            \"pos\": {\n                \"x\": 262,\n                \"y\": 132\n            },\n            \"properties\": {\n            },\n            \"type\": \"PIN_EVENT_PCIC_O_CMD\"\n        },\n        \"B00003\": {\n            \"pos\": {\n                \"x\": 600,\n                \"y\": 75\n            },\n            \"properties\": {\n                \"pulse_duration\": 0\n            },\n            \"type\": \"DIGITAL_OUT1\"\n        },\n        \"B00005\": {\n            \"pos\": {\n                \"x\": 600,\n                \"y\": 200\n            },\n            \"properties\": {\n                \"pulse_duration\": 0\n            },\n            \"type\": \"DIGITAL_OUT2\"\n        }\n    },\n    \"connectors\": {\n        \"C00000\": {\n            \"dst\": \"B00003\",\n            \"dstEP\": 0,\n            \"src\": \"B00001\",\n            \"srcEP\": 0\n        },\n        \"C00001\": {\n            \"dst\": \"B00005\",\n            \"dstEP\": 0,\n            \"src\": \"B00001\",\n            \"srcEP\": 0\n        }\n    }\n}\n"
            }
        ]
    }
}
)CONFIG";

int main(int argc, char** argv)
{
  // Create camera
  o3d3xx::Camera::Ptr cam = std::make_shared<o3d3xx::Camera>();

  // Configure camera to allow user defined IO state
  cam->FromJSON(config);

  // Create pcic interface
  o3d3xx::PCICClient::Ptr pcic = std::make_shared<o3d3xx::PCICClient>(cam);

  // Start setting IOs (and led flashing)
  pcic->Call("o010"); // OUT1 off
  pcic->Call("o020"); // OUT2 off
  for(int i = 0; i < 10; ++i)
    {
      std::cout << "Pass " << (i+1) << "/" << 25 << std::endl;

      pcic->Call("o011"); // OUT1 on
      std::cout << "State: " << pcic->Call("O01?") << " " << pcic->Call("O02?") << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));

      pcic->Call("o021"); // OUT2 on
      std::cout << "State: " << pcic->Call("O01?") << " " << pcic->Call("O02?") << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));

      pcic->Call("o010"); // OUT1 off
      std::cout << "State: " << pcic->Call("O01?") << " " << pcic->Call("O02?") << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));

      pcic->Call("o020"); // OUT2 off
      std::cout << "State: " << pcic->Call("O01?") << " " << pcic->Call("O02?") << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));

      std::cout << std::endl;
    }

  return 0;
}
<commit_msg>Correct printing overall number of passes ..<commit_after>// -*- c++ -*-
/*
 * Copyright (C) 2017 Kuhn & Völkel GmbH
 *
 * 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 distribted 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.
 */

//
// ex-pcicclient_set_io.cpp
//
// Shows how to use the PCICClient module to control the IOs state
// of the camera.
//

#include <iostream>
#include <string>
#include <thread>
#include <o3d3xx_camera.h>
#include <o3d3xx_pcicclient.h>

// Camera configuration string:
// * Create and activate application with index 1
// * Set LogicGraph to control IOs state via PCIC interface
const char *config = R"CONFIG(
{
    "o3d3xx":
    {
        "Device":
        {
            "ActiveApplication": "1"
        },
        "Apps":
        [
            {
                "Name": "PCICClient Example",
                "Description": "Manipulates digital IOs",
                "Index" : "1",
                "LogicGraph": "{\n    \"IOMap\": {\n        \"OUT1\": \"PCIC_OUT\",\n        \"OUT2\": \"PCIC_OUT\"\n    },\n    \"blocks\": {\n        \"B00001\": {\n            \"pos\": {\n                \"x\": 262,\n                \"y\": 132\n            },\n            \"properties\": {\n            },\n            \"type\": \"PIN_EVENT_PCIC_O_CMD\"\n        },\n        \"B00003\": {\n            \"pos\": {\n                \"x\": 600,\n                \"y\": 75\n            },\n            \"properties\": {\n                \"pulse_duration\": 0\n            },\n            \"type\": \"DIGITAL_OUT1\"\n        },\n        \"B00005\": {\n            \"pos\": {\n                \"x\": 600,\n                \"y\": 200\n            },\n            \"properties\": {\n                \"pulse_duration\": 0\n            },\n            \"type\": \"DIGITAL_OUT2\"\n        }\n    },\n    \"connectors\": {\n        \"C00000\": {\n            \"dst\": \"B00003\",\n            \"dstEP\": 0,\n            \"src\": \"B00001\",\n            \"srcEP\": 0\n        },\n        \"C00001\": {\n            \"dst\": \"B00005\",\n            \"dstEP\": 0,\n            \"src\": \"B00001\",\n            \"srcEP\": 0\n        }\n    }\n}\n"
            }
        ]
    }
}
)CONFIG";

int main(int argc, char** argv)
{
  // Create camera
  o3d3xx::Camera::Ptr cam = std::make_shared<o3d3xx::Camera>();

  // Configure camera to allow user defined IO state
  cam->FromJSON(config);

  // Create pcic interface
  o3d3xx::PCICClient::Ptr pcic = std::make_shared<o3d3xx::PCICClient>(cam);

  // Start setting IOs (and led flashing)
  pcic->Call("o010"); // OUT1 off
  pcic->Call("o020"); // OUT2 off
  for(int i = 0; i < 10; ++i)
    {
      std::cout << "Pass " << (i+1) << "/" << 10 << std::endl;

      pcic->Call("o011"); // OUT1 on
      std::cout << "State: " << pcic->Call("O01?") << " " << pcic->Call("O02?") << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));

      pcic->Call("o021"); // OUT2 on
      std::cout << "State: " << pcic->Call("O01?") << " " << pcic->Call("O02?") << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));

      pcic->Call("o010"); // OUT1 off
      std::cout << "State: " << pcic->Call("O01?") << " " << pcic->Call("O02?") << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));

      pcic->Call("o020"); // OUT2 off
      std::cout << "State: " << pcic->Call("O01?") << " " << pcic->Call("O02?") << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));

      std::cout << std::endl;
    }

  return 0;
}
<|endoftext|>


<commit_before>/*
 * SessionConnections.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "SessionConnections.hpp"

#include <core/Log.hpp>
#include <core/Error.hpp>
#include <core/Exec.hpp>

#include <session/SessionModuleContext.hpp>

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace modules {
namespace connections {

namespace {

} // anonymous namespace

bool connectionsEnabled()
{
   return module_context::isPackageInstalled("spark");
}

Error initialize()
{

   using boost::bind;
   using namespace module_context;
   ExecBlock initBlock ;
   initBlock.addFunctions()
      (bind(sourceModuleRFile, "SessionConnections.R"));

   return initBlock.execute();
}

} // namespace connections
} // namespace modules
} // namesapce session
} // namespace rstudio

<commit_msg>enable connections when requisite packages are installed<commit_after>/*
 * SessionConnections.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "SessionConnections.hpp"

#include <boost/foreach.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/predicate.hpp>

#include <core/Log.hpp>
#include <core/Error.hpp>
#include <core/Exec.hpp>

#include <session/SessionModuleContext.hpp>

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace modules {
namespace connections {

namespace {

// track last reported state of connections enabled
bool s_reportedConnectionsEnabled = false;

void onInstalledPackagesChanged()
{
   // reload the IDE if connections should be enabled but they were
   // last reported as disabled
   if (!s_reportedConnectionsEnabled && connectionsEnabled())
   {
      ClientEvent event(client_events::kReloadWithLastChanceSave);
      module_context::enqueClientEvent(event);
   }
}

} // anonymous namespace

bool connectionsEnabled()
{
   // track last reported state of connections enabled
   s_reportedConnectionsEnabled = module_context::isPackageInstalled("rspark");

   // return value
   return s_reportedConnectionsEnabled;
}

Error initialize()
{
   // connect to events to track whether we should enable connections
   module_context::events().onPackageLibraryMutated.connect(
                                             onInstalledPackagesChanged);

   using boost::bind;
   using namespace module_context;
   ExecBlock initBlock ;
   initBlock.addFunctions()
      (bind(sourceModuleRFile, "SessionConnections.R"));

   return initBlock.execute();
}

} // namespace connections
} // namespace modules
} // namesapce session
} // namespace rstudio

<|endoftext|>