]> ruin.nu Git - germs.git/blobdiff - src/threadgenesorter.cpp
Added progress information for the search
[germs.git] / src / threadgenesorter.cpp
index a45988c21dcc4a14f7717a9ef7b07d9757f81179..d4fe06995d2d850298cb011346c3700668d88dce 100644 (file)
 #include "threadgenesorter.h"
 #include "sortaction.h"
 
+#include "genealgorithms.h"
+
+#include <sys/time.h>
+#include <errno.h>
+
+#include <set>
 using namespace std;
 
 /**
@@ -69,15 +75,41 @@ void ThreadGeneSorter::join(){
 }
 
 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(){
@@ -131,6 +163,7 @@ void ThreadGeneSorter::sorter(const GeneOrder& go){
 }
 
 void ThreadGeneSorter::worker(){
+       try{
        while(!_done){
                Mutex m(&_queuelock);
 
@@ -146,6 +179,33 @@ void ThreadGeneSorter::worker(){
                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;
        }
 }