// toiproducer.cc // Eric Aubourg CEA/DAPNIA/SPP septembre 1999 #include #include #include "toiproducer.h" #include "toiabsorber.h" #include "toimanager.h" #include "archexc.h" #include "requesthandler.h" void TOIProducer::outManifest(RequestHandler* h) { outVersion(h); h->processOption("#COMMENT", " Producing:"); for (set::iterator i = producedTOIs.begin(); i != producedTOIs.end(); i++) { h->processOption("#COMMENT", " " + (*i).fullName()); } } void TOIProducer::outVersion(RequestHandler* h) { h->processOption("#COMMENT", getName()); } string TOIProducer::getName() { return("Anonymous"); } bool TOIProducer::canProduce(TOI const& toi) { // It should be in our list of possibleTOI's TOI myTOI; for (set::const_iterator i = possibleTOIs.begin(); i != possibleTOIs.end(); i++) { if ((toi.name == (*i).name) && (toi.index == (*i).index || (*i).index == TOI::all)) { myTOI = (*i); break; } } if (myTOI.name == "") return false; // not in list // Handle options set extraopts = toi.options; // should contain mandatory options for (set::iterator i = myTOI.reqOptions.begin(); i != myTOI.reqOptions.end(); i++) { if (extraopts.find(*i) == extraopts.end()) return false; } // remove local options for (set::iterator i = myTOI.options.begin(); i != myTOI.options.end(); i++) { extraopts.erase(*i); } // should be nothing left if (!extraopts.empty()) return false; return true; } void TOIProducer::addTOI(TOI& toi, TOIAbsorber* client) { if (!canProduce(toi)) throw ArchExc("Cannot produce " + toi.name); // Add unit... for (set::const_iterator i = possibleTOIs.begin(); i != possibleTOIs.end(); i++) { if (toi.name == (*i).name) { toi.unit = (*i).unit; break; } } clients[client].insert(toi); lastNeededSample[toi.ref][client] = 0; producedTOIs.insert(toi); } bool TOIProducer::isProducing(TOI const& toi) { return (producedTOIs.find(toi) != producedTOIs.end()); } long TOIProducer::wontNeedEarlier(TOI const& toi, TOIAbsorber* client, long t) { CHKPROD long oldT = lastNeededSample[toi.ref][client]; if (t m = lastNeededSample[toi.ref]; long min=999999999L; for (map::iterator i = m.begin(); i != m.end(); i++) { if ((*i).second < min) min = (*i).second; } deque >& h = history[toi.ref]; while(!h.empty() && h.front().first < min) h.pop_front(); return min; } set TOIProducer::getProperAvailOptions(TOI const& toi) { // toi.options.clear(); // toi.index = -2; // set::const_iterator i = possibleTOIs.upper_bound(toi); // if ((*i).name != toi.name) throw ArchExc("no such toi " + toi.name); for (set::const_iterator i = possibleTOIs.begin(); i != possibleTOIs.end(); i++) if ((*i).name == toi.name) return (*i).options; throw ArchExc("no such toi " + toi.name); } set TOIProducer::getAvailOptions(TOI const& toi) { return getProperAvailOptions(toi); } long TOIProducer::firstSampleNum(TOI const& toi) { CHKPROD // deque > h = (*history.find(toi)).second; deque >& h = history[toi.ref]; if (h.empty()) return 99999999; return h.front().first; } long TOIProducer::lastSampleNum(TOI const& toi) { CHKPROD deque >& h = history[toi.ref]; if (h.empty()) return -99999999; return h.back().first; } class comp2nd { public:bool operator()(pair const& a, long b) {return a.first const& b) {return a >::const_iterator TOIProducer::findHistL(TOI const& toi,long sampleNum) { CHKPROD deque >& h = history[toi.ref]; return lower_bound(h.begin(), h.end(), sampleNum, comp2nd()); } deque >::const_iterator TOIProducer::findHistL(deque >& h,long sampleNum) { return lower_bound(h.begin(), h.end(), sampleNum, comp2nd()); } deque >::const_iterator TOIProducer::findHistH(TOI const& toi,long sampleNum) { CHKPROD deque >& h = history[toi.ref]; return upper_bound(h.begin(), h.end(), sampleNum, comp2ndI()); } deque >::const_iterator TOIProducer::findHistH(deque >& h,long sampleNum) { return upper_bound(h.begin(), h.end(), sampleNum, comp2ndI()); } bool TOIProducer::canGetValue(long sampleNum, TOI const& toi) { CHKPROD deque >& h = history[toi.ref]; if (h.empty()) return false; if (sampleNum < h.front().first || sampleNum > h.back().first) return false; deque >::const_iterator i = findHistL(h, sampleNum); if (i == h.end()) return false; return ((*i).first == sampleNum); } bool TOIProducer::canGetValueLater(long sampleNum, TOI const& toi) { CHKPROD deque >& h = history[toi.ref]; if (h.empty()) return true; int x = h.back().first; return sampleNum > x; return (sampleNum > h.back().first); } bool TOIProducer::canGetPrevValue(long sampleNum, TOI const& toi) { CHKPROD deque >& h = history[toi.ref]; if (h.empty()) return false; return (sampleNum > h.front().first && sampleNum <= h.back().first); // Must be inside, otherwise we don't know if it is prev or simply past } bool TOIProducer::canGetNextValue(long sampleNum, TOI const& toi) { CHKPROD deque >& h = history[toi.ref]; if (h.empty()) return false; return (sampleNum >= h.front().first && sampleNum < h.back().first); } double TOIProducer::getValue(long sampleNum, TOI const& toi) { deque >& h = history[toi.ref]; // cout << "request " << sampleNum << " history " // << h.front().first // << " " << h.back().first << endl; deque >::const_iterator i = findHistL(h, sampleNum); if (i == h.end()) return -999999; // cout << "found " << (*i).first << endl; return ((*i).first == sampleNum) ? (*i).second : -999999; } // $CHECK$ check this carefully !!!! double TOIProducer::getPrevValue(long& sampleNum, TOI const& toi) { deque >& h = history[toi.ref]; deque >::const_iterator i = findHistH(h, sampleNum); if (i == h.end()) return -999999; pair tstpair = *i; while ((*i).first >= sampleNum) { if (i == history[toi.ref].begin()) {sampleNum = -99999 ;return -9999;} i--; } tstpair = *i; sampleNum = (*i).first; return (*i).second; } double TOIProducer::getNextValue(long& sampleNum, TOI const& toi) { deque >& h = history[toi.ref]; deque >::const_iterator i = findHistL(h, sampleNum); if (i == h.end()) return -999999; pair tstpair = *i; while ((*i).first <= sampleNum) { if (i == history[toi.ref].end()) {sampleNum = -99999 ;return -9999;} i++; } tstpair=*i; sampleNum = (*i).first; return (*i).second; } void TOIProducer::computedValue(TOI const& toi, long sampleNum, double value) { //map > >::iterator i = history.find(toi.ref); //if (i == history.end()) throw ArchExc("computedValue : bad TOI " + toi.name); //deque >& h = (*i).second; deque >& h = history[toi.ref]; if (!h.empty() && sampleNum <= h.back().first) throw ArchExc("computedValue : sampleNum not in sequence for " + toi.name); h.push_back(pair(sampleNum,value)); for (map >::iterator j = clients.begin(); j != clients.end(); j++) { set& tois = (*j).second; if (tois.find(toi) != tois.end()) (*j).first->dataFeed(this, toi, sampleNum, value); } } void TOILowLevProducer::addTOI(TOI& toi, TOIAbsorber* client) { TOIProducer::addTOI(toi, client); TOIManager::activateLLProducer(this); }