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;
|
---|
59 |
|
---|
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;}};
|
---|
131 | class comp2ndI { public:bool operator()(long a, pair<long, double> const& b) {return a<b.first;}};
|
---|
132 |
|
---|
133 | deque<pair<long, double> >::const_iterator TOIProducer::findHistL(TOI const& toi,long sampleNum) {
|
---|
134 | CHKPROD
|
---|
135 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
136 | return lower_bound(h.begin(), h.end(), sampleNum, comp2nd());
|
---|
137 | }
|
---|
138 |
|
---|
139 | deque<pair<long, double> >::const_iterator TOIProducer::findHistL(deque<pair<long, double> >& h,long sampleNum) {
|
---|
140 | return lower_bound(h.begin(), h.end(), sampleNum, comp2nd());
|
---|
141 | }
|
---|
142 |
|
---|
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 |
|
---|
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;
|
---|
159 | deque<pair<long, double> >::const_iterator i = findHistL(h, sampleNum);
|
---|
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;
|
---|
177 | return (sampleNum > h.front().first && sampleNum <= h.back().first);
|
---|
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;
|
---|
185 | return (sampleNum >= h.front().first && sampleNum < h.back().first);
|
---|
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;
|
---|
193 | deque<pair<long, double> >::const_iterator i = findHistL(h, sampleNum);
|
---|
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];
|
---|
203 | deque<pair<long, double> >::const_iterator i = findHistH(h, sampleNum);
|
---|
204 | if (i == h.end()) return -999999;
|
---|
205 | pair<long, double> tstpair = *i;
|
---|
206 | while ((*i).first >= sampleNum) {
|
---|
207 | if (i == history[toi.ref].begin()) {sampleNum = -99999 ;return -9999;}
|
---|
208 | i--;
|
---|
209 | }
|
---|
210 | tstpair = *i;
|
---|
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];
|
---|
217 | deque<pair<long, double> >::const_iterator i = findHistL(h, sampleNum);
|
---|
218 | if (i == h.end()) return -999999;
|
---|
219 | pair<long, double> tstpair = *i;
|
---|
220 | while ((*i).first <= sampleNum) {
|
---|
221 | if (i == history[toi.ref].end()) {sampleNum = -99999 ;return -9999;}
|
---|
222 | i++;
|
---|
223 | }
|
---|
224 | tstpair=*i;
|
---|
225 | sampleNum = (*i).first;
|
---|
226 | return (*i).second;
|
---|
227 | }
|
---|
228 |
|
---|
229 | void TOIProducer::computedValue(TOI const& toi, long sampleNum, double value) {
|
---|
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];
|
---|
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 | }
|
---|