<commit_before>/**
 * @file
 */
#include "libbirch/Memo.hpp"

#include "libbirch/SwapClone.hpp"
#include "libbirch/SwapContext.hpp"

bi::Memo::Memo() :
    isForked(false) {
  //
}

bi::Memo::Memo(Memo* parent, const bool isForwarding) :
    cloneParent(isForwarding ? nullptr : parent),
    forwardParent(isForwarding ? parent : nullptr),
    isForked(false) {
  //
}

bi::Memo::~Memo() {
  //
}

bool bi::Memo::hasAncestor(Memo* memo) const {
  SharedPtr<Memo> parent = getParent();
  return parent && (parent == memo || parent->hasAncestor(memo));
}

bi::Memo* bi::Memo::fork() {
  #if USE_LAZY_DEEP_CLONE
  isForked = true;
  #endif
  return create(this, false);
}

void bi::Memo::clean() {
  auto parent = getParent();
  if (parent) {
    parent->clean();
  }
  clones.clean();
}

bi::Memo* bi::Memo::forwardGet() {
  #if USE_LAZY_DEEP_CLONE
  ///@todo make this thread safe
  if (forwardChild) {
    return forwardChild->forwardGet();
  } else if (isForked) {
    forwardChild = create(this, true);
    clean();
    return forwardChild.get();
  } else {
    return this;
  }
  #else
  return this;
  #endif
}

bi::Memo* bi::Memo::forwardPull() {
  #if USE_LAZY_DEEP_CLONE
  return forwardChild ? forwardChild->forwardPull() : this;
  #else
  return this;
  #endif
}

bi::SharedPtr<bi::Memo> bi::Memo::getParent() const {
  return cloneParent ? cloneParent : SharedPtr<Memo>(forwardParent);
}

bi::Any* bi::Memo::get(Any* o) {
  if (!o || o->getContext() == this) {
    return o;
  } else {
    Any* result = clones.get(o);
    if (!result) {
      #if USE_LAZY_DEEP_CLONE
      /* for a lazy deep clone there is no risk of infinite recursion, but
       * there may be thread contention if two threads access the same object
       * and both trigger a lazy clone simultaneously; in this case multiple
       * new objects may be made but only one thread can be successful in
       * inserting an object into the map; a shared pointer is used to
       * destroy any additional objects */
      SwapClone swapClone(true);
      SwapContext swapContext(this);
      SharedPtr<Any> cloned = o->clone();
      // ^ use shared to clean up if beaten by another thread
      result = clones.put(o, cloned.get());
      #else
      /* for an eager deep clone we must be cautious to avoid infinite
       * recursion; memory for the new object is allocated first and put
       * in the map in case of deeper pointers back to the same object; then
       * the new object is constructed; there is no risk of another thread
       * accessing the uninitialized memory as the deep clone is not
       * accessible to other threads until completion; the new object will
       * at least have completed the Counted() constructor to initialize
       * reference counts before any recursive clones occur */
      Any* alloc = static_cast<Any*>(allocate(o->getSize()));
      assert(alloc);
      Any* uninit = m->clones.uninitialized_put(o, alloc);
      assert(uninit == alloc);  // should be no thread contention here
      SwapClone swapClone(true);
      SwapContext swapContext(this);
      result = o->clone(uninit);
      assert(result == uninit);  // clone should be in the allocation
      o->incMemo();  // uninitialized_put(), so responsible for ref counts
      result->incShared();
      #endif
    }
    return result;
  }
}

bi::Any* bi::Memo::pull(Any* o) {
  if (!o || o->getContext() == this) {
    return o;
  } else {
    return clones.get(o, o);
  }
}

bi::Any* bi::Memo::deep(Any* o) {
  if (!o || o->getContext() == this) {
    return o;
  } else {
    Any* result = clones.get(o);
    if (!result) {
      auto parent = getParent();
      if (parent) {
        result = parent->deep(o);
        if (result != o) {
          result = clones.get(result, result);
        }
      } else {
        result = o;
      }
      result = clones.put(o, result);
    }
    return result;
  }
}
<commit_msg>Made new sweep clean shallow rather than recursing all the way back to root memo. Won't generalise well, but sufficient for current use cases.<commit_after>/**
 * @file
 */
#include "libbirch/Memo.hpp"

#include "libbirch/SwapClone.hpp"
#include "libbirch/SwapContext.hpp"

bi::Memo::Memo() :
    isForked(false) {
  //
}

bi::Memo::Memo(Memo* parent, const bool isForwarding) :
    cloneParent(isForwarding ? nullptr : parent),
    forwardParent(isForwarding ? parent : nullptr),
    isForked(false) {
  //
}

bi::Memo::~Memo() {
  //
}

bool bi::Memo::hasAncestor(Memo* memo) const {
  SharedPtr<Memo> parent = getParent();
  return parent && (parent == memo || parent->hasAncestor(memo));
}

bi::Memo* bi::Memo::fork() {
  #if USE_LAZY_DEEP_CLONE
  isForked = true;
  #endif
  return create(this, false);
}

void bi::Memo::clean() {
  /* for current use cases, just clean the current memo, not parents */
  //auto parent = getParent();
  //if (parent) {
  //  parent->clean();
  //}
  clones.clean();
}

bi::Memo* bi::Memo::forwardGet() {
  #if USE_LAZY_DEEP_CLONE
  ///@todo make this thread safe
  if (forwardChild) {
    return forwardChild->forwardGet();
  } else if (isForked) {
    forwardChild = create(this, true);
    clean();
    return forwardChild.get();
  } else {
    return this;
  }
  #else
  return this;
  #endif
}

bi::Memo* bi::Memo::forwardPull() {
  #if USE_LAZY_DEEP_CLONE
  return forwardChild ? forwardChild->forwardPull() : this;
  #else
  return this;
  #endif
}

bi::SharedPtr<bi::Memo> bi::Memo::getParent() const {
  return cloneParent ? cloneParent : SharedPtr<Memo>(forwardParent);
}

bi::Any* bi::Memo::get(Any* o) {
  if (!o || o->getContext() == this) {
    return o;
  } else {
    Any* result = clones.get(o);
    if (!result) {
      #if USE_LAZY_DEEP_CLONE
      /* for a lazy deep clone there is no risk of infinite recursion, but
       * there may be thread contention if two threads access the same object
       * and both trigger a lazy clone simultaneously; in this case multiple
       * new objects may be made but only one thread can be successful in
       * inserting an object into the map; a shared pointer is used to
       * destroy any additional objects */
      SwapClone swapClone(true);
      SwapContext swapContext(this);
      SharedPtr<Any> cloned = o->clone();
      // ^ use shared to clean up if beaten by another thread
      result = clones.put(o, cloned.get());
      #else
      /* for an eager deep clone we must be cautious to avoid infinite
       * recursion; memory for the new object is allocated first and put
       * in the map in case of deeper pointers back to the same object; then
       * the new object is constructed; there is no risk of another thread
       * accessing the uninitialized memory as the deep clone is not
       * accessible to other threads until completion; the new object will
       * at least have completed the Counted() constructor to initialize
       * reference counts before any recursive clones occur */
      Any* alloc = static_cast<Any*>(allocate(o->getSize()));
      assert(alloc);
      Any* uninit = m->clones.uninitialized_put(o, alloc);
      assert(uninit == alloc);  // should be no thread contention here
      SwapClone swapClone(true);
      SwapContext swapContext(this);
      result = o->clone(uninit);
      assert(result == uninit);  // clone should be in the allocation
      o->incMemo();  // uninitialized_put(), so responsible for ref counts
      result->incShared();
      #endif
    }
    return result;
  }
}

