#include "threadgenesorter.h"
#include "sortaction.h"
+#include "genealgorithms.h"
+
+#include <sys/time.h>
+#include <errno.h>
+
+#include <set>
using namespace std;
/**
}
void ThreadGeneSorter::stop(){
+ Mutex m(&_queuelock);
_done = true;
+ pthread_cond_signal(&_waiting);
}
size_t ThreadGeneSorter::size(){
- //TODO: thread safety..
+ Mutex m(&_solutionslock);
return _solutions.size();
}
-double progress(int time, int solutions = 1){
+bool ThreadGeneSorter::running(){
+ return !_done;
+}
+
+double ThreadGeneSorter::wait(time_t time, size_t solutions){
+
+ timeval now;
+ gettimeofday(&now, NULL);
+ timespec timeout;
+ timeout.tv_sec = now.tv_sec + time;
+ timeout.tv_nsec = 0;
+
+ int err = 0;
+
+ Mutex m(&_solutionslock);
+ size_t n = _solutions.size();
+
+ while (!_done && err != ETIMEDOUT
+ && _solutions.size() - n < solutions){
+ err = pthread_cond_timedwait(&_addedSolution,&_solutionslock
+ , &timeout);
+ }
+ if (_solutions.size() == 0)
+ return 0.0;
+ return _solutions.top().first;
}
ThreadGeneSorter::SolutionsQueue ThreadGeneSorter::solutions(){
}
void ThreadGeneSorter::worker(){
+ try{
while(!_done){
Mutex m(&_queuelock);
SortUnit su = _queue.top();
_queue.pop();
m.unlock();
+
+ size_t dist = inversionDistance(su._go);
+ if (dist == 0){
+ Mutex m(&_solutionslock);
+ _solutions.push(pair<double,ActionList>(su._score,su._al));
+ pthread_cond_broadcast(&_addedSolution);
+ continue;;
+ }
+
+ ActionList act = safeActions(su._go);
+ if (act.size() > 0){
+ set<SortAction> safe(act.begin(), act.end());
+ for (set<SortAction>::iterator sa = safe.begin(); sa != safe.end(); ++sa){
+ GeneOrder go(su._go);
+ ActionList al(su._al);
+ al.push_back(*sa);
+ (*sa)(go);
+ double score = su._score + _model.score(*sa,su._go);
+ Mutex m(&_queuelock);
+ _queue.push(SortUnit(score,go,al));
+ }
+ pthread_cond_broadcast(&_addedTask);
+ } //TODO: Hurdles..
+
+ }
+ }catch(const bad_alloc& e){
+ _done = true;
}
}