1 | // toiderivproducer.cc
|
---|
2 | // Eric Aubourg CEA/DAPNIA/SPP septembre 1999
|
---|
3 |
|
---|
4 | #include "toiderivproducer.h"
|
---|
5 | #include "toimanager.h"
|
---|
6 | #include "archexc.h"
|
---|
7 | #include "requesthandler.h"
|
---|
8 | #include "subsets.h"
|
---|
9 |
|
---|
10 | set<TOI> TOIDerivProducer::reqTOIFor(TOI const&) {
|
---|
11 | set<TOI> empty;
|
---|
12 | return empty;
|
---|
13 | }
|
---|
14 |
|
---|
15 | void TOIDerivProducer::outManifest(RequestHandler* h) {
|
---|
16 | outVersion(h);
|
---|
17 | h->processOption("#COMMENT", " Producing:");
|
---|
18 | for (set<TOI>::iterator i = producedTOIs.begin(); i != producedTOIs.end(); i++) {
|
---|
19 | h->processOption("#COMMENT", " " + (*i).fullName());
|
---|
20 | set<TOI> x = reqTOIFor(*i);
|
---|
21 | if (!x.empty()) {
|
---|
22 | h->processOption("#COMMENT", " from:");
|
---|
23 | for (set<TOI>::iterator j=x.begin(); j!=x.end(); j++) {
|
---|
24 | h->processOption("#COMMENT", " " + (*j).fullName());
|
---|
25 | }
|
---|
26 | }
|
---|
27 | }
|
---|
28 | }
|
---|
29 |
|
---|
30 |
|
---|
31 | bool TOIDerivProducer::canProduce(TOI const& toi) {
|
---|
32 | // 1. Already in cache ?
|
---|
33 | map<TOI, map<TOI, TOIProducer*> >::const_iterator j = neededTOIs.find(toi);
|
---|
34 | if (j != neededTOIs.end()) return true;
|
---|
35 |
|
---|
36 | // 2. It should be in our list of possibleTOI's
|
---|
37 | TOI myTOI;
|
---|
38 | for (set<TOI>::const_iterator i = possibleTOIs.begin(); i != possibleTOIs.end(); i++) {
|
---|
39 | if ((toi.name == (*i).name) &&
|
---|
40 | (toi.index == (*i).index || (*i).index == TOI::all)) {
|
---|
41 | myTOI = (*i);
|
---|
42 | break;
|
---|
43 | }
|
---|
44 | }
|
---|
45 | if (myTOI.name == "") return false; // not in list
|
---|
46 |
|
---|
47 | // 3. Handle options
|
---|
48 |
|
---|
49 | set<string> extraopts = toi.options;
|
---|
50 |
|
---|
51 | // 3a should contain mandatory options
|
---|
52 | for (set<string>::iterator i = myTOI.reqOptions.begin();
|
---|
53 | i != myTOI.reqOptions.end(); i++) {
|
---|
54 | if (extraopts.find(*i) == extraopts.end()) return false;
|
---|
55 | }
|
---|
56 |
|
---|
57 | // 3b remove local options
|
---|
58 |
|
---|
59 | for (set<string>::iterator i = myTOI.options.begin();
|
---|
60 | i != myTOI.options.end(); i++) {
|
---|
61 | extraopts.erase(*i);
|
---|
62 | }
|
---|
63 |
|
---|
64 | set<string> unusedextra = extraopts;
|
---|
65 |
|
---|
66 | // 4. Find producers, distribute remaining options
|
---|
67 | map<TOI, TOIProducer*> fullInputTOI;
|
---|
68 | set<TOI> inputTOIs = reqTOIFor(toi);
|
---|
69 | for (set<TOI>::iterator i = inputTOIs.begin(); i != inputTOIs.end(); i++) {
|
---|
70 | TOI inTOI = *i;
|
---|
71 | //TOIProducer* prod0 = TOIManager::findTOIProducer(inTOI);
|
---|
72 | // Let's see if we get others with options, we have to do this because
|
---|
73 | // of required options, and we have to iterate over all subsets of the options.
|
---|
74 | // This algorithm is NOT correct, but should work for realistic cases...
|
---|
75 | int nmaxopt=-1;
|
---|
76 | TOIProducer* prod=NULL;
|
---|
77 | set<set<string> > optsets = getSetOfSubsets(extraopts);
|
---|
78 | for (set<set<string> >::iterator j = optsets.begin(); j != optsets.end(); j++) {
|
---|
79 | TOI toi2 = inTOI;
|
---|
80 | toi2.options.insert((*j).begin(), (*j).end());
|
---|
81 | TOIProducer* prod0 = TOIManager::findTOIProducer(toi2);
|
---|
82 | if (prod0 == NULL) continue;
|
---|
83 | if ((long) toi2.options.size() > nmaxopt) {
|
---|
84 | prod = prod0;
|
---|
85 | nmaxopt = toi2.options.size();
|
---|
86 | }
|
---|
87 | }
|
---|
88 | if (!prod) return false;
|
---|
89 | if (!extraopts.empty()) {
|
---|
90 | set<string> xopts = prod->getAvailOptions(inTOI);
|
---|
91 | for (set<string>::iterator j = xopts.begin(); j != xopts.end(); j++) {
|
---|
92 | if (extraopts.find(*j) != extraopts.end()) {
|
---|
93 | inTOI.options.insert(*j);
|
---|
94 | unusedextra.erase(*j);
|
---|
95 | }
|
---|
96 | }
|
---|
97 | }
|
---|
98 | fullInputTOI[inTOI] = prod;
|
---|
99 | }
|
---|
100 |
|
---|
101 | if (!unusedextra.empty()) return false;
|
---|
102 |
|
---|
103 | neededTOIs[toi] = fullInputTOI;
|
---|
104 | return true;
|
---|
105 | }
|
---|
106 |
|
---|
107 | set<string> TOIDerivProducer::getAvailOptions(TOI const& toi) {
|
---|
108 | // toi.options.clear();
|
---|
109 | // toi.index = -2;
|
---|
110 | // if (!canProduce(toi)) throw ArchExc("cannot produce " + toi.name);
|
---|
111 | set<string> s = getProperAvailOptions(toi);
|
---|
112 | map<TOI, TOIProducer*> & need = neededTOIs[toi];
|
---|
113 | for (map<TOI, TOIProducer*>::iterator i = need.begin(); i != need.end(); i++) {
|
---|
114 | set<string> s1 = (*i).second->getAvailOptions((*i).first);
|
---|
115 | s.insert(s1.begin(), s1.end());
|
---|
116 | }
|
---|
117 | return s;
|
---|
118 | }
|
---|
119 |
|
---|
120 | void TOIDerivProducer::addTOI(TOI& toi, TOIAbsorber* client) {
|
---|
121 | TOIProducer::addTOI(toi, client);
|
---|
122 | map<TOI, TOIProducer*> & m = neededTOIs[toi];
|
---|
123 | for (map<TOI, TOIProducer*>::iterator i = m.begin(); i != m.end(); i++) {
|
---|
124 | TOI toi2 = (*i).first;
|
---|
125 | (*i).second->addTOI(toi2,this);
|
---|
126 | }
|
---|
127 | }
|
---|
128 |
|
---|
129 | long TOIDerivProducer::wontNeedEarlier(TOI const& toi, TOIAbsorber* client, long t) {
|
---|
130 | long xt = TOIProducer::wontNeedEarlier(toi, client, t);
|
---|
131 | if (xt>0) propagateLowBound(toi, xt);
|
---|
132 | return xt;
|
---|
133 | }
|
---|
134 |
|
---|
135 | // if no need for past values...
|
---|
136 | void TOIDerivProducer::propagateLowBound(TOI const& toi, long sampleNum) {
|
---|
137 | CHKPROD
|
---|
138 | map<TOI, TOIProducer*> & need = neededTOIs[toi];
|
---|
139 | for (map<TOI, TOIProducer*>::iterator i = need.begin(); i != need.end(); i++) {
|
---|
140 | (*i).second->wontNeedEarlier((*i).first, this, sampleNum);
|
---|
141 | }
|
---|
142 | }
|
---|