ChannelInfo.cc

00001 #include "ChannelInfo.h"
00002 
00003 #include <iostream>
00004 #include <assert.h>
00005 
00006 void ChannelInfo::addAirFrame(AirFrame* frame, simtime_t startTime)
00007 {
00008   assert(airFrameStarts.count(frame) == 0);
00009 
00010   //check if we were previously empty
00011   if(isChannelEmpty()) {
00012     //earliest time point is current sim time
00013     earliestInfoPoint = startTime;
00014   }
00015 
00016   //calculate endTime of AirFrame
00017   simtime_t endTime = startTime + frame->getDuration();
00018 
00019   //add AirFrame to active AirFrames
00020   activeAirFrames[endTime].push_back(AirFrameTimePair(startTime, frame));
00021 
00022   //add to start time map
00023   airFrameStarts[frame] = startTime;
00024 
00025   assert(!isChannelEmpty());
00026 }
00027 
00028 simtime_t ChannelInfo::findEarliestInfoPoint()
00029 {
00030   //TODO: check for a more efficient way to find out that earliest time-point
00031 
00032   // make a variable for the earliest-start-time of all remaining AirFrames
00033   simtime_t earliestStart = 0;
00034   AirFrameStartMap::const_iterator it = airFrameStarts.begin();
00035 
00036   // if there is an entry for an AirFrame
00037   if (it != airFrameStarts.end())
00038   {
00039     // store the start-time of the first entry as earliestStart so far
00040     earliestStart = (*it).second;
00041 
00042     // go through all other start-time-points
00043     for (; it != airFrameStarts.end(); ++it)
00044     {
00045       // and check if an earlier start-time was found,
00046       // if so, replace earliestStart with it
00047       if( (*it).second < earliestStart )
00048         earliestStart = (*it).second;
00049     }
00050   }
00051 
00052   return earliestStart;
00053 }
00054 
00055 simtime_t ChannelInfo::removeAirFrame(AirFrame* frame)
00056 {
00057   assert(airFrameStarts.count(frame) > 0);
00058 
00059   //get start of AirFrame
00060   simtime_t startTime = airFrameStarts[frame];
00061 
00062   //calculate end time
00063   simtime_t endTime = startTime + frame->getDuration();
00064 
00065   //remove this AirFrame from active AirFrames
00066   deleteAirFrame(activeAirFrames, frame, startTime, endTime);
00067 
00068   //add to inactive AirFrames
00069   addToInactives(frame, startTime, endTime);
00070 
00071 
00072   // Now check, whether the earliest time-point we need to store information
00073   // for might have moved on in time, since an AirFrame has been deleted.
00074   if(isChannelEmpty()) {
00075     earliestInfoPoint = -1;
00076   } else {
00077     earliestInfoPoint = findEarliestInfoPoint();
00078   }
00079 
00080   return earliestInfoPoint;
00081 }
00082 
00083 void ChannelInfo::assertNoIntersections() {
00084   for(AirFrameMatrix::iterator it1 = inactiveAirFrames.begin();
00085     it1 != inactiveAirFrames.end(); ++it1)
00086   {
00087     simtime_t e0 = it1->first;
00088     for(AirFrameTimeList::iterator it2 = it1->second.begin();
00089       it2 != it1->second.end(); ++it2)
00090     {
00091       simtime_t s0 = it2->first;
00092 
00093       bool intersects = (recordStartTime > -1 && recordStartTime <= e0);
00094 
00095       for(AirFrameMatrix::iterator it3 = activeAirFrames.begin();
00096         it3 != activeAirFrames.end() && !intersects; ++it3)
00097       {
00098         simtime_t e1 = it3->first;
00099         for(AirFrameTimeList::iterator it4 = it3->second.begin();
00100           it4 != it3->second.end() && !intersects; ++it4)
00101         {
00102           simtime_t s1 = it4->first;
00103 
00104           if(e0 >= s1 && s0 <= e1)
00105             intersects = true;
00106         }
00107       }
00108       assert(intersects);
00109     }
00110   }
00111 }
00112 
00113 void ChannelInfo::deleteAirFrame(AirFrameMatrix& airFrames,
00114                  AirFrame* frame,
00115                  simtime_t startTime, simtime_t endTime)
00116 {
00117   AirFrameMatrix::iterator listIt = airFrames.find(endTime);
00118   AirFrameTimeList* list = &listIt->second;
00119 
00120   for(AirFrameTimeList::iterator it = list->begin();
00121     it != list->end(); it++)
00122   {
00123     if(it->second == frame)
00124     {
00125       it = list->erase(it);
00126       if(list->empty()) {
00127         airFrames.erase(listIt);
00128       }
00129       return;
00130     }
00131   }
00132 
00133   assert(false);
00134 }
00135 
00136 bool ChannelInfo::canDiscardInterval(simtime_t startTime,
00137                    simtime_t endTime)
00138 {
00139   assert(recordStartTime >= 0 || recordStartTime == -1);
00140 
00141   // only if it ends before the point in time we started recording or if
00142   // we aren't recording at all and it does not intersect with any active one
00143   // anymore this AirFrame can be deleted
00144   return (recordStartTime > endTime || recordStartTime == -1)
00145        && !isIntersecting(activeAirFrames, startTime, endTime);
00146 }
00147 
00148 void ChannelInfo::checkAndCleanInterval(simtime_t startTime,
00149                      simtime_t endTime)
00150 {
00151 
00152 
00153   // get through inactive AirFrame which intersected with the passed interval
00154   IntersectionIterator inactiveIntersectIt(&inactiveAirFrames,
00155                        startTime,
00156                        endTime);
00157 
00158   AirFrame* inactiveIntersect = inactiveIntersectIt.next();
00159   while(inactiveIntersect != 0)
00160   {
00161     simtime_t currentStart = airFrameStarts[inactiveIntersect];
00162     simtime_t currentEnd = currentStart + inactiveIntersect->getDuration();
00163 
00164     if(canDiscardInterval(currentStart, currentEnd))
00165     {
00166       inactiveIntersectIt.eraseAirFrame();
00167 
00168       airFrameStarts.erase(inactiveIntersect);
00169 
00170       delete inactiveIntersect;
00171       inactiveIntersect = 0;
00172     }
00173     inactiveIntersect = inactiveIntersectIt.next();
00174   }
00175 }
00176 
00177 void ChannelInfo::addToInactives(AirFrame* frame,
00178                  simtime_t startTime,
00179                  simtime_t endTime)
00180 {
00181   // At first, check if some inactive AirFrames can be removed because the
00182   // AirFrame to in-activate was the last one they intersected with.
00183   checkAndCleanInterval(startTime, endTime);
00184 
00185   if(!canDiscardInterval(startTime, endTime))
00186   {
00187     inactiveAirFrames[endTime].push_back(AirFrameTimePair(startTime, frame));
00188   }
00189   else
00190   {
00191     airFrameStarts.erase(frame);
00192 
00193     delete frame;
00194   }
00195 }
00196 
00197 bool ChannelInfo::isIntersecting(const AirFrameMatrix& airFrames,
00198                  simtime_t from, simtime_t to) const
00199 {
00200   ConstIntersectionIterator it(&airFrames, from, to);
00201   return (it.next() != 0);
00202 }
00203 
00204 void ChannelInfo::getIntersections( const AirFrameMatrix& airFrames,
00205                   simtime_t from, simtime_t to,
00206                   AirFrameVector& outVector) const
00207 {
00208   ConstIntersectionIterator it(&airFrames, from, to);
00209 
00210   AirFrame* intersect = it.next();
00211   while(intersect != 0)
00212   {
00213     outVector.push_back(intersect);
00214     intersect = it.next();
00215   }
00216 }
00217 
00218 void ChannelInfo::getAirFrames(simtime_t from, simtime_t to,
00219                  AirFrameVector& out) const
00220 {
00221   //check for intersecting inactive AirFrames
00222   getIntersections(inactiveAirFrames, from, to, out);
00223 
00224   //check for intersecting active AirFrames
00225   getIntersections(activeAirFrames, from, to, out);
00226 }
00227 
00228