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