@ -0,0 +1,76 @@ | |||||
#include "util/experimentscope.h" | |||||
namespace satlab | |||||
{ | |||||
KSATinstance* ExperimentScope::InstanceIncrementer::operator->() | |||||
{ | |||||
return &instance; | |||||
} | |||||
KSATinstance& ExperimentScope::InstanceIncrementer::operator*() | |||||
{ | |||||
return instance; | |||||
} | |||||
void ExperimentScope::InstanceIncrementer::next() | |||||
{ | |||||
step++; | |||||
} | |||||
bool ExperimentScope::iterator::operator==(const ExperimentScope::iterator& other) | |||||
{ | |||||
return cmp(pIncr, other.pIncr); | |||||
} | |||||
bool ExperimentScope::iterator::operator!=(const ExperimentScope::iterator& other) | |||||
{ | |||||
return !(cmp(pIncr, other.pIncr)); | |||||
} | |||||
ExperimentScope::iterator::reference ExperimentScope::iterator::operator*() | |||||
{ | |||||
return (*pIncr).operator*(); | |||||
} | |||||
ExperimentScope::iterator::pointer ExperimentScope::iterator::operator->() | |||||
{ | |||||
return (*pIncr).operator->(); | |||||
} | |||||
ExperimentScope::iterator& ExperimentScope::iterator::operator++() | |||||
{ | |||||
pIncr->next(); | |||||
return *this; | |||||
} | |||||
ExperimentScope::iterator ExperimentScope::iterator::operator++(int) | |||||
{ | |||||
iterator copy(*this); | |||||
pIncr->next(); | |||||
return copy; | |||||
} | |||||
ExperimentScope::iterator::iterator(ExperimentScope::P_INCR_T&& pIncr, | |||||
ExperimentScope::iterator::CMP_FNC_T&& cmp) | |||||
: cmp(std::move(cmp)), | |||||
pIncr(std::move(pIncr)) | |||||
{ | |||||
} | |||||
ExperimentScope::iterator | |||||
ExperimentScope::createIterator(ExperimentScope::P_INCR_T&& pIncr, | |||||
ExperimentScope::iterator::CMP_FNC_T&& cmp) | |||||
{ | |||||
return iterator(std::move(pIncr), std::move(cmp)); | |||||
} | |||||
} |
@ -0,0 +1,94 @@ | |||||
#ifndef EXPERIMENTSCOPE_H | |||||
#define EXPERIMENTSCOPE_H | |||||
#include "util/ksatinstance.h" | |||||
#include <memory> | |||||
#include <functional> | |||||
namespace satlab | |||||
{ | |||||
class ExperimentScope | |||||
{ | |||||
protected: | |||||
class InstanceIncrementer | |||||
{ | |||||
public: | |||||
friend bool operator==(const ExperimentScope::InstanceIncrementer& lhs, | |||||
const ExperimentScope::InstanceIncrementer& rhs); | |||||
InstanceIncrementer() = default; | |||||
virtual ~InstanceIncrementer() = default; | |||||
InstanceIncrementer(const InstanceIncrementer& other) = default; | |||||
InstanceIncrementer(InstanceIncrementer&& other) = default; | |||||
InstanceIncrementer& operator=(const InstanceIncrementer& other) = default; | |||||
InstanceIncrementer& operator=(InstanceIncrementer&& other) = default; | |||||
virtual void next(); | |||||
virtual KSATinstance* operator->(); | |||||
virtual KSATinstance& operator*(); | |||||
private: | |||||
int step; | |||||
protected: | |||||
KSATinstance instance; | |||||
}; | |||||
using P_INCR_T = std::shared_ptr<InstanceIncrementer>; | |||||
public: | |||||
class iterator | |||||
{ | |||||
public: | |||||
friend class ExperimentScope; | |||||
using iterator_category = std::forward_iterator_tag; | |||||
using value_type = KSATinstance; | |||||
using difference_type = int; | |||||
using pointer = KSATinstance*; | |||||
using reference = KSATinstance&; | |||||
iterator() = default; | |||||
virtual ~iterator() = default; | |||||
iterator(const iterator& other) = default; | |||||
iterator& operator=(const iterator& other) = default; | |||||
virtual bool operator==(const iterator&other); | |||||
virtual bool operator!=(const iterator&other); | |||||
virtual reference operator*(); | |||||
virtual pointer operator->(); | |||||
virtual iterator& operator++(); | |||||
virtual iterator operator++(int); | |||||
private: | |||||
using CMP_FNC_T = std::function<bool(const P_INCR_T& lhs, | |||||
const P_INCR_T& rhs)>; | |||||
iterator(P_INCR_T&& pIncr, CMP_FNC_T&& cmp); | |||||
CMP_FNC_T cmp; | |||||
P_INCR_T pIncr; | |||||
}; | |||||
virtual iterator begin() noexcept = 0; | |||||
virtual iterator end() noexcept = 0; | |||||
protected: | |||||
iterator createIterator(P_INCR_T&& pIncr, iterator::CMP_FNC_T&& cmp); | |||||
}; | |||||
} | |||||
#endif // EXPERIMENTSCOPE_H |
@ -0,0 +1,147 @@ | |||||
#include "util/mongodbexperimentscope.h" | |||||
#include "util/conversions.h" | |||||
#include "mongocxx/collection.hpp" | |||||
#include "mongocxx/pipeline.hpp" | |||||
#include "bsoncxx/builder/stream/document.hpp" | |||||
#include "bsoncxx/oid.hpp" | |||||
#include <iostream> | |||||
namespace satlab | |||||
{ | |||||
MongoDBExperimentScope::InstanceIncrementer::InstanceIncrementer( | |||||
mongocxx::cursor::iterator&& cursorIt) | |||||
: cursorIt(std::move(cursorIt)) | |||||
{ | |||||
} | |||||
void MongoDBExperimentScope::InstanceIncrementer::next() | |||||
{ | |||||
BASE::InstanceIncrementer::next(); | |||||
cursorIt++; | |||||
instanceIsUpdated = false; | |||||
} | |||||
void MongoDBExperimentScope::InstanceIncrementer::updateInstance() | |||||
{ | |||||
if(instanceIsUpdated) | |||||
{ | |||||
return; | |||||
} | |||||
instance = KSATinstance(types::convert(*cursorIt)); | |||||
instanceIsUpdated = true; | |||||
} | |||||
KSATinstance* MongoDBExperimentScope::InstanceIncrementer::operator->() | |||||
{ | |||||
updateInstance(); | |||||
return &instance; | |||||
} | |||||
KSATinstance& MongoDBExperimentScope::InstanceIncrementer::operator*() | |||||
{ | |||||
updateInstance(); | |||||
return instance; | |||||
} | |||||
MongoDBExperimentScope::MongoDBExperimentScope(mongocxx::cursor&& cursor) | |||||
: cursor(std::move(cursor)) | |||||
{ | |||||
} | |||||
MongoDBExperimentScope::MongoDBExperimentScope(const mongocxx::database& db, | |||||
const std::string& scopeName) | |||||
: MongoDBExperimentScope(std::move(getCursor(db, scopeName))) | |||||
{ | |||||
} | |||||
mongocxx::cursor MongoDBExperimentScope::getCursor(const mongocxx::database& db, | |||||
const std::string& scopeName) | |||||
{ | |||||
return db["experiment_scopes"].aggregate(createScopePipeline(scopeName)); | |||||
} | |||||
mongocxx::pipeline | |||||
MongoDBExperimentScope::createScopePipeline(const std::string& scopeName) | |||||
{ | |||||
mongocxx::pipeline pipeline; | |||||
pipeline.match(bsoncxx::builder::stream::document() | |||||
<< "_id" << scopeName | |||||
<< bsoncxx::builder::stream::finalize); | |||||
pipeline.unwind("$instances"); | |||||
pipeline.lookup(bsoncxx::builder::stream::document() | |||||
<< "from" << "instances" | |||||
<< "localField" << "instances" | |||||
<< "foreignField" << "_id" | |||||
<< "as" << "instance" | |||||
<< bsoncxx::builder::stream::finalize); | |||||
pipeline.unwind("$instance"); | |||||
pipeline.replace_root(bsoncxx::builder::stream::document() | |||||
<< "newRoot" << "$instance" | |||||
<< bsoncxx::builder::stream::finalize); | |||||
return pipeline; | |||||
} | |||||
MongoDBExperimentScope::BASE::iterator MongoDBExperimentScope::begin() noexcept | |||||
{ | |||||
P_INCR_T incrementer = P_INCR_T(new InstanceIncrementer(cursor.begin())); | |||||
return BASE::createIterator( | |||||
std::move(incrementer), | |||||
[] (const std::shared_ptr<BASE::InstanceIncrementer>& lhs, | |||||
const std::shared_ptr<BASE::InstanceIncrementer>& rhs) | |||||
{ | |||||
auto derivedLhs = std::dynamic_pointer_cast<InstanceIncrementer>(lhs); | |||||
auto derivedRhs = std::dynamic_pointer_cast<InstanceIncrementer>(rhs); | |||||
if(derivedLhs && derivedRhs) | |||||
{ | |||||
return derivedLhs->cursorIt == derivedRhs->cursorIt; | |||||
} | |||||
return false; | |||||
} | |||||
); | |||||
} | |||||
MongoDBExperimentScope::BASE::iterator MongoDBExperimentScope::end() noexcept | |||||
{ | |||||
P_INCR_T incrementer = P_INCR_T(new InstanceIncrementer(cursor.end())); | |||||
return BASE::createIterator( | |||||
std::move(incrementer), | |||||
[] (const std::shared_ptr<BASE::InstanceIncrementer>& lhs, | |||||
const std::shared_ptr<BASE::InstanceIncrementer>& rhs) | |||||
{ | |||||
auto derivedLhs = std::dynamic_pointer_cast<InstanceIncrementer>(lhs); | |||||
auto derivedRhs = std::dynamic_pointer_cast<InstanceIncrementer>(rhs); | |||||
if(derivedLhs && derivedRhs) | |||||
{ | |||||
return derivedLhs->cursorIt == derivedRhs->cursorIt; | |||||
} | |||||
return false; | |||||
} | |||||
); | |||||
} | |||||
} |
@ -0,0 +1,77 @@ | |||||
#ifndef MONGODBEXPERIMENTSCOPE_H | |||||
#define MONGODBEXPERIMENTSCOPE_H | |||||
#include "util/experimentscope.h" | |||||
#include "mongocxx/cursor.hpp" | |||||
#include "mongocxx/database.hpp" | |||||
#include <string> | |||||
namespace satlab | |||||
{ | |||||
class MongoDBExperimentScope : public ExperimentScope | |||||
{ | |||||
public: | |||||
using BASE = ExperimentScope; | |||||
class InstanceIncrementer : public ExperimentScope::InstanceIncrementer | |||||
{ | |||||
public: | |||||
friend class MongoDBExperimentScope; | |||||
InstanceIncrementer() = default; | |||||
virtual ~InstanceIncrementer() = default; | |||||
InstanceIncrementer(const InstanceIncrementer& other) = default; | |||||
InstanceIncrementer(InstanceIncrementer&& other) = default; | |||||
InstanceIncrementer& operator=(const InstanceIncrementer& other) = default; | |||||
InstanceIncrementer& operator=(InstanceIncrementer&& other) = default; | |||||
InstanceIncrementer(mongocxx::cursor::iterator&& cursorIt); | |||||
virtual void next() override; | |||||
virtual KSATinstance* operator->() override; | |||||
virtual KSATinstance& operator*() override; | |||||
private: | |||||
void updateInstance(); | |||||
bool instanceIsUpdated = false; | |||||
mongocxx::cursor::iterator cursorIt; | |||||
}; | |||||
public: | |||||
MongoDBExperimentScope() = default; | |||||
virtual ~MongoDBExperimentScope() = default; | |||||
MongoDBExperimentScope(const MongoDBExperimentScope& other) = default; | |||||
MongoDBExperimentScope(MongoDBExperimentScope&& other) = default; | |||||
MongoDBExperimentScope& operator=(const MongoDBExperimentScope& other) = default; | |||||
MongoDBExperimentScope& operator=(MongoDBExperimentScope&& other) = default; | |||||
MongoDBExperimentScope(mongocxx::cursor&& cursor); | |||||
MongoDBExperimentScope(const mongocxx::database& db, const std::string& scopeName); | |||||
virtual BASE::iterator begin() noexcept override; | |||||
virtual BASE::iterator end() noexcept override; | |||||
private: | |||||
using P_INCR_T = BASE::P_INCR_T; | |||||
mongocxx::cursor getCursor(const mongocxx::database& db, | |||||
const std::string& scopeName); | |||||
mongocxx::pipeline createScopePipeline(const std::string& scopeName); | |||||
mongocxx::cursor cursor; | |||||
}; | |||||
} | |||||
#endif // MONGODBEXPERIMENTSCOPE_H |