bi::Any* bi::Memo::pull(Any* o) {
  if (!o || o->getContext() == this) {
    return o;
  } else {
    return clones.get(o, o);
  }
}

bi::Any* bi::Memo::deep(Any* o) {
  if (!o || o->getContext() == this) {
    return o;
  } else {
    Any* result = clones.get(o);
    if (!result) {
      auto parent = getParent();
      if (parent) {
        result = parent->deep(o);
        if (result != o) {
          result = clones.get(result, result);
        }
      } else {
        result = o;
      }
      result = clones.put(o, result);
    }
    return result;
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 - 2021 gary@drinkingtea.net
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include <ox/std/types.hpp>
#include <ox/std/vector.hpp>

namespace nostalgia::scene {

struct TileDoc {

	constexpr static auto Fields = 2;
	constexpr static auto Preloadable = true;
	constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Tile";
	constexpr static auto TypeVersion = 1;

	uint16_t sheetIdx = 0;
	uint8_t  type = 0;

};

struct SceneDoc {

	using TileMapRow = ox::Vector<TileDoc>;
	using TileMapLayer = ox::Vector<TileMapRow>;
	using TileMap = ox::Vector<TileMapLayer>;

	constexpr static auto Fields = 1;
	constexpr static auto Preloadable = true;
	constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Scene";
	constexpr static auto TypeVersion = 1;

	TileMap tiles;

};

struct SceneInstance {

	uint16_t layers = 0;
	uint16_t *columns = nullptr;
	uint16_t *rows = nullptr;
	uint16_t **tileMapIdx = nullptr;
	uint8_t  **tileType = nullptr;

};

}
<commit_msg>[nostalgia/scene] Add models for Doc types<commit_after>/*
 * Copyright 2016 - 2021 gary@drinkingtea.net
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include <ox/std/error.hpp>
#include <ox/std/types.hpp>
#include <ox/std/vector.hpp>

namespace nostalgia::scene {

struct TileDoc {

	constexpr static auto Fields = 2;
	constexpr static auto Preloadable = true;
	constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Tile";
	constexpr static auto TypeVersion = 1;

	uint16_t sheetIdx = 0;
	uint8_t  type = 0;

};

template<typename T>
constexpr ox::Error model(T *io, TileDoc *obj) {
	io->template setTypeInfo<TileDoc>();
	oxReturnError(io->field("sheetIdx", &obj->sheetIdx));
	oxReturnError(io->field("type", &obj->type));
	return OxError(0);
}

struct SceneDoc {

	using TileMapRow = ox::Vector<TileDoc>;
	using TileMapLayer = ox::Vector<TileMapRow>;
	using TileMap = ox::Vector<TileMapLayer>;

	constexpr static auto Fields = 1;
	constexpr static auto Preloadable = true;
	constexpr static auto TypeName = "net.drinkingtea.nostalgia.scene.Scene";
	constexpr static auto TypeVersion = 1;

	TileMap tiles;

};

template<typename T>
constexpr ox::Error model(T *io, SceneDoc *obj) {
	io->template setTypeInfo<SceneDoc>();
	oxReturnError(io->field("tiles", &obj->tiles));
	return OxError(0);
}

struct SceneInstance {

	uint16_t layers = 0;
	uint16_t *columns = nullptr;
	uint16_t *rows = nullptr;
	uint16_t **tileMapIdx = nullptr;
	uint8_t  **tileType = nullptr;

};

}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <queue>

// template <class T, class Container = vector<T>,
//           class Compare = less<typename Container::value_type>>
// class priority_queue
// {
// public:
//     typedef Container                                container_type;
//     typedef Compare                                  value_compare; // LWG#2684
//     typedef typename container_type::value_type      value_type;
//     typedef typename container_type::reference       reference;
//     typedef typename container_type::const_reference const_reference;
//     typedef typename container_type::size_type       size_type;
//
// protected:
//     container_type c;
//     Compare comp;

#include <queue>
#include <cassert>
#include <type_traits>

struct test
    : private std::priority_queue<int>
{
    test()
    {
        c.push_back(1);
        assert(comp(1, 2));
    }
};

struct C
{
    typedef int value_type;
    typedef int& reference;
    typedef const int& const_reference;
    typedef int size_type;
};

int main()
{
    static_assert(( std::is_same<std::priority_queue<int>::container_type, std::vector<int> >::value), "");
    static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::container_type, std::deque<int> >::value), "");
    static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::value_type, int>::value), "");
    static_assert(( std::is_same<std::priority_queue<int>::reference, std::vector<int>::reference>::value), "");
    static_assert(( std::is_same<std::priority_queue<int>::const_reference, std::vector<int>::const_reference>::value), "");
    static_assert(( std::is_same<std::priority_queue<int>::size_type, std::vector<int>::size_type>::value), "");
    static_assert(( std::is_same<std::priority_queue<int>::value_compare, std::less<int> >::value), "");
    static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::value_compare, std::less<int> >::value), "");
    static_assert(( std::is_same<std::priority_queue<int, std::deque<int>, std::greater<int> >::value_compare, std::greater<int> >::value), "");
    static_assert(( std::uses_allocator<std::priority_queue<int>, std::allocator<int> >::value), "");
    static_assert((!std::uses_allocator<std::priority_queue<int, C>, std::allocator<int> >::value), "");
    test t;
}
<commit_msg>Add includes in test. Patch from STL@microsoft.com<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <queue>

// template <class T, class Container = vector<T>,
//           class Compare = less<typename Container::value_type>>
// class priority_queue
// {
// public:
//     typedef Container                                container_type;
//     typedef Compare                                  value_compare; // LWG#2684
//     typedef typename container_type::value_type      value_type;
//     typedef typename container_type::reference       reference;
//     typedef typename container_type::const_reference const_reference;
//     typedef typename container_type::size_type       size_type;
//
// protected:
//     container_type c;
//     Compare comp;

#include <queue>
#include <cassert>
#include <deque>
#include <functional>
#include <memory>
#include <type_traits>
#include <vector>

struct test
    : private std::priority_queue<int>
{
    test()
    {
        c.push_back(1);
        assert(comp(1, 2));
    }
};

struct C
{
    typedef int value_type;
    typedef int& reference;
    typedef const int& const_reference;
    typedef int size_type;
};

int main()
{
    static_assert(( std::is_same<std::priority_queue<int>::container_type, std::vector<int> >::value), "");
    static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::container_type, std::deque<int> >::value), "");
    static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::value_type, int>::value), "");
    static_assert(( std::is_same<std::priority_queue<int>::reference, std::vector<int>::reference>::value), "");
    static_assert(( std::is_same<std::priority_queue<int>::const_reference, std::vector<int>::const_reference>::value), "");
    static_assert(( std::is_same<std::priority_queue<int>::size_type, std::vector<int>::size_type>::value), "");
    static_assert(( std::is_same<std::priority_queue<int>::value_compare, std::less<int> >::value), "");
    static_assert(( std::is_same<std::priority_queue<int, std::deque<int> >::value_compare, std::less<int> >::value), "");
    static_assert(( std::is_same<std::priority_queue<int, std::deque<int>, std::greater<int> >::value_compare, std::greater<int> >::value), "");
    static_assert(( std::uses_allocator<std::priority_queue<int>, std::allocator<int> >::value), "");
    static_assert((!std::uses_allocator<std::priority_queue<int, C>, std::allocator<int> >::value), "");
    test t;
}
<|endoftext|>


<commit_before>#include <test/unit/math/test_ad.hpp>
#include <test/unit/math/mix/fun/offset_multiplier_constrain_matvar_helpers.hpp>

// real[], real[], real[]
// real[], real, real[]
// real[], real[], real
TEST(mathMixMatFun, offset_multiplier_constrain_matvar_stdvec_constrain) {
  std::vector<double> A{5.0, 2.0, 4.0, -2.0};
  std::vector<double> mum{-3.0, 3.0, -6.0, 6.0};
  std::vector<double> sigmam{-1.0, 5.0, 0.0, 38.0};
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mum, sigmam);
  double mud = -6.0;
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mud, sigmam);
  double sigmad = 8.0;
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mud, sigmad);
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mum, sigmad);
}

// array matrix[], array matrix[], array matrix[]
// array matrix[], array matrix[], matrix[]
// array matrix[], matrix[], array matrix[]
// array matrix[], matrix[], matrix[]
// array matrix[], array matrix[], real
// array matrix[], real, array matrix[]
// array matrix[], matrix[], real
// array matrix[], real, matrix[]
// array matrix[], real, real
TEST(mathMixMatFun, offset_multiplier_matvar_stdvec_mat_scalar_constrain) {
  Eigen::MatrixXd A_inner(2, 3);
  // swapping 0.0000001 for 0 causes a failure for the hessian?
  A_inner << 5.0, 2.0, 4.0, -2.0, 0.0000001, 0.1;
  Eigen::MatrixXd mu_inner(2, 3);
  mu_inner << -1.0, 1.0, -6.0, 1.0, 0.0, 0.01;
  Eigen::MatrixXd sigma_inner(2, 3);
  sigma_inner << 6.0, 3.0, 12.0, 38.0, 0.1, 0.15;

  std::vector<Eigen::MatrixXd> A{A_inner, A_inner};
  std::vector<Eigen::MatrixXd> mu_vec{mu_inner, mu_inner};
  std::vector<Eigen::MatrixXd> sigma_vec{sigma_inner, sigma_inner};
  double mu_scal = -1.0;
  double sigma_scal = 7.0;
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mu_scal, sigma_inner);
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mu_inner, sigma_scal);
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mu_scal, sigma_scal);
}
<commit_msg>breakup offset_mul tests more<commit_after>#include <test/unit/math/test_ad.hpp>
#include <test/unit/math/mix/fun/offset_multiplier_constrain_matvar_helpers.hpp>

// array matrix[], array matrix[], array matrix[]
// array matrix[], array matrix[], matrix[]
// array matrix[], matrix[], array matrix[]
// array matrix[], matrix[], matrix[]
// array matrix[], array matrix[], real
// array matrix[], real, array matrix[]
// array matrix[], matrix[], real
// array matrix[], real, matrix[]
// array matrix[], real, real
TEST(mathMixMatFun, offset_multiplier_matvar_stdvec_mat_scalar_constrain) {
  Eigen::MatrixXd A_inner(2, 3);
  // swapping 0.0000001 for 0 causes a failure for the hessian?
  A_inner << 5.0, 2.0, 4.0, -2.0, 0.0000001, 0.1;
  Eigen::MatrixXd mu_inner(2, 3);
  mu_inner << -1.0, 1.0, -6.0, 1.0, 0.0, 0.01;
  Eigen::MatrixXd sigma_inner(2, 3);
  sigma_inner << 6.0, 3.0, 12.0, 38.0, 0.1, 0.15;

  std::vector<Eigen::MatrixXd> A{A_inner, A_inner};
  std::vector<Eigen::MatrixXd> mu_vec{mu_inner, mu_inner};
  std::vector<Eigen::MatrixXd> sigma_vec{sigma_inner, sigma_inner};
  double mu_scal = -1.0;
  double sigma_scal = 7.0;
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mu_scal, sigma_inner);
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mu_inner, sigma_scal);
  offset_multiplier_constrain_tests::expect_vec_matvar(A, mu_scal, sigma_scal);
}
<|endoftext|>


<commit_before>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* fermin at tid dot es
*
* Author: Ken Zangelin
*/
#include "gtest/gtest.h"

#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"
#include "common/globals.h"

#include "convenience/RegisterProviderRequest.h"
#include "convenience/UpdateContextElementRequest.h"
#include "convenience/UpdateContextElementResponse.h"
#include "convenienceMap/mapPutIndividualContextEntity.h"
#include "convenienceMap/mapDeleteIndividualContextEntity.h"
#include "mongoBackend/mongoRegisterContext.h"
#include "ngsi9/RegisterContextResponse.h"
#include "ngsi9/DiscoverContextAvailabilityResponse.h"
#include "testInit.h"
#include "commonMocks.h"

using ::testing::_;
using ::testing::Throw;
using ::testing::Return;

/* ****************************************************************************
*
* prepareDatabase -
*/
static void prepareDatabase(std::string id, std::string type)
{
  /* Set database */
  setupDatabase();

  DBClientConnection* connection = getMongoConnection();

  /* We create one entity:
   *
   * - 'id', 'type' with four attributes
   *     A1: X
   *     A1: Y
   *     A2: Z
   *     A3: W
   */

  BSONObj en1 = BSON("_id" << BSON("id" << id << "type" << type) <<
                     "attrs" << BSON_ARRAY(
                        BSON("name" << "A1" << "type" << "TA1" << "value" << "X") <<
                        BSON("name" << "A1" << "type" << "TA1bis" << "value" << "Y") <<
                        BSON("name" << "A2" << "type" << "TA2" << "value" << "Z") <<
                        BSON("name" << "A3" << "type" << "TA3" << "value" << "W")
                        )
     );

  connection->insert(ENTITIES_COLL, en1);
}

/* ****************************************************************************
*
* notFoundThenFound -
*/
TEST(mapPutIndividualContextEntity, notFoundThenFound)
{
  HttpStatusCode                ms;
  UpdateContextElementRequest   request;
  UpdateContextElementResponse  response;

  /* Set timer */
  Timer* t = new Timer();
  setTimer(t);

  prepareDatabase("MPICE", "ttt");
  request.attributeDomainName.set("ad");

  ms = mapPutIndividualContextEntity("MPICE", &request, &response);
  EXPECT_EQ(SccOk, ms);
  EXPECT_EQ(200, response.errorCode.code);

  ms = mapPutIndividualContextEntity("MPICE2", &request, &response);
  EXPECT_EQ(SccOk, ms);
  // FIXME: next should be change 404 -> 200 in the case PUT is interpreted as POST in this case, but
  // not sure...
  EXPECT_EQ(404, response.errorCode.code);

  // Cleanup
  StatusCode sCode;
  mapDeleteIndividualContextEntity("MPICE", &sCode);
}
<commit_msg>FIX unit test mapPutIndividualContextEntity.createTwoEntities<commit_after>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* fermin at tid dot es
*
* Author: Ken Zangelin
*/
#include "gtest/gtest.h"

#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"
#include "common/globals.h"

#include "convenience/RegisterProviderRequest.h"
#include "convenience/UpdateContextElementRequest.h"
#include "convenience/UpdateContextElementResponse.h"
#include "convenienceMap/mapPutIndividualContextEntity.h"
#include "convenienceMap/mapDeleteIndividualContextEntity.h"
#include "mongoBackend/mongoRegisterContext.h"
#include "ngsi9/RegisterContextResponse.h"
#include "ngsi9/DiscoverContextAvailabilityResponse.h"
#include "testInit.h"
#include "commonMocks.h"

using ::testing::_;
using ::testing::Throw;
using ::testing::Return;

/* ****************************************************************************
*
* prepareDatabase -
*/
static void prepareDatabase(std::string id, std::string type)
{
  /* Set database */
  setupDatabase();

  DBClientConnection* connection = getMongoConnection();

  /* We create one entity:
   *
   * - 'id', 'type' with four attributes
   *     A1: X
   *     A1: Y
   *     A2: Z
   *     A3: W
   */

  BSONObj en1 = BSON("_id" << BSON("id" << id << "type" << type) <<
                     "attrs" << BSON_ARRAY(
                        BSON("name" << "A1" << "type" << "TA1" << "value" << "X") <<
                        BSON("name" << "A1" << "type" << "TA1bis" << "value" << "Y") <<
                        BSON("name" << "A2" << "type" << "TA2" << "value" << "Z") <<
                        BSON("name" << "A3" << "type" << "TA3" << "value" << "W")
                        )
     );

  connection->insert(ENTITIES_COLL, en1);
}

/* ****************************************************************************
*
* notFoundThenFound -
*/
TEST(mapPutIndividualContextEntity, createTwoEntities)
{
  HttpStatusCode                ms;
  UpdateContextElementRequest   request;
  UpdateContextElementResponse  response;

  /* Set timer */
  Timer* t = new Timer();
  setTimer(t);

  prepareDatabase("MPICE", "ttt");
  request.attributeDomainName.set("ad");

  ms = mapPutIndividualContextEntity("MPICE", &request, &response);
  EXPECT_EQ(SccOk, ms);
  EXPECT_EQ(200, response.errorCode.code);

  ms = mapPutIndividualContextEntity("MPICE2", &request, &response);
  EXPECT_EQ(SccOk, ms);
  EXPECT_EQ(200, response.errorCode.code);

  // Cleanup
  StatusCode sCode;
  mapDeleteIndividualContextEntity("MPICE", &sCode);
}
<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     test_spectral_connectivity.cpp
* @author   Daniel Strohmeier <daniel.strohmeier@tu-ilmenau.de>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     May, 2018
*
* @section  LICENSE
*
* Copyright (C) 2018, Daniel Strohmeier and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    The spectral connectivity test implementation
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <iostream>
#include <mne/mne.h>
#include <utils/ioutils.h>
#include "connectivity/metrics/coherence.h"
#include "connectivity/metrics/imagcoherence.h"
#include "connectivity/metrics/phaselockingvalue.h"
#include "connectivity/metrics/phaselagindex.h"
#include "connectivity/metrics/unbiasedsquaredphaselagindex.h"
#include "connectivity/metrics/weightedphaselagindex.h"
#include "connectivity/metrics/debiasedsquaredweightedphaselagindex.h"

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtTest>

//*************************************************************************************************************
//=============================================================================================================
// Eigen INCLUDES
//=============================================================================================================

#include <Eigen/Core>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace Eigen;
using namespace CONNECTIVITYLIB;
using namespace UTILSLIB;

//=============================================================================================================
/**
* DECLARE CLASS TestSpectralConnectivity
*
* @brief The TestSpectralConnectivity class provides spectral connectivity tests
*
*/
class TestSpectralConnectivity: public QObject
{
    Q_OBJECT

public:
    TestSpectralConnectivity();

private slots:
    void initTestCase();
    void spectralConnectivityCoherence();
    void spectralConnectivityImagCoherence();
    void spectralConnectivityPLV();
    void spectralConnectivityPLI();
    void spectralConnectivityPLI2();
    void spectralConnectivityWPLI();
    void spectralConnectivityWPLI2();
    void cleanupTestCase();

private:
    void compareConnectivity();
    double epsilon;
    RowVectorXd m_ConnectivityOutput;
    RowVectorXd m_RefConnectivityOutput;
};

//*************************************************************************************************************

TestSpectralConnectivity::TestSpectralConnectivity()
: epsilon(0.000001)
{
}

//*************************************************************************************************************

void TestSpectralConnectivity::TestSpectralConnectivity()
{

}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityCoherence()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    inputTrials = MatrixXd();
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> Coh = Coherence::computeCoherence(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = Coh.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    refConnectivity = MatrixXd();
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivity/ref_spectral_connectivity_coh.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityImagCoherence()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    inputTrials = MatrixXd();
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> ImagCoh = ImagCoherence::computeImagCoherence(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = ImagCoh.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    refConnectivity = MatrixXd();
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_icoh.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityPLV()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    inputTrials = MatrixXd();
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> PLV = PhaseLockingValue::computePLV(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = PLV.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    refConnectivity = MatrixXd();
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_plv.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityPLI()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    inputTrials = MatrixXd();
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> PLI = PhaseLagIndex::computePLI(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = PLI.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    refConnectivity = MatrixXd();
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_pli.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityPLI2()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    inputTrials = MatrixXd();
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> PLI2 = UnbiasedSquaredPhaseLagIndex::computeUnbiasedSquaredPLI(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = PLI2.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    refConnectivity = MatrixXd();
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_pli2.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityWPLI()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    inputTrials = MatrixXd();
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> WPLI = WeightedPhaseLagIndex::computeWPLI(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = WPLI.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    refConnectivity = MatrixXd();
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_wpli.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityWPLI2()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    inputTrials = MatrixXd();
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> WPLI2 = DebiasedSquaredWeightedPhaseLagIndex::computeDebiasedSquaredWPLI(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = WPLI2.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    refConnectivity = MatrixXd();
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_wpli2.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::compareConnectivity()
{
    //*********************************************************************************************************
    // Compare Spectral Connectvitity Result to MNE-PYTHON
    //*********************************************************************************************************

    printf(">>>>>>>>>>>>>>>>>>>>>>>>> Compare Spectral Connectivities >>>>>>>>>>>>>>>>>>>>>>>>>\n");

    QVERIFY( m_ConnectivityOutput.cols() == m_RefConnectivityOutput.cols() );
    for (int i = 0; i < m_ConnectivityOutput.cols(); ++i)
    {
        QVERIFY( (m_ConnectivityOutput(i) - m_RefConnectivityOutput(i)) / m_RefConnectivityOutput(i) < epsilon );
    }

    printf("<<<<<<<<<<<<<<<<<<<<<<<<< Compare Spectral Connectivities Finished <<<<<<<<<<<<<<<<<<<<<<<<<\n");
}

//*************************************************************************************************************

void TestSpectralConnectivity::cleanupTestCase()
{
}

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

QTEST_APPLESS_MAIN(TestSpectralConnectivity)
<commit_msg>remove imports<commit_after>//=============================================================================================================
/**
* @file     test_spectral_connectivity.cpp
* @author   Daniel Strohmeier <daniel.strohmeier@tu-ilmenau.de>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     May, 2018
*
* @section  LICENSE
*
* Copyright (C) 2018, Daniel Strohmeier and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    The spectral connectivity test implementation
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <utils/ioutils.h>
#include "connectivity/metrics/coherence.h"
#include "connectivity/metrics/imagcoherence.h"
#include "connectivity/metrics/phaselockingvalue.h"
#include "connectivity/metrics/phaselagindex.h"
#include "connectivity/metrics/unbiasedsquaredphaselagindex.h"
#include "connectivity/metrics/weightedphaselagindex.h"
#include "connectivity/metrics/debiasedsquaredweightedphaselagindex.h"

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtTest>

//*************************************************************************************************************
//=============================================================================================================
// Eigen INCLUDES
//=============================================================================================================

#include <Eigen/Core>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace Eigen;
using namespace CONNECTIVITYLIB;
using namespace UTILSLIB;

//=============================================================================================================
/**
* DECLARE CLASS TestSpectralConnectivity
*
* @brief The TestSpectralConnectivity class provides spectral connectivity tests
*
*/
class TestSpectralConnectivity: public QObject
{
    Q_OBJECT

public:
    TestSpectralConnectivity();

private slots:
    void initTestCase();
    void spectralConnectivityCoherence();
    void spectralConnectivityImagCoherence();
    void spectralConnectivityPLV();
    void spectralConnectivityPLI();
    void spectralConnectivityPLI2();
    void spectralConnectivityWPLI();
    void spectralConnectivityWPLI2();
    void cleanupTestCase();

private:
    void compareConnectivity();
    double epsilon;
    RowVectorXd m_ConnectivityOutput;
    RowVectorXd m_RefConnectivityOutput;
};

//*************************************************************************************************************

TestSpectralConnectivity::TestSpectralConnectivity()
: epsilon(0.000001)
{
}

//*************************************************************************************************************

void TestSpectralConnectivity::initTestCase()
{

}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityCoherence()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    MatrixXd inputTrials;
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> Coh = Coherence::computeCoherence(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = Coh.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    MatrixXd refConnectivity;
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivity/ref_spectral_connectivity_coh.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityImagCoherence()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    MatrixXd inputTrials;
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> ImagCoh = ImagCoherence::computeImagCoherence(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = ImagCoh.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    MatrixXd refConnectivity;
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_icoh.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityPLV()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    MatrixXd inputTrials;
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> PLV = PhaseLockingValue::computePLV(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = PLV.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    MatrixXd refConnectivity;
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_plv.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityPLI()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    MatrixXd inputTrials;
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> PLI = PhaseLagIndex::computePLI(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = PLI.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    MatrixXd refConnectivity;
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_pli.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityPLI2()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    MatrixXd inputTrials;
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> PLI2 = UnbiasedSquaredPhaseLagIndex::computeUnbiasedSquaredPLI(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = PLI2.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    MatrixXd refConnectivity;
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_pli2.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityWPLI()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    MatrixXd inputTrials;
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> WPLI = WeightedPhaseLagIndex::computeWPLI(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = WPLI.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    MatrixXd refConnectivity;
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_wpli.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::spectralConnectivityWPLI2()
{
    //*********************************************************************************************************
    // Load Data
    //*********************************************************************************************************

    MatrixXd inputTrials;
    QString dataFileName(QDir::currentPath()+"/mne-cpp-test-data/MEG/sample/data_spectral_connectivity.txt");
    IOUtils::read_eigen_matrix(inputTrials, dataFileName);
    int iNTrials = inputTrials.rows() / 2;
    int iNfft = inputTrials.cols();
    QString sWindowType = "hanning";

    QList<MatrixXd> matDataList;
    for (int i = 0; i < iNTrials; ++i)
    {
        matDataList.append(inputTrials.middleRows(i * 2, 2));
    }

    //*********************************************************************************************************
    // Compute Connectivity
    //*********************************************************************************************************

    QVector<MatrixXd> WPLI2 = DebiasedSquaredWeightedPhaseLagIndex::computeDebiasedSquaredWPLI(matDataList, iNfft, sWindowType);
    m_ConnectivityOutput = WPLI2.at(0).row(1);

    //*********************************************************************************************************
    // Load MNE-PYTHON Results As Reference
    //*********************************************************************************************************

    MatrixXd refConnectivity;
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/Connectivty/ref_spectral_connectivity_wpli2.txt");
    IOUtils::read_eigen_matrix(refConnectivity, refFileName);
    m_RefConnectivityOutput = refConnectivity.row(0);

    //*********************************************************************************************************
    // Compare Connectivity
    //*********************************************************************************************************

    compareConnectivity();
}

//*************************************************************************************************************

void TestSpectralConnectivity::compareConnectivity()
{
    //*********************************************************************************************************
    // Compare Spectral Connectvitity Result to MNE-PYTHON
    //*********************************************************************************************************

    printf(">>>>>>>>>>>>>>>>>>>>>>>>> Compare Spectral Connectivities >>>>>>>>>>>>>>>>>>>>>>>>>\n");

    QVERIFY( m_ConnectivityOutput.cols() == m_RefConnectivityOutput.cols() );
    for (int i = 0; i < m_ConnectivityOutput.cols(); ++i)
    {
        QVERIFY( (m_ConnectivityOutput(i) - m_RefConnectivityOutput(i)) / m_RefConnectivityOutput(i) < epsilon );
    }

    printf("<<<<<<<<<<<<<<<<<<<<<<<<< Compare Spectral Connectivities Finished <<<<<<<<<<<<<<<<<<<<<<<<<\n");
}

//*************************************************************************************************************

void TestSpectralConnectivity::cleanupTestCase()
{
}

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

QTEST_APPLESS_MAIN(TestSpectralConnectivity)
#include "test_spectral_connectivity.moc"
<|endoftext|>


<commit_before>#include "IrrCompileConfig.h"

#ifdef _IRR_COMPILE_WITH_OPENGL_

#include "COpenGLDriver.h"

#include "COpenGLRenderBuffer.h"

namespace irr
{
namespace video
{

//! constructor
COpenGLRenderBuffer::COpenGLRenderBuffer(GLenum internalFormat, core::dimension2du size)
    : RenderBufferSize(size), InternalFormat(internalFormat), RenderBufferName(0), RenderBufferNameHasChanged(0)
{
    COpenGLExtensionHandler::extGlCreateRenderbuffers(1,&RenderBufferName);
    COpenGLExtensionHandler::extGlNamedRenderbufferStorage(RenderBufferName,InternalFormat,RenderBufferSize.Width,RenderBufferSize.Height);
}

//! destructor
COpenGLRenderBuffer::~COpenGLRenderBuffer()
{
    COpenGLExtensionHandler::extGlDeleteRenderbuffers(1,&RenderBufferName);
}

void COpenGLRenderBuffer::resize(const core::dimension2du &newSize)
{
    RenderBufferSize = newSize;

    if (RenderBufferName)
    {
        glDeleteTextures(1,&RenderBufferName);
        RenderBufferName = 0;
    }
    COpenGLExtensionHandler::extGlCreateRenderbuffers(1,&RenderBufferName);
    COpenGLExtensionHandler::extGlNamedRenderbufferStorage(RenderBufferName,InternalFormat,RenderBufferSize.Width,RenderBufferSize.Height);

	RenderBufferNameHasChanged = CNullDriver::incrementAndFetchReallocCounter();
}

//! constructor
COpenGLMultisampleRenderBuffer::COpenGLMultisampleRenderBuffer(GLenum internalFormat, core::dimension2du size, uint32_t sampleCount)
    : COpenGLRenderBuffer(internalFormat, size, false), SampleCount(sampleCount)
{
    COpenGLExtensionHandler::extGlCreateRenderbuffers(1,&RenderBufferName);
    COpenGLExtensionHandler::extGlNamedRenderbufferStorageMultisample(RenderBufferName,SampleCount,InternalFormat,RenderBufferSize.Width,RenderBufferSize.Height);
}

void COpenGLMultisampleRenderBuffer::resize(const core::dimension2du &newSize)
{
    RenderBufferSize = newSize;

    if (RenderBufferName)
    {
        glDeleteTextures(1,&RenderBufferName);
        RenderBufferName = 0;
    }
    COpenGLExtensionHandler::extGlCreateRenderbuffers(1,&RenderBufferName);
    COpenGLExtensionHandler::extGlNamedRenderbufferStorageMultisample(RenderBufferName,SampleCount,InternalFormat,RenderBufferSize.Width,RenderBufferSize.Height);

	RenderBufferNameHasChanged = CNullDriver::incrementAndFetchReallocCounter();
}

}
}
#endif
<commit_msg>Renderbuffer killing random textures on resize fix.<commit_after>#include "IrrCompileConfig.h"

#ifdef _IRR_COMPILE_WITH_OPENGL_

#include "COpenGLDriver.h"

#include "COpenGLRenderBuffer.h"

namespace irr
{
namespace video
{

//! constructor
COpenGLRenderBuffer::COpenGLRenderBuffer(GLenum internalFormat, core::dimension2du size)
    : RenderBufferSize(size), InternalFormat(internalFormat), RenderBufferName(0), RenderBufferNameHasChanged(0)
{
    COpenGLExtensionHandler::extGlCreateRenderbuffers(1,&RenderBufferName);
    COpenGLExtensionHandler::extGlNamedRenderbufferStorage(RenderBufferName,InternalFormat,RenderBufferSize.Width,RenderBufferSize.Height);
}

//! destructor
COpenGLRenderBuffer::~COpenGLRenderBuffer()
{
    COpenGLExtensionHandler::extGlDeleteRenderbuffers(1,&RenderBufferName);
}

void COpenGLRenderBuffer::resize(const core::dimension2du &newSize)
{
    RenderBufferSize = newSize;

    if (RenderBufferName)
    {
        COpenGLExtensionHandler::extGlDeleteRenderbuffers(1,&RenderBufferName);
        RenderBufferName = 0;
    }
    COpenGLExtensionHandler::extGlCreateRenderbuffers(1,&RenderBufferName);
    COpenGLExtensionHandler::extGlNamedRenderbufferStorage(RenderBufferName,InternalFormat,RenderBufferSize.Width,RenderBufferSize.Height);

	RenderBufferNameHasChanged = CNullDriver::incrementAndFetchReallocCounter();
}

//! constructor
COpenGLMultisampleRenderBuffer::COpenGLMultisampleRenderBuffer(GLenum internalFormat, core::dimension2du size, uint32_t sampleCount)
    : COpenGLRenderBuffer(internalFormat, size, false), SampleCount(sampleCount)
{
    COpenGLExtensionHandler::extGlCreateRenderbuffers(1,&RenderBufferName);
    COpenGLExtensionHandler::extGlNamedRenderbufferStorageMultisample(RenderBufferName,SampleCount,InternalFormat,RenderBufferSize.Width,RenderBufferSize.Height);
}

void COpenGLMultisampleRenderBuffer::resize(const core::dimension2du &newSize)
{
    RenderBufferSize = newSize;

    if (RenderBufferName)
    {
        COpenGLExtensionHandler::extGlDeleteRenderbuffers(1,&RenderBufferName);
        RenderBufferName = 0;
    }
    COpenGLExtensionHandler::extGlCreateRenderbuffers(1,&RenderBufferName);
    COpenGLExtensionHandler::extGlNamedRenderbufferStorageMultisample(RenderBufferName,SampleCount,InternalFormat,RenderBufferSize.Width,RenderBufferSize.Height);

	RenderBufferNameHasChanged = CNullDriver::incrementAndFetchReallocCounter();
}

}
}
#endif
<|endoftext|>


<commit_before>/*Copyright 2010 George Karagoulis

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

#include "file_manager.h"
#include "stringhelpers.h"
#include "encryption.h"
#include "exception.h"
#include <QDesktopServices>
#include <QFile>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QVariant>
#include <QMutex>
#include <QReadWriteLock>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlResult>
#include <QMap>
#include <QMessageBox>
#include <QByteArray>
using namespace GUtil;
using namespace GUtil::QtUtil;

// A class to keep track of our mutexes
class mutex_record_t
{
public:
    mutex_record_t()
    {
        count = 1;
        mut = new QReadWriteLock();
    }
    ~mutex_record_t(){ delete mut;}

    QReadWriteLock *mut;
    int count;
};

QMap<QString, mutex_record_t *> mutexes;
QReadWriteLock mutex_lock;

File_Manager::File_Manager(const QString &id, bool primary)
{
    my_id = id;
    file_location = get_file_loc(id);

    mutex_lock.lockForWrite();
    if(mutexes.contains(id))
    {
        mutexes.value(id)->mut->lockForWrite();

        mutexes[id]->count++;

        mutexes.value(id)->mut->unlock();
    }
    else
    {
        mutexes.insert(id, new mutex_record_t());
    }
    mutex_lock.unlock();

    if(primary)
    {
        if(QFile::exists(file_location))
            QFile::remove(file_location);

        QSqlDatabase::addDatabase("QSQLITE").setDatabaseName(file_location);
        reset();
    }
}

File_Manager::~File_Manager()
{

}

int File_Manager::addFile(const QString &data)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    int ret = get_free_file_id(dbase);
    add_file(ret, data, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();

    return ret;
}

int File_Manager::addFile(int id, const QString &data)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    int ret = add_file(id, data, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();

    return ret;
}

int File_Manager::add_file(int id, const QString &data, QSqlDatabase &dbase)
{
    if(has_file(id, dbase))
        remove_file(id, dbase);

    QSqlQuery q("INSERT INTO files (id, data) VALUES (:id, :data)", dbase);
    q.bindValue(":id", id);
    q.bindValue(":data", data, QSql::Binary);
    q.exec();

    return id;
}

void File_Manager::removeFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    remove_file(id, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
}

void File_Manager::remove_file(int id, QSqlDatabase &dbase)
{
    // Remove each item one by one
    QSqlQuery q("DELETE FROM files WHERE id=:id");
    q.bindValue(":id", id);
    q.exec();
}

QString File_Manager::getFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q("SELECT data, COUNT(data) FROM files WHERE id=:id", dbase);
    q.bindValue(":id", id);
    q.exec();

    if(q.first() && (q.value(1).toInt() == 1))
    {
        QByteArray ba = q.value(0).toByteArray();
        mutexes.value(my_id)->mut->unlock();
        mutex_lock.unlock();
        return QString::fromStdString(string(ba.constData(), ba.length()));
    }

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    throw GUtil::Exception("File not found");
}

// Clear all files
void File_Manager::reset()
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q(dbase);
    q.exec("DROP TABLE \"files\"");
    q.exec("CREATE TABLE \"files\" ("
               "\"id\" INTEGER NOT NULL,"
               "\"data\" BLOB NOT NULL)");
    q.exec("CREATE INDEX idx ON files(id)");
    dbase.close();

    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
}

void File_Manager::prep_database(QSqlDatabase &dbase)
{
    dbase = QSqlDatabase::database();
    if(!dbase.open())
    {
        mutexes.value(my_id)->mut->unlock();
        mutex_lock.unlock();
        throw GUtil::Exception("Cannot open database");
    }
}

QString File_Manager::get_file_loc(const QString &id)
{
    return QDesktopServices::storageLocation(QDesktopServices::TempLocation)
            + QString("/%1.tempfile").arg(id);
}

QList<int> File_Manager::idList()
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QList<int> ret;
    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q("SELECT id FROM files");
    if(q.exec())
    {
        while(q.next())
        {
            ret.append(q.value(0).toInt());
        }
    }

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    return ret;
}

bool File_Manager::hasFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QSqlDatabase dbase;
    prep_database(dbase);

    bool ret = has_file(id, dbase);

    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    return ret;
}

bool File_Manager::has_file(int id, QSqlDatabase &dbase)
{
    QSqlQuery q("SELECT id FROM files WHERE id=:id", dbase);
    q.bindValue(":id", id);
    q.exec();
    return q.first();
}

int File_Manager::get_free_file_id(QSqlDatabase &dbase)
{
    // You must already have a lock on the database before using this function!

    int max_id = 0;
    QSqlQuery q("SELECT COUNT(id),MAX(id) FROM files", dbase);
    q.exec();
    if(q.first())
    {
        if(q.value(0).toInt() > 0)
            max_id = q.value(1).toInt();
    }

    do
    {
        if(++max_id < 0)
            max_id = 0;

    // Make sure the id isn't taken
    }while(has_file(max_id, dbase));

    return max_id;
}
<commit_msg>Fixed a bug in the id selection code<commit_after>/*Copyright 2010 George Karagoulis

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

#include "file_manager.h"
#include "stringhelpers.h"
#include "encryption.h"
#include "exception.h"
#include <QDesktopServices>
#include <QFile>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QVariant>
#include <QMutex>
#include <QReadWriteLock>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlResult>
#include <QMap>
#include <QMessageBox>
#include <QByteArray>
using namespace GUtil;
using namespace GUtil::QtUtil;

// A class to keep track of our mutexes
class mutex_record_t
{
public:
    mutex_record_t()
    {
        count = 1;
        mut = new QReadWriteLock();
    }
    ~mutex_record_t(){ delete mut;}

    QReadWriteLock *mut;
    int count;
};

QMap<QString, mutex_record_t *> mutexes;
QReadWriteLock mutex_lock;

File_Manager::File_Manager(const QString &id, bool primary)
{
    my_id = id;
    file_location = get_file_loc(id);

    mutex_lock.lockForWrite();
    if(mutexes.contains(id))
    {
        mutexes.value(id)->mut->lockForWrite();

        mutexes[id]->count++;

        mutexes.value(id)->mut->unlock();
    }
    else
    {
        mutexes.insert(id, new mutex_record_t());
    }
    mutex_lock.unlock();

    if(primary)
    {
        if(QFile::exists(file_location))
            QFile::remove(file_location);

        QSqlDatabase::addDatabase("QSQLITE").setDatabaseName(file_location);
        reset();
    }
}

File_Manager::~File_Manager()
{

}

int File_Manager::addFile(const QString &data)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    int ret = get_free_file_id(dbase);
    add_file(ret, data, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();

    return ret;
}

int File_Manager::addFile(int id, const QString &data)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    int ret = add_file(id, data, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();

    return ret;
}

int File_Manager::add_file(int id, const QString &data, QSqlDatabase &dbase)
{
    if(has_file(id, dbase))
        remove_file(id, dbase);

    QSqlQuery q("INSERT INTO files (id, data) VALUES (:id, :data)", dbase);
    q.bindValue(":id", id);
    q.bindValue(":data", data, QSql::Binary);
    if(!q.exec())
        throw GUtil::Exception(q.lastError().text().toStdString());

    return id;
}

void File_Manager::removeFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    remove_file(id, dbase);

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
}

void File_Manager::remove_file(int id, QSqlDatabase &dbase)
{
    // Remove each item one by one
    QSqlQuery q("DELETE FROM files WHERE id=:id");
    q.bindValue(":id", id);
    q.exec();
}

QString File_Manager::getFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q("SELECT data, COUNT(data) FROM files WHERE id=:id", dbase);
    q.bindValue(":id", id);
    q.exec();

    if(q.first() && (q.value(1).toInt() == 1))
    {
        QByteArray ba = q.value(0).toByteArray();
        mutexes.value(my_id)->mut->unlock();
        mutex_lock.unlock();
        return QString::fromStdString(string(ba.constData(), ba.length()));
    }

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    throw GUtil::Exception("File not found");
}

// Clear all files
void File_Manager::reset()
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForWrite();

    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q(dbase);
    q.exec("DROP TABLE \"files\"");
    q.exec("CREATE TABLE \"files\" ("
               "\"id\" INTEGER NOT NULL,"
               "\"data\" BLOB NOT NULL)");
    q.exec("CREATE INDEX idx ON files(id)");
    dbase.close();

    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
}

void File_Manager::prep_database(QSqlDatabase &dbase)
{
    dbase = QSqlDatabase::database();
    if(!dbase.open())
    {
        mutexes.value(my_id)->mut->unlock();
        mutex_lock.unlock();
        throw GUtil::Exception("Cannot open database");
    }
}

QString File_Manager::get_file_loc(const QString &id)
{
    return QDesktopServices::storageLocation(QDesktopServices::TempLocation)
            + QString("/%1.tempfile").arg(id);
}

QList<int> File_Manager::idList()
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QList<int> ret;
    QSqlDatabase dbase;
    prep_database(dbase);

    QSqlQuery q("SELECT id FROM files");
    if(q.exec())
    {
        while(q.next())
        {
            ret.append(q.value(0).toInt());
        }
    }

    dbase.close();
    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    return ret;
}

bool File_Manager::hasFile(int id)
{
    mutex_lock.lockForRead();
    mutexes.value(my_id)->mut->lockForRead();

    QSqlDatabase dbase;
    prep_database(dbase);

    bool ret = has_file(id, dbase);

    mutexes.value(my_id)->mut->unlock();
    mutex_lock.unlock();
    return ret;
}

bool File_Manager::has_file(int id, QSqlDatabase &dbase)
{
    QSqlQuery q("SELECT id FROM files WHERE id=:id", dbase);
    q.bindValue(":id", id);
    q.exec();
    return q.first();
}

int File_Manager::get_free_file_id(QSqlDatabase &dbase)
{
    // You must already have a lock on the database before using this function!

    int max_id = 0;
    bool found_id = false;

    QSqlQuery q("SELECT COUNT(id),MAX(id) FROM files", dbase);
    q.exec();
    if(q.first())
    {
        if(q.value(0).toInt() > 0)
        {
            max_id = q.value(1).toInt();
            found_id = true;
        }
    }

    bool first_time = true;
    do
    {
        if(first_time)
        {
            first_time = false;
            if(found_id)
                max_id++;
        }
        else
            max_id++;

        if(max_id < 0)
            max_id = 0;

    // Make sure the id isn't taken
    }while(has_file(max_id, dbase));

    return max_id;
}
<|endoftext|>


<commit_before>int dp[MAX][MAX]; // dp[i][j] is number of ways j items can be choosen from i items

void ncr() {
	dp[0][0] = 1;
    for(int i = 1; i < MAX; ++i) {
        for(int j = 0; j <= i; ++j) {
            if(j == i or j == 0) {
                dp[i][j] = 1;
            } else {
                dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod;
            }
        }
    }
}

// Using combinatorics
#define MAX 100001
#define MOD 1000000007
int fact[MAX];
int ifact[MAX];

int power(int base, int exp, int mod) {
    if(exp == 0) return 1;
    int ret = power(base, exp / 2, mod) % mod;
    ret = 1LL * ret * ret % mod;
    if(exp & 1) {
        ret = 1LL * ret * base % mod;
    }
    return ret;
}

// Modular mutiplicative inverse
int modInv(int base, int mod = 1000000007) {
    return power(base, mod - 2, mod);
}

void init() {
    fact[0] = 1;
    ifact[0] = modInv(fact[0]);
    FOR(i, 1, MAX - 1) {
        fact[i] = 1LL * i * fact[i - 1] % MOD;
        ifact[i] = modInv(fact[i]);
    }
}

int ncr(int n, int r) {
    int ncr = 1LL * fact[n] * ifact[r] % MOD;
    ncr = 1LL * ncr * ifact[n - r] % MOD;
    return ncr;
}<commit_msg>nCr updated<commit_after>int dp[MAX][MAX]; // dp[i][j] is number of ways j items can be choosen from i items

void ncr() {
	dp[0][0] = 1;
    for(int i = 1; i < MAX; ++i) {
        for(int j = 0; j <= i; ++j) {
            if(j == i or j == 0) {
                dp[i][j] = 1;
            } else {
                dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod;
            }
        }
    }
}

// Using combinatorics
#define MAX 100001
#define MOD 1000000007
int fact[MAX];
int ifact[MAX];

int power(int base, int exp, int mod) {
    if(exp == 0) return 1;
    int ret = power(base, exp / 2, mod) % mod;
    ret = 1LL * ret * ret % mod;
    if(exp & 1) {
        ret = 1LL * ret * base % mod;
    }
    return ret;
}

// Modular mutiplicative inverse
int modInv(int base, int mod = 1000000007) {
    return power(base, mod - 2, mod);
}

void init() {
    fact[0] = 1;
    ifact[0] = modInv(fact[0]);
    FOR(i, 1, MAX - 1) {
        fact[i] = 1LL * i * fact[i - 1] % MOD;
        ifact[i] = modInv(fact[i]);
    }
}

int ncr(int n, int r) {
    int ans = fact[n];
    ans = 1LL * ans * ifact[r] % MOD;
    ans = 1LL * ans * ifact[n - r] % MOD;
    return ans;
}<|endoftext|>