@ -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 |