Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

AlgThread.cxx

Go to the documentation of this file.
00001 // $Id: AlgThread.cxx,v 1.2 2008/01/31 22:18:17 rustem Exp $
00002 
00003 // C++
00004 #include <iostream>
00005 #include <iterator>
00006 
00007 // Local
00008 #include "AlgThread.h"
00009 
00010 using namespace std;
00011 
00012 //---------------------------------------------------------------------------------------
00013 void* Anp::run_alg_thread(void *data_)
00014 {
00015    if(!data_)
00016    {
00017       cerr << "Anp::run_alg_thread - null data pointer" << endl;
00018       return 0;
00019    }
00020 
00021    AlgThread *data = static_cast<AlgThread *> (data_);
00022 
00023    data -> Run();
00024 
00025    return data;
00026 }
00027 
00028 //---------------------------------------------------------------------------------------
00029 Anp::AlgThread::AlgThread(AlgSnarlPtr alg, const string &name)
00030    :fMutex(),
00031     fThread(),
00032     fThreadStatus(1),
00033     fAlg(alg),
00034     fName(name),
00035     fRecord(),
00036     fNPass(0),
00037     fNFail(0)
00038 {
00039 }
00040 
00041 //---------------------------------------------------------------------------------------
00042 Anp::AlgThread::~AlgThread()
00043 {
00044 }
00045 
00046 //----------------------------------------------------------------------
00047 void Anp::AlgThread::Run(Record &record, const bool new_thread)
00048 {   
00049    
00050    if(new_thread)
00051    {
00052       //
00053       // Lock mutex ONLY when starting new thread
00054       //
00055       Anp::Lock<Mutex> lock(fMutex);
00056 
00057       //
00058       // Make local copy of input record
00059       //
00060       fRecord = record;
00061 
00062       //
00063       // Run kNN algorithm in this thread in NEW thread
00064       //
00065       fThreadStatus = pthread_create(&fThread, NULL, Anp::run_alg_thread, this);
00066       
00067       if(fThreadStatus != 0)
00068       {
00069          cerr << "AlgThread::Run - invalid thread status: " << fThreadStatus << endl;
00070       }
00071    }
00072    else
00073    {
00074       //
00075       // No thread is created, set thread status to 1,
00076       // so that we do not try later to join same thread
00077       //
00078       fThreadStatus = 1;
00079 
00080       //
00081       // Make local copy of input record
00082       //
00083       fRecord = record;
00084       
00085       //
00086       // Run kNN algorithm in this thread
00087       //
00088       Run();
00089    }
00090 }
00091 
00092 //----------------------------------------------------------------------
00093 int Anp::AlgThread::Join()
00094 {
00095    //
00096    // If there is parallel thread running then attempt to join to main thread
00097    //
00098    if(fThreadStatus == 0)
00099    {
00100       return pthread_join(fThread, NULL);
00101    }
00102 
00103    return fThreadStatus;
00104 }
00105 
00106 //------------------------------------------------------------------------------------------
00107 bool Anp::AlgThread::Init(const Header &header)
00108 {
00109    //
00110    // Initiliaze FillkNN::AlgSnarl algorithm
00111    //
00112    
00113    if(!fAlg.valid())
00114    {
00115       cerr << "AlgThread::Init - invalid AlgSnarl handle" << endl;
00116       return false;
00117    }
00118 
00119    return fAlg -> Init(header);
00120 }
00121 
00122 //---------------------------------------------------------------------------------------
00123 void Anp::AlgThread::End(const DataBlock &block)
00124 {
00125    //
00126    // Send signal to algirithm that we are done here...
00127    //
00128    if(fAlg.valid()) fAlg -> End(block);
00129 }
00130 
00131 //---------------------------------------------------------------------------------------
00132 void Anp::AlgThread::Run()
00133 {
00134    //
00135    // This function _might_ be running in new thread and will 
00136    // modify internal class data so put lock on current thread.
00137    //
00138    Anp::Lock<Mutex> lock(fMutex);
00139 
00140    if(!fAlg.valid())
00141    {
00142       cerr << "AlgThread::Run - invalid AlgSnarl handle" << endl;
00143       return;
00144    }
00145 
00146    //
00147    // Store all already existing event and track keys
00148    //
00149    map<short, Anp::PrevDataKey> emap, tmap;
00150 
00151    for(EventIterator it = fRecord.EventBegIterator(); it != fRecord.EventEndIterator(); ++it)
00152    {
00153       emap[it -> EventIndex()] = Anp::PrevDataKey(it -> DataBeg(), it -> DataEnd());
00154    }
00155    for(TrackIterator it = fRecord.TrackBegIterator(); it != fRecord.TrackEndIterator(); ++it)
00156    {
00157       tmap[it -> TrackIndex()] = Anp::PrevDataKey(it -> DataBeg(), it -> DataEnd());
00158    }
00159 
00160    //
00161    // Run algorithm...
00162    //
00163    fAlg -> Run(fRecord);
00164 
00165    //
00166    // Erase previous data with keys stored earlier
00167    //
00168    for(EventIterator it = fRecord.EventBegIterator(); it != fRecord.EventEndIterator(); ++it)
00169    {
00170       it -> Erase(std::remove_if(it -> DataBegIterator(),
00171                                  it -> DataEndIterator(),
00172                                  emap[it -> EventIndex()]), it -> DataEndIterator());
00173    }
00174 
00175    //
00176    // Erase previous data with keys stored earlier
00177    //
00178    for(TrackIterator it = fRecord.TrackBegIterator(); it != fRecord.TrackEndIterator(); ++it)
00179    {
00180       it -> Erase(std::remove_if(it -> DataBegIterator(),
00181                                  it -> DataEndIterator(),
00182                                  tmap[it -> TrackIndex()]), it -> DataEndIterator());
00183    }
00184 }
00185 
00186 //---------------------------------------------------------------------------------------
00187 Anp::PrevDataKey::PrevDataKey()
00188    :dvec(),
00189     valid(false)
00190 {
00191 }
00192 
00193 //---------------------------------------------------------------------------------------
00194 Anp::PrevDataKey::PrevDataKey(DataIter ibeg, DataIter iend)
00195    :dvec(),
00196     valid(true)
00197 {
00198    //
00199    // Save input elements: key and data pairs
00200    //
00201    dvec.insert(dvec.end(), ibeg, iend);
00202 
00203    //
00204    // Sort keys
00205    //
00206    std::sort(dvec.begin(), dvec.end());
00207 }
00208 
00209 //---------------------------------------------------------------------------------------
00210 Anp::PrevDataKey::PrevDataKey(const vector<short> &kvec_)
00211    :dvec(),
00212     valid(true)
00213 {
00214    for(unsigned int i = 0; i < kvec_.size(); ++i)
00215    {
00216       dvec.push_back(Anp::Data(kvec_[i], 0.0));
00217    }
00218 
00219    //
00220    // Sort vector
00221    //
00222    std::sort(dvec.begin(), dvec.end());
00223 }
00224 
00225 //---------------------------------------------------------------------------------------
00226 bool Anp::PrevDataKey::operator()(const Data &data) const
00227 {
00228    if(!valid)
00229    {
00230       cerr << "PrevDataKey::operator() - invalid internal state" << endl;
00231       return false;
00232    }
00233 
00234    //
00235    // return true if this key is found
00236    //
00237    return std::binary_search(dvec.begin(), dvec.end(), data);
00238 }
00239 
00240 //---------------------------------------------------------------------------------------
00241 bool Anp::PrevDataKey::operator() (Event &event) const
00242 {
00243    if(!valid)
00244    {
00245       cerr << "PrevDataKey::operator() - invalid internal state" << endl;
00246       return false;
00247    }
00248 
00249    //
00250    // Add current elements to Event
00251    //
00252    for(DataVec::const_iterator dit = dvec.begin(); dit != dvec.end(); ++dit)
00253    {
00254       event.Add(dit -> Key(), dit -> Data());
00255    }
00256 
00257    return true;
00258 }
00259 
00260 //---------------------------------------------------------------------------------------
00261 bool Anp::PrevDataKey::operator() (Track &track) const
00262 {
00263    if(!valid)
00264    {
00265       cerr << "PrevDataKey::operator() - invalid internal state" << endl;
00266       return false;
00267    }
00268 
00269    //
00270    // Add current elements to Track
00271    //
00272    for(DataVec::const_iterator dit = dvec.begin(); dit != dvec.end(); ++dit)
00273    {
00274       track.Add(dit -> Key(), dit -> Data());
00275    }
00276 
00277    return true;
00278 }

Generated on Mon Feb 15 11:06:20 2010 for loon by  doxygen 1.3.9.1