[534] | 1 | // toiproducer.cc
|
---|
| 2 | // Eric Aubourg CEA/DAPNIA/SPP septembre 1999
|
---|
| 3 |
|
---|
| 4 | #include <iostream.h>
|
---|
| 5 |
|
---|
| 6 | #include "toiproducer.h"
|
---|
| 7 | #include "toiabsorber.h"
|
---|
| 8 | #include "toimanager.h"
|
---|
| 9 | #include "archexc.h"
|
---|
| 10 | #include "requesthandler.h"
|
---|
| 11 |
|
---|
| 12 | void TOIProducer::outManifest(RequestHandler* h) {
|
---|
| 13 | outVersion(h);
|
---|
| 14 | h->processOption("#COMMENT", " Producing:");
|
---|
| 15 | for (set<TOI>::iterator i = producedTOIs.begin(); i != producedTOIs.end(); i++) {
|
---|
| 16 | h->processOption("#COMMENT", " " + (*i).fullName());
|
---|
| 17 | }
|
---|
| 18 | }
|
---|
| 19 |
|
---|
| 20 | void TOIProducer::outVersion(RequestHandler* h) {
|
---|
| 21 | h->processOption("#COMMENT", getName());
|
---|
| 22 | }
|
---|
| 23 |
|
---|
| 24 | string TOIProducer::getName() {
|
---|
| 25 | return("Anonymous");
|
---|
| 26 | }
|
---|
| 27 |
|
---|
| 28 |
|
---|
| 29 | bool TOIProducer::canProduce(TOI const& toi) {
|
---|
| 30 | // It should be in our list of possibleTOI's
|
---|
| 31 | TOI myTOI;
|
---|
| 32 | for (set<TOI>::const_iterator i = possibleTOIs.begin(); i != possibleTOIs.end(); i++) {
|
---|
| 33 | if ((toi.name == (*i).name) &&
|
---|
| 34 | (toi.index == (*i).index || (*i).index == TOI::all)) {
|
---|
| 35 | myTOI = (*i);
|
---|
| 36 | break;
|
---|
| 37 | }
|
---|
| 38 | }
|
---|
| 39 | if (myTOI.name == "") return false; // not in list
|
---|
| 40 |
|
---|
| 41 | // Handle options
|
---|
| 42 |
|
---|
| 43 | set<string> extraopts = toi.options;
|
---|
| 44 |
|
---|
| 45 | // should contain mandatory options
|
---|
| 46 | for (set<string>::iterator i = myTOI.reqOptions.begin();
|
---|
| 47 | i != myTOI.reqOptions.end(); i++) {
|
---|
| 48 | if (extraopts.find(*i) == extraopts.end()) return false;
|
---|
| 49 | }
|
---|
| 50 |
|
---|
| 51 | // remove local options
|
---|
| 52 | for (set<string>::iterator i = myTOI.options.begin();
|
---|
| 53 | i != myTOI.options.end(); i++) {
|
---|
| 54 | extraopts.erase(*i);
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | // should be nothing left
|
---|
| 58 | if (!extraopts.empty()) return false;
|
---|
[555] | 59 |
|
---|
[534] | 60 | return true;
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | void TOIProducer::addTOI(TOI& toi, TOIAbsorber* client) {
|
---|
| 64 | if (!canProduce(toi)) throw ArchExc("Cannot produce " + toi.name);
|
---|
| 65 | // Add unit...
|
---|
| 66 | for (set<TOI>::const_iterator i = possibleTOIs.begin(); i != possibleTOIs.end(); i++) {
|
---|
| 67 | if (toi.name == (*i).name) {
|
---|
| 68 | toi.unit = (*i).unit;
|
---|
| 69 | break;
|
---|
| 70 | }
|
---|
| 71 | }
|
---|
| 72 |
|
---|
| 73 | clients[client].insert(toi);
|
---|
| 74 | lastNeededSample[toi.ref][client] = 0;
|
---|
| 75 | producedTOIs.insert(toi);
|
---|
| 76 | }
|
---|
| 77 |
|
---|
| 78 | bool TOIProducer::isProducing(TOI const& toi) {
|
---|
| 79 | return (producedTOIs.find(toi) != producedTOIs.end());
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 |
|
---|
| 83 | long TOIProducer::wontNeedEarlier(TOI const& toi, TOIAbsorber* client, long t) {
|
---|
| 84 | CHKPROD
|
---|
| 85 | long oldT = lastNeededSample[toi.ref][client];
|
---|
| 86 | if (t<oldT) return -1;
|
---|
| 87 | lastNeededSample[toi.ref][client] = t;
|
---|
| 88 | map<TOIAbsorber*, long> m = lastNeededSample[toi.ref];
|
---|
| 89 | long min=999999999L;
|
---|
| 90 | for (map<TOIAbsorber*, long>::iterator i = m.begin(); i != m.end(); i++) {
|
---|
| 91 | if ((*i).second < min) min = (*i).second;
|
---|
| 92 | }
|
---|
| 93 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 94 | while(!h.empty() && h.front().first < min) h.pop_front();
|
---|
| 95 | return min;
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | set<string> TOIProducer::getProperAvailOptions(TOI const& toi) {
|
---|
| 99 | // toi.options.clear();
|
---|
| 100 | // toi.index = -2;
|
---|
| 101 | // set<TOI>::const_iterator i = possibleTOIs.upper_bound(toi);
|
---|
| 102 | // if ((*i).name != toi.name) throw ArchExc("no such toi " + toi.name);
|
---|
| 103 | for (set<TOI>::const_iterator i = possibleTOIs.begin(); i != possibleTOIs.end(); i++)
|
---|
| 104 | if ((*i).name == toi.name)
|
---|
| 105 | return (*i).options;
|
---|
| 106 | throw ArchExc("no such toi " + toi.name);
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | set<string> TOIProducer::getAvailOptions(TOI const& toi) {
|
---|
| 110 | return getProperAvailOptions(toi);
|
---|
| 111 | }
|
---|
| 112 |
|
---|
| 113 |
|
---|
| 114 |
|
---|
| 115 | long TOIProducer::firstSampleNum(TOI const& toi) {
|
---|
| 116 | CHKPROD
|
---|
| 117 | // deque<pair<long, double> > h = (*history.find(toi)).second;
|
---|
| 118 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 119 | if (h.empty()) return 99999999;
|
---|
| 120 | return h.front().first;
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | long TOIProducer::lastSampleNum(TOI const& toi) {
|
---|
| 124 | CHKPROD
|
---|
| 125 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 126 | if (h.empty()) return -99999999;
|
---|
| 127 | return h.back().first;
|
---|
| 128 | }
|
---|
| 129 |
|
---|
| 130 | class comp2nd { public:bool operator()(pair<long, double> const& a, long b) {return a.first<b;}};
|
---|
[555] | 131 | class comp2ndI { public:bool operator()(long a, pair<long, double> const& b) {return a<b.first;}};
|
---|
[534] | 132 |
|
---|
[555] | 133 | deque<pair<long, double> >::const_iterator TOIProducer::findHistL(TOI const& toi,long sampleNum) {
|
---|
[534] | 134 | CHKPROD
|
---|
| 135 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 136 | return lower_bound(h.begin(), h.end(), sampleNum, comp2nd());
|
---|
| 137 | }
|
---|
| 138 |
|
---|
[555] | 139 | deque<pair<long, double> >::const_iterator TOIProducer::findHistL(deque<pair<long, double> >& h,long sampleNum) {
|
---|
[534] | 140 | return lower_bound(h.begin(), h.end(), sampleNum, comp2nd());
|
---|
| 141 | }
|
---|
| 142 |
|
---|
[555] | 143 | deque<pair<long, double> >::const_iterator TOIProducer::findHistH(TOI const& toi,long sampleNum) {
|
---|
| 144 | CHKPROD
|
---|
| 145 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 146 | return upper_bound(h.begin(), h.end(), sampleNum, comp2ndI());
|
---|
| 147 | }
|
---|
| 148 |
|
---|
| 149 | deque<pair<long, double> >::const_iterator TOIProducer::findHistH(deque<pair<long, double> >& h,long sampleNum) {
|
---|
| 150 | return upper_bound(h.begin(), h.end(), sampleNum, comp2ndI());
|
---|
| 151 | }
|
---|
| 152 |
|
---|
| 153 |
|
---|
[534] | 154 | bool TOIProducer::canGetValue(long sampleNum, TOI const& toi) {
|
---|
| 155 | CHKPROD
|
---|
| 156 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 157 | if (h.empty()) return false;
|
---|
| 158 | if (sampleNum < h.front().first || sampleNum > h.back().first) return false;
|
---|
[555] | 159 | deque<pair<long, double> >::const_iterator i = findHistL(h, sampleNum);
|
---|
[534] | 160 | if (i == h.end()) return false;
|
---|
| 161 | return ((*i).first == sampleNum);
|
---|
| 162 | }
|
---|
| 163 |
|
---|
| 164 | bool TOIProducer::canGetValueLater(long sampleNum, TOI const& toi) {
|
---|
| 165 | CHKPROD
|
---|
| 166 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 167 | if (h.empty()) return true;
|
---|
| 168 | int x = h.back().first;
|
---|
| 169 | return sampleNum > x;
|
---|
| 170 | return (sampleNum > h.back().first);
|
---|
| 171 | }
|
---|
| 172 |
|
---|
| 173 | bool TOIProducer::canGetPrevValue(long sampleNum, TOI const& toi) {
|
---|
| 174 | CHKPROD
|
---|
| 175 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 176 | if (h.empty()) return false;
|
---|
[555] | 177 | return (sampleNum > h.front().first && sampleNum <= h.back().first);
|
---|
[534] | 178 | // Must be inside, otherwise we don't know if it is prev or simply past
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | bool TOIProducer::canGetNextValue(long sampleNum, TOI const& toi) {
|
---|
| 182 | CHKPROD
|
---|
| 183 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 184 | if (h.empty()) return false;
|
---|
[555] | 185 | return (sampleNum >= h.front().first && sampleNum < h.back().first);
|
---|
[534] | 186 | }
|
---|
| 187 |
|
---|
| 188 | double TOIProducer::getValue(long sampleNum, TOI const& toi) {
|
---|
| 189 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
| 190 | // cout << "request " << sampleNum << " history "
|
---|
| 191 | // << h.front().first
|
---|
| 192 | // << " " << h.back().first << endl;
|
---|
[555] | 193 | deque<pair<long, double> >::const_iterator i = findHistL(h, sampleNum);
|
---|
[534] | 194 | if (i == h.end()) return -999999;
|
---|
| 195 | // cout << "found " << (*i).first << endl;
|
---|
| 196 | return ((*i).first == sampleNum) ? (*i).second : -999999;
|
---|
| 197 | }
|
---|
| 198 |
|
---|
| 199 | // $CHECK$ check this carefully !!!!
|
---|
| 200 |
|
---|
| 201 | double TOIProducer::getPrevValue(long& sampleNum, TOI const& toi) {
|
---|
| 202 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
[555] | 203 | deque<pair<long, double> >::const_iterator i = findHistH(h, sampleNum);
|
---|
[534] | 204 | if (i == h.end()) return -999999;
|
---|
[555] | 205 | pair<long, double> tstpair = *i;
|
---|
| 206 | while ((*i).first >= sampleNum) {
|
---|
[534] | 207 | if (i == history[toi.ref].begin()) {sampleNum = -99999 ;return -9999;}
|
---|
| 208 | i--;
|
---|
| 209 | }
|
---|
[555] | 210 | tstpair = *i;
|
---|
[534] | 211 | sampleNum = (*i).first;
|
---|
| 212 | return (*i).second;
|
---|
| 213 | }
|
---|
| 214 |
|
---|
| 215 | double TOIProducer::getNextValue(long& sampleNum, TOI const& toi) {
|
---|
| 216 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
[555] | 217 | deque<pair<long, double> >::const_iterator i = findHistL(h, sampleNum);
|
---|
[534] | 218 | if (i == h.end()) return -999999;
|
---|
[555] | 219 | pair<long, double> tstpair = *i;
|
---|
| 220 | while ((*i).first <= sampleNum) {
|
---|
[534] | 221 | if (i == history[toi.ref].end()) {sampleNum = -99999 ;return -9999;}
|
---|
| 222 | i++;
|
---|
| 223 | }
|
---|
[555] | 224 | tstpair=*i;
|
---|
[534] | 225 | sampleNum = (*i).first;
|
---|
| 226 | return (*i).second;
|
---|
| 227 | }
|
---|
| 228 |
|
---|
| 229 | void TOIProducer::computedValue(TOI const& toi, long sampleNum, double value) {
|
---|
[555] | 230 | //map<int, deque<pair<long, double> > >::iterator i = history.find(toi.ref);
|
---|
| 231 | //if (i == history.end()) throw ArchExc("computedValue : bad TOI " + toi.name);
|
---|
| 232 | //deque<pair<long, double> >& h = (*i).second;
|
---|
| 233 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
[534] | 234 | if (!h.empty() && sampleNum <= h.back().first)
|
---|
| 235 | throw ArchExc("computedValue : sampleNum not in sequence for " + toi.name);
|
---|
| 236 | h.push_back(pair<long,double>(sampleNum,value));
|
---|
| 237 | for (map<TOIAbsorber*, set<TOI> >::iterator j = clients.begin(); j != clients.end(); j++) {
|
---|
| 238 | set<TOI>& tois = (*j).second;
|
---|
| 239 | if (tois.find(toi) != tois.end())
|
---|
| 240 | (*j).first->dataFeed(this, toi, sampleNum, value);
|
---|
| 241 | }
|
---|
| 242 | }
|
---|
| 243 |
|
---|
| 244 |
|
---|
| 245 |
|
---|
| 246 |
|
---|
| 247 |
|
---|
| 248 | void TOILowLevProducer::addTOI(TOI& toi, TOIAbsorber* client) {
|
---|
| 249 | TOIProducer::addTOI(toi, client);
|
---|
| 250 | TOIManager::activateLLProducer(this);
|
---|
| 251 | }
|
---|