00001 #ifndef CHANNELINFO_H_
00002 #define CHANNELINFO_H_
00003
00004 #include <list>
00005 #include <omnetpp.h>
00006 #include "AirFrame_m.h"
00007
00042 class ChannelInfo {
00043
00044 protected:
00045
00047 typedef std::pair<simtime_t, AirFrame*> AirFrameTimePair;
00049 typedef std::list<AirFrameTimePair> AirFrameTimeList;
00054 typedef std::map<simtime_t, AirFrameTimeList > AirFrameMatrix;
00055
00079 template<class C, class ItMatrix, class ItList>
00080 class BaseIntersectionIterator
00081 {
00082 public:
00084 C* intervals;
00085
00087 simtime_t from;
00088
00090 simtime_t to;
00091
00093 ItMatrix endIt;
00094
00096 ItList startIt;
00097
00099 bool alreadyNext;
00100
00101 public:
00102
00107 BaseIntersectionIterator(C* airFrames, simtime_t from, simtime_t to) :
00108 intervals(airFrames), from(from), to(to)
00109 {
00110
00111
00112 endIt = intervals->lower_bound(from);
00113
00114 if(endIt != intervals->end()) {
00115 startIt = endIt->second.begin();
00116 }
00117
00118 alreadyNext = true;
00119 }
00120
00125 AirFrame* next()
00126 {
00127 if(endIt == intervals->end())
00128 return 0;
00129
00130
00131
00132
00133
00134 if(alreadyNext)
00135 alreadyNext = false;
00136 else
00137 startIt++;
00138
00139
00140 while(endIt != intervals->end())
00141 {
00142
00143 while(startIt != endIt->second.end())
00144 {
00145
00146
00147
00148 if(startIt->first <= to) {
00149 return startIt->second;
00150 }
00151 startIt++;
00152 }
00153
00154 endIt++;
00155 if(endIt == intervals->end())
00156 return 0;
00157
00158 startIt = endIt->second.begin();
00159
00160 }
00161
00162 return 0;
00163 }
00164 };
00165
00167 typedef BaseIntersectionIterator
00168 <const AirFrameMatrix,
00169 AirFrameMatrix::const_iterator,
00170 AirFrameTimeList::const_iterator> ConstIntersectionIterator;
00171
00177 class IntersectionIterator:
00178 public BaseIntersectionIterator<AirFrameMatrix,
00179 AirFrameMatrix::iterator,
00180 AirFrameTimeList::iterator>
00181 {
00182 private:
00184 typedef BaseIntersectionIterator<AirFrameMatrix,
00185 AirFrameMatrix::iterator,
00186 AirFrameTimeList::iterator> Base;
00187 public:
00192 IntersectionIterator(AirFrameMatrix* airFrames,
00193 simtime_t from,
00194 simtime_t to) :
00195 Base(airFrames, from, to)
00196 {}
00197
00205 void eraseAirFrame()
00206 {
00207 assert(endIt != intervals->end());
00208 assert(startIt != endIt->second.end());
00209
00210
00211 startIt = endIt->second.erase(startIt);
00212
00213
00214 if(startIt == endIt->second.end())
00215 {
00216
00217 if(endIt->second.empty()) {
00218 intervals->erase(endIt++);
00219 } else {
00220 endIt++;
00221 }
00222
00223
00224 if(endIt != intervals->end()) {
00225 startIt = endIt->second.begin();
00226 }
00227 }
00228 alreadyNext = true;
00229 }
00230 };
00231
00237 AirFrameMatrix activeAirFrames;
00238
00245 AirFrameMatrix inactiveAirFrames;
00246
00248 typedef std::map<AirFrame*, simtime_t> AirFrameStartMap;
00249
00251 AirFrameStartMap airFrameStarts;
00252
00255 simtime_t earliestInfoPoint;
00256
00259 simtime_t recordStartTime;
00260
00261 public:
00267 typedef std::list<AirFrame*> AirFrameVector;
00268
00269 protected:
00274 void assertNoIntersections();
00275
00276
00284 void getIntersections( const AirFrameMatrix& airFrames,
00285 simtime_t from, simtime_t to,
00286 AirFrameVector& outVector) const;
00287
00292 bool isIntersecting( const AirFrameMatrix& airFrames,
00293 simtime_t from, simtime_t to) const;
00294
00304 void addToInactives(AirFrame* a, simtime_t startTime, simtime_t endTime);
00305
00309 void deleteAirFrame(AirFrameMatrix& airFrames,
00310 AirFrame* a,
00311 simtime_t startTime, simtime_t endTime);
00312
00316 simtime_t findEarliestInfoPoint();
00317
00328 void checkAndCleanInterval(simtime_t startTime, simtime_t endTime);
00329
00342 bool canDiscardInterval(simtime_t startTime, simtime_t endTime);
00343
00350 void checkAndCleanFrom(simtime_t start) {
00351
00352 if(inactiveAirFrames.empty())
00353 return;
00354
00355
00356 checkAndCleanInterval(start, inactiveAirFrames.rbegin()->first);
00357 }
00358
00359 public:
00360 ChannelInfo():
00361 earliestInfoPoint(-1),
00362 recordStartTime(-1)
00363 {}
00364
00365 virtual ~ChannelInfo() {}
00366
00375 void addAirFrame(AirFrame* a, simtime_t startTime);
00376
00385 simtime_t removeAirFrame(AirFrame* a);
00386
00397 void getAirFrames(simtime_t from, simtime_t to, AirFrameVector& out) const;
00398
00403 simtime_t getEarliestInfoPoint()
00404 {
00405 assert(!isChannelEmpty() || earliestInfoPoint == -1);
00406
00407 return earliestInfoPoint;
00408 }
00409
00424 void startRecording(simtime_t start)
00425 {
00426
00427 if(recordStartTime > -1) {
00428 recordStartTime = start;
00429 checkAndCleanInterval(0, recordStartTime);
00430 } else {
00431 recordStartTime = start;
00432 }
00433 }
00434
00441 void stopRecording()
00442 {
00443 if(recordStartTime > -1) {
00444 simtime_t old = recordStartTime;
00445 recordStartTime = -1;
00446 checkAndCleanFrom(old);
00447 }
00448 }
00449
00454 bool isRecording() const
00455 {
00456 return recordStartTime > -1;
00457 }
00458
00463 bool isChannelEmpty() const {
00464 assert(recordStartTime != -1
00465 || activeAirFrames.empty() == airFrameStarts.empty());
00466
00467 return airFrameStarts.empty();
00468 }
00469 };
00470
00471 #endif