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 |
|
---|
132 | deque<pair<long, double> >::const_iterator TOIProducer::findHist(TOI const& toi,long sampleNum) {
|
---|
133 | CHKPROD
|
---|
134 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
135 | return lower_bound(h.begin(), h.end(), sampleNum, comp2nd());
|
---|
136 | }
|
---|
137 |
|
---|
138 | deque<pair<long, double> >::const_iterator TOIProducer::findHist(deque<pair<long, double> >& h,long sampleNum) {
|
---|
139 | return lower_bound(h.begin(), h.end(), sampleNum, comp2nd());
|
---|
140 | }
|
---|
141 |
|
---|
142 | bool TOIProducer::canGetValue(long sampleNum, TOI const& toi) {
|
---|
143 | CHKPROD
|
---|
144 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
145 | if (h.empty()) return false;
|
---|
146 | if (sampleNum < h.front().first || sampleNum > h.back().first) return false;
|
---|
147 | deque<pair<long, double> >::const_iterator i = findHist(h, sampleNum);
|
---|
148 | if (i == h.end()) return false;
|
---|
149 | return ((*i).first == sampleNum);
|
---|
150 | }
|
---|
151 |
|
---|
152 | bool TOIProducer::canGetValueLater(long sampleNum, TOI const& toi) {
|
---|
153 | CHKPROD
|
---|
154 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
155 | if (h.empty()) return true;
|
---|
156 | int x = h.back().first;
|
---|
157 | return sampleNum > x;
|
---|
158 | return (sampleNum > h.back().first);
|
---|
159 | }
|
---|
160 |
|
---|
161 | bool TOIProducer::canGetPrevValue(long sampleNum, TOI const& toi) {
|
---|
162 | CHKPROD
|
---|
163 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
164 | if (h.empty()) return false;
|
---|
165 | return (sampleNum > h.back().first && sampleNum <= h.front().first);
|
---|
166 | // Must be inside, otherwise we don't know if it is prev or simply past
|
---|
167 | }
|
---|
168 |
|
---|
169 | bool TOIProducer::canGetNextValue(long sampleNum, TOI const& toi) {
|
---|
170 | CHKPROD
|
---|
171 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
172 | if (h.empty()) return false;
|
---|
173 | return (sampleNum >= h.back().first && sampleNum < h.front().first);
|
---|
174 | }
|
---|
175 |
|
---|
176 | double TOIProducer::getValue(long sampleNum, TOI const& toi) {
|
---|
177 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
178 | // cout << "request " << sampleNum << " history "
|
---|
179 | // << h.front().first
|
---|
180 | // << " " << h.back().first << endl;
|
---|
181 | deque<pair<long, double> >::const_iterator i = findHist(h, sampleNum);
|
---|
182 | if (i == h.end()) return -999999;
|
---|
183 | // cout << "found " << (*i).first << endl;
|
---|
184 | return ((*i).first == sampleNum) ? (*i).second : -999999;
|
---|
185 | }
|
---|
186 |
|
---|
187 | // $CHECK$ check this carefully !!!!
|
---|
188 |
|
---|
189 | double TOIProducer::getPrevValue(long& sampleNum, TOI const& toi) {
|
---|
190 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
191 | deque<pair<long, double> >::const_iterator i = findHist(h, sampleNum);
|
---|
192 | if (i == h.end()) return -999999;
|
---|
193 | if ((*i).first == sampleNum) {
|
---|
194 | if (i == history[toi.ref].begin()) {sampleNum = -99999 ;return -9999;}
|
---|
195 | i--;
|
---|
196 | }
|
---|
197 | sampleNum = (*i).first;
|
---|
198 | return (*i).second;
|
---|
199 | }
|
---|
200 |
|
---|
201 | double TOIProducer::getNextValue(long& sampleNum, TOI const& toi) {
|
---|
202 | deque<pair<long, double> >& h = history[toi.ref];
|
---|
203 | deque<pair<long, double> >::const_iterator i = findHist(h, sampleNum);
|
---|
204 | if (i == h.end()) return -999999;
|
---|
205 | if ((*i).first == sampleNum) {
|
---|
206 | if (i == history[toi.ref].end()) {sampleNum = -99999 ;return -9999;}
|
---|
207 | i++;
|
---|
208 | }
|
---|
209 | sampleNum = (*i).first;
|
---|
210 | return (*i).second;
|
---|
211 | }
|
---|
212 |
|
---|
213 | void TOIProducer::computedValue(TOI const& toi, long sampleNum, double value) {
|
---|
214 | map<int, deque<pair<long, double> > >::iterator i = history.find(toi.ref);
|
---|
215 | if (i == history.end()) throw ArchExc("computedValue : bad TOI " + toi.name);
|
---|
216 | deque<pair<long, double> >& h = (*i).second;
|
---|
217 | if (!h.empty() && sampleNum <= h.back().first)
|
---|
218 | throw ArchExc("computedValue : sampleNum not in sequence for " + toi.name);
|
---|
219 | h.push_back(pair<long,double>(sampleNum,value));
|
---|
220 |
|
---|
221 | for (map<TOIAbsorber*, set<TOI> >::iterator j = clients.begin(); j != clients.end(); j++) {
|
---|
222 | set<TOI>& tois = (*j).second;
|
---|
223 | if (tois.find(toi) != tois.end())
|
---|
224 | (*j).first->dataFeed(this, toi, sampleNum, value);
|
---|
225 | }
|
---|
226 | }
|
---|
227 |
|
---|
228 |
|
---|
229 |
|
---|
230 |
|
---|
231 |
|
---|
232 | void TOILowLevProducer::addTOI(TOI& toi, TOIAbsorber* client) {
|
---|
233 | TOIProducer::addTOI(toi, client);
|
---|
234 | TOIManager::activateLLProducer(this);
|
---|
235 | }
|
---|