User Manual, Developers Guide and API Documentation

BestChannel.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2009
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/scheduler/strategy/dsastrategy/BestChannel.hpp>
00029 #include <WNS/scheduler/strategy/dsastrategy/DSAStrategyInterface.hpp>
00030 #include <WNS/scheduler/SchedulerTypes.hpp>
00031 #include <vector>
00032 #include <iostream>
00033 #include <algorithm>
00034 
00035 using namespace wns::scheduler;
00036 using namespace wns::scheduler::strategy;
00037 using namespace wns::scheduler::strategy::dsastrategy;
00038 
00039 STATIC_FACTORY_REGISTER_WITH_CREATOR(BestChannel,
00040                                      DSAStrategyInterface,
00041                                      "BestChannel",
00042                                      wns::PyConfigViewCreator);
00043 
00044 BestChannel::BestChannel(const wns::pyconfig::View& config)
00045     : DSAStrategy(config)
00046 {
00047     //useRandomChannelAtBeginning =
00048     //config.get<bool>("useRandomChannelAtBeginning");
00049 }
00050 
00051 BestChannel::~BestChannel()
00052 {
00053 }
00054 
00055 // call this before each timeSlot/frame
00056 void
00057 BestChannel::initialize(SchedulerStatePtr schedulerState,
00058                         SchedulingMapPtr schedulingMap)
00059 {
00060     DSAStrategy::initialize(schedulerState,schedulingMap); // must always initialize base class too
00061     if (!userInfoMap.empty())
00062     {
00063         userInfoMap.clear();
00064     }
00065     // just a SmartPtr:
00066     //ChannelQualitiesOfAllUsersPtr
00067     assure(schedulerState->currentState!=RevolvingStatePtr(),"currentState must be valid");
00068     // set member:
00069     channelQualitiesOfAllUsers =
00070         schedulerState->currentState->channelQualitiesOfAllUsers;
00071 
00072 }
00073 
00074 DSAResult
00075 BestChannel::getSubChannelWithDSA(RequestForResource& request,
00076                                   SchedulerStatePtr schedulerState,
00077                                   SchedulingMapPtr schedulingMap)
00078 {
00079     DSAResult dsaResult;
00080     UserID user = request.user;
00081     if (userInfoMap.find(user) == userInfoMap.end()) {
00082         userInfoMap.insert(UserInfoMap::value_type(user, UserInfo(schedulerState->currentState->strategyInput->fChannels)));
00083     }
00084     UserInfo& userInfo = userInfoMap.find(user)->second;
00085 
00086     int lastUsedSubChannel = userInfo.lastUsedSubChannel;
00087     int subChannel = lastUsedSubChannel;
00088     int maxSubChannel = schedulingMap->subChannels.size();
00089     int maxTimeSlots = schedulerState->currentState->strategyInput->getNumberOfTimeSlots();
00090     int lastUsedTimeSlot = userInfo.lastUsedTimeSlot;
00091     int timeSlot = lastUsedTimeSlot;
00092 
00093     assure(maxSubChannel==schedulerState->currentState->strategyInput->fChannels,"maxSubChannel="<<maxSubChannel<<"!=fChannels");
00094     ChannelQualitiesOnAllSubBandsPtr channelQualitiesOnAllSubBands = userInfo.channelQualitiesOnAllSubBands;
00095     if (channelQualitiesOnAllSubBands==ChannelQualitiesOnAllSubBandsPtr()) { // empty
00096         assure(channelQualitiesOfAllUsers->knowsUser(user),"channelQualitiesOfAllUsers["<<user.getName()<<"] invalid");
00097         // ^ or should we ask the registryProxy for CQI here?
00098         channelQualitiesOnAllSubBands = channelQualitiesOfAllUsers->find(user)->second;
00099         userInfo.channelQualitiesOnAllSubBands = channelQualitiesOnAllSubBands;
00100     }
00101     MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA("<<request.toString()<<"): lastSC="<<lastUsedSubChannel);
00102     // does this change the schedulerState->currentState->channelQualitiesOfAllUsers ?
00103     // sort takes O(N*log(N)) and stable_sort takes O(N*log(N)^2).
00104     // so why? If linear search is faster: O(N)
00105     //std::stable_sort(schedulingPar.channelQualities.begin(), schedulingPar.channelQualities.end(),
00106     //wns::scheduler::strategy::betterChannelQuality());
00107 
00108     int spatialLayer=0;
00109     bool found  = false;
00110     bool giveUp = false;
00111     if (!schedulerState->isTx
00112         && adjacentSubchannelsOnUplink
00113         && (lastUsedSubChannel!=DSAsubChannelNotFound) // already used subChannel
00114         )
00115     { // UL SC-FDMA
00116         // adjacentSubchannelsOnUplink
00117         while(!found && !giveUp)
00118         {
00119             // try same old subChannel again:
00120             subChannel = lastUsedSubChannel;
00121             if (!userInfo.usedSubChannels[subChannel]
00122                 && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
00123             { // PDU fits in
00124                 found=true; break;
00125             } else { // mark unusable
00126                 userInfo.usedSubChannels[subChannel] = true;
00127             }
00128             // TODO: consider timeSlots !!!
00129 
00130             // try +/-1 +/-2 and so on
00131             for (int tryThisSubChannelOffset=0; tryThisSubChannelOffset<maxSubChannel/2; tryThisSubChannelOffset++)
00132             {
00133                 subChannel = (lastUsedSubChannel + tryThisSubChannelOffset*userInfo.toggleOffset);
00134                 if ((subChannel>=0) && !userInfo.usedSubChannels[subChannel]
00135                     && (subChannel<maxSubChannel)
00136                     && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
00137                 { // PDU fits in
00138                     found=true; break;
00139                 } else { // mark unusable
00140                     userInfo.usedSubChannels[subChannel] = true;
00141                 }
00142                 subChannel = (lastUsedSubChannel - tryThisSubChannelOffset*userInfo.toggleOffset);
00143                 if ((subChannel>=0) && !userInfo.usedSubChannels[subChannel]
00144                     && (subChannel<maxSubChannel)
00145                     && channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
00146                 { // PDU fits in
00147                     found=true; break;
00148                 } else { // mark unusable
00149                     userInfo.usedSubChannels[subChannel] = true;
00150                 }
00151             } // for offset +/-
00152             // the resulting DSA may not be contiguous in the case of another small-band user nearby
00153         } // while
00154         userInfo.toggleOffset *= -1;
00155     } else { // free search
00156         BetterChannelQuality comparator; // from SchedulerTypes.hpp
00157         // O(N^2) operations:
00158         while(!found && !giveUp)
00159         {
00160             subChannel = DSAsubChannelNotFound;
00161             ChannelQualityOnOneSubChannel bestChannelQuality;
00162             // find best of the remaining subChannels:
00163             for (int tryThisSubChannel=0; tryThisSubChannel<maxSubChannel; tryThisSubChannel++)
00164             {
00165                 for (int tryThisTimeSlot=0; tryThisTimeSlot<maxTimeSlots; tryThisTimeSlot++)
00166                 {
00167                     // TODO: userInfo.usedSubChannels[tryThisSubChannel][tryThisTimeSlot]
00168                     if (!userInfo.usedSubChannels[tryThisSubChannel]) { // could be free (at least not checked before)
00169                         ChannelQualityOnOneSubChannel channelQuality
00170                             = (*channelQualitiesOnAllSubBands)[tryThisSubChannel];
00171                         if (comparator(channelQuality, bestChannelQuality)) {
00172                             bestChannelQuality = channelQuality;
00173                             subChannel = tryThisSubChannel;
00174                             timeSlot = tryThisTimeSlot;
00175                         }
00176                     } // if unused
00177                 } // forall tryThisTimeSlot
00178             } // forall tryThisSubChannel
00179             if (subChannel==DSAsubChannelNotFound)
00180             { // one complete round already done
00181                 giveUp=true; break;
00182             }
00183             // best subChannel found; now check if usable:
00184             if (channelIsUsable(subChannel, timeSlot, request, schedulerState, schedulingMap))
00185             { // PDU fits in
00186                 found=true; break;
00187             } else { // mark unusable
00188                 userInfo.usedSubChannels[subChannel] = true;
00189             }
00190         } // while
00191     } // if free search or linear (SC-FDMA)
00192 
00193     if (giveUp) {
00194         MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA(): no free subchannel");
00195         return dsaResult; // empty with subChannel=DSAsubChannelNotFound
00196     } else {
00197         MESSAGE_SINGLE(NORMAL, logger, "getSubChannelWithDSA(): subChannel="<<subChannel);
00198         spatialLayer = getSpatialLayerForSubChannel(subChannel, timeSlot, request, schedulerState, schedulingMap);
00199         userInfo.lastUsedSubChannel = subChannel;
00200         dsaResult.subChannel = subChannel;
00201         dsaResult.spatialLayer = spatialLayer;
00202         return dsaResult;
00203     }
00204     return dsaResult; // empty with subChannel=DSAsubChannelNotFound
00205 }
00206 

Generated on Mon May 21 03:31:56 2012 for openWNS by  doxygen 1.5.5