Nps.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2009 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00024 #include <GlobalNodeList.h>
00025 #include <PeerInfo.h>
00026 #include <RpcMacros.h>
00027 #include <NeighborCache.h>
00028 #include <GlobalNodeListAccess.h>
00029 #include <Landmark.h>
00030 #include <UnderlayConfigurator.h>
00031 #include <SimpleNodeEntry.h>
00032 #include <SimpleInfo.h>
00033 #include <CoordBasedRoutingAccess.h>
00034 #include <GlobalStatistics.h>
00035 
00036 #include <Nps_m.h>
00037 
00038 #include <Nps.h>
00039 
00040 
00041 void Nps::initNps(NeighborCache* neighborCache)
00042 {
00043     this->neighborCache = neighborCache;
00044 
00045     npsMaxLayer = neighborCache->par("npsMaxLayer");
00046     npsDimensions = neighborCache->par("npsDimensions");
00047     landmarkTimeout = neighborCache->par("landmarkTimeout");
00048 
00049     ownLayer = -1;
00050 
00051     receivedCalls = 0;
00052     pendingRequests = 0;
00053     coordCalcRuns = neighborCache->par("npsCoordCalcRuns");
00054 
00055     WATCH(ownLayer);
00056     WATCH_VECTOR(ownCoordinates);
00057     WATCH_VECTOR(landmarkSet);
00058 
00059     coordBasedRouting = CoordBasedRoutingAccess().get();
00060     globalNodeList = GlobalNodeListAccess().get();
00061 
00062     if (neighborCache->getParentModule()->getModuleByRelativePath("tier1")
00063         ->getModuleByRelativePath("landmark") == NULL) {
00064         landmarkTimer = new cMessage("landmarkTimer");
00065         neighborCache->scheduleAt(simTime() + landmarkTimeout, landmarkTimer);
00066     } else {
00067         // GNP-landmark or NPS-Layer-0-landmark
00068         ownLayer = 0;
00069     }
00070 }
00071 
00072 void Nps::handleTimerEvent(cMessage* msg)
00073 {
00074     // process landmark timer message
00075     if (msg == landmarkTimer) {
00076         if (enoughLandmarks()) {
00077             delete msg;
00078             //std::cout << "[" << getThisNode().getAddress() << "] (Re-)Trying to contact landmarks" << std::endl;
00079             sendCoordRequests();
00080         } else {
00081             neighborCache->scheduleAt(simTime() + landmarkTimeout, msg);
00082         }
00083     }
00084 }
00085 
00086 void Nps::handleRpcResponse(BaseResponseMessage* msg,
00087                             cPolymorphic* context,
00088                             int rpcId, simtime_t rtt)
00089 {
00090     // call rpc stubs
00091     RPC_SWITCH_START( msg );
00092         RPC_ON_RESPONSE( CoordsReq ) {
00093             coordsReqRpcResponse(_CoordsReqResponse, context, rpcId, rtt);
00094         }
00095 #ifdef EXTJOIN_DISCOVERY
00096         RPC_ON_RESPONSE( RttToNode ) {
00097             rttToNodeRpcResponse(_RttToNodeResponse, context, rpcId, rtt);
00098         }
00099 #endif
00100     RPC_SWITCH_END( );
00101 
00102     return;
00103 }
00104 
00105 void Nps::handleRpcTimeout(BaseCallMessage* msg,
00106                            const TransportAddress& dest,
00107                            cPolymorphic* context, int rpcId,
00108                            const OverlayKey& destKey)
00109 {
00110     RPC_SWITCH_START( msg ) {
00111 
00112         RPC_ON_CALL( CoordsReq ) {
00113             if (true/*doingNodeMeasurement()*/) {//TODO
00114 #ifdef EXTJOIN_DISCOVERY
00115                 if (getPendingRttsReq(dest) == -1) {
00116                     RttToNodeCall* call = getNodeMessage(dest);
00117 
00118                     RttToNodeResponse* rttRes = new RttToNodeResponse("RttToNodeXRes");
00119                     rttRes->setPingedNode(dest);
00120                     rttRes->setRttToNode(0);
00121                     std::vector<double> tempOwnCoords;
00122                     tempOwnCoords = getOwnCoordinates();
00123                     rttRes->setOwnCoordinatesArraySize(tempOwnCoords.size());
00124                     for (uint i = 0; i < tempOwnCoords.size(); i++) {
00125                         rttRes->setOwnCoordinates(i, tempOwnCoords[i]);
00126                     }
00127                     sendRpcResponse(call, rttRes);
00128                     deleteNodeMeasurement(dest);
00129                 } else {
00130 #endif
00131                     updateNodeMeasurement(dest, -1);
00132 #ifdef EXTJOIN_DISCOVERY
00133                 }
00134 #endif
00135 
00136             } else {
00137                 pendingRequests--;
00138                 //neighborCache->setNodeTimeout(dest);
00139             }
00140         }
00141 #ifdef EXTJOIN_DISCOVERY
00142         RPC_ON_CALL( RttToNode ) {
00143             updateNodeMeasurement(dest, -1);
00144         }
00145 #endif
00146     }
00147     RPC_SWITCH_END( )
00148 }
00149 
00150 
00151 void Nps::coordsReqRpc(CoordsReqCall* msg)
00152 {
00153     receivedCalls++;
00154     CoordsReqResponse* coordRes = new CoordsReqResponse("CoordsReqRes");
00155     coordRes->setLayer(getOwnLayer());
00156     coordRes->setCoordsArraySize(npsDimensions);
00157 
00158     if (getOwnLayer() != 0) {
00159         const std::vector<double>& ownCoordinates = getOwnCoordinates();
00160 
00161         for (uint i = 0; i < ownCoordinates.size(); i++) {
00162             coordRes->setCoords(i, ownCoordinates[i]);
00163         }
00164     } else {
00165         Landmark* landmark = check_and_cast<Landmark*>(neighborCache->getParentModule()
00166             ->getModuleByRelativePath("tier1.landmark"));
00167         assert(landmark);
00168         const std::vector<double>& ownCoordinates =
00169             landmark->getOwnNpsCoords();
00170 
00171         for (uint i = 0; i < ownCoordinates.size(); i++) {
00172             coordRes->setCoords(i, ownCoordinates[i]);
00173         }
00174     }
00175     coordRes->setBitLength(COORDSREQRESPONSE_L(coordRes));
00176     neighborCache->sendRpcResponse(msg, coordRes);
00177 }
00178 
00179 #ifdef EXTJOIN_DISCOVERY
00180 void Nps::rttToNodeRpc(RttToNodeCall* msg)
00181 {
00182     incReceivedCalls();
00183     TransportAddress dest = msg->getNodeToPing();
00184 //std::cout << "Set Node Message";
00185     setNodeMessage(dest, msg);
00186     sendCoordsReqCall(dest, -1);
00187 }
00188 #endif
00189 
00190 void Nps::coordsReqRpcResponse(CoordsReqResponse* response,
00191                                cPolymorphic* context, int rpcId, simtime_t rtt)
00192 {
00193     pendingRequests--;
00194     NodeHandle& srcNode = response->getSrcNode();
00195     //uint dim = getXmlDimensions();
00196 
00197 //    std::cout << thisNode.getAddress() <<" received something from LM (" << srcNode.getAddress() << ")! RTT: " << rtt << " Layer:" << (int)(response->getLayer()) << " Coords:";
00198 //    for (uint i = 0; i < dim; i++) {
00199 //        std::cout << response->getCoords(i) << ", ";
00200 //    }
00201 //    std::cout << pendingRequests << std::endl;
00202 
00203     std::vector<double> tempCoords;
00204     for (uint i = 0; i < response->getCoordsArraySize(); i++) {
00205         tempCoords.push_back(response->getCoords(i));
00206     }
00207     char tempLayer = response->getLayer();
00208 
00209     EV << "[Nps::coordsReqRpcResponse() @ " << neighborCache->thisNode.getAddress()
00210        << " (" << neighborCache->thisNode.getKey().toString(16) << ")]\n    received landmark coords: "
00211        << tempCoords[0];
00212     for (uint8_t i = 1; i < npsDimensions; i++) {
00213         EV << ", " << tempCoords[i];
00214     }
00215     EV << endl;
00216 
00217 #ifdef EXTJOIN_DISCOVERY
00218     if (doingDiscovery()) {
00219         //if in Discovery insert RTT only if lower then already set RTT
00220         if ((isEntry(srcNode) && rtt < getNodeRtt(srcNode))
00221             || (isEntry(srcNode) && getNodeRtt(srcNode) < 0) ) {
00222             updateNode(srcNode, rtt, tempCoords, 0);
00223         } else if (!(isEntry(srcNode))) {
00224             updateNode(srcNode, rtt, tempCoords, 0);
00225         } else {
00226             updateNode(srcNode, getNodeRtt(srcNode), tempCoords, 0);
00227         }
00228         setNodeLayer(srcNode, tempLayer);
00229     }
00230     else if (doingNodeMeasurement()) {
00231         if (getPendingRttsReq(srcNode) == -1) {
00232             updateNode(srcNode, rtt, tempCoords, 0);
00233             setNodeLayer(srcNode, tempLayer);
00234             RttToNodeCall* prevCall = getNodeMessage(srcNode);
00235 
00236             RttToNodeResponse* rttRes = new RttToNodeResponse("RttToNodeXRes");
00237             rttRes->setPingedNode(srcNode);
00238             rttRes->setRttToNode(rtt);
00239             std::vector<double> tempOwnCoords;
00240             tempOwnCoords = getOwnCoordinates();
00241             rttRes->setOwnCoordinatesArraySize(tempOwnCoords.size());
00242             for (uint i = 0; i < tempOwnCoords.size(); i++) {
00243                 rttRes->setOwnCoordinates(i, tempOwnCoords[i]);
00244             }
00245 
00246             sendRpcResponse(prevCall, rttRes);
00247             deleteNodeMeasurement(srcNode);
00248         } else {
00249             updateNode(srcNode, rtt, tempCoords, 0);
00250             setNodeLayer(srcNode, tempLayer);
00251             if (checkCoordinates(getOwnCoordinates(), tempCoords, rtt)) {
00252                 updateNodeMeasurement(srcNode, -1, 0, 1);
00253             } else {
00254                 updateNodeMeasurement(srcNode, -1, 0, 0);
00255             }
00256         }
00257     }
00258     else
00259 #endif
00260     if (pendingRequests == 0) {
00261         neighborCache->updateNode(srcNode, rtt, NodeHandle::UNSPECIFIED_NODE,
00262                                   tempCoords, 0);     // Ported neighborCache->insertAddressRtt(srcNode, rtt) to new method updateNode()
00263         neighborCache->setNodeLayer(srcNode, tempLayer);  // set layer
00264         /*********** GOT ALL RESPONSES, DO COORD COMPUTATION AND JOIN ***********/
00265 
00266         std::vector<LandmarkDataEntry> setOfLandmarks;
00267         if (getLandmarkSetSize() < npsDimensions + 1) {
00268             neighborCache->setLandmarkSet(npsDimensions + 1,
00269                            npsMaxLayer, &landmarkSet);
00270         }
00271         setOfLandmarks = neighborCache->getLandmarkData(landmarkSet);
00272         assert(setOfLandmarks.size() > 0);
00273 
00274         //showReceivedCoords();
00275 
00276         computeOwnCoordinates(setOfLandmarks);
00277         computeOwnLayer(setOfLandmarks);
00278 
00279         std::vector<double> coords = getOwnCoordinates();
00280         EV << "[Nps::coordsReqRpcResponse() @ " << neighborCache->thisNode.getAddress()
00281            << " (" << neighborCache->thisNode.getKey().toString(16) << ")]\n    setting own coords: "
00282            << coords[0];
00283         for (uint8_t i = 1; i < npsDimensions; i++) {
00284             EV << ", " << coords[i];
00285         }
00286         EV << endl;
00287 
00288 
00289         //test
00290         ChurnGenerator* lmChurnGen = NULL;
00291         for (uint8_t i = 0; i < neighborCache->underlayConfigurator->getChurnGeneratorNum(); i++) {
00292             ChurnGenerator* searchedGen;
00293             searchedGen = neighborCache->underlayConfigurator->getChurnGenerator(i);
00294             if (searchedGen->getNodeType().overlayType != "oversim.common.cbr.LandmarkModules") {
00295                 lmChurnGen = searchedGen;
00296             }
00297         }
00298         SimpleNodeEntry* entry =
00299                 dynamic_cast<SimpleInfo*>(globalNodeList->
00300                                           getPeerInfo(neighborCache->thisNode.getAddress()))->getEntry();
00301 
00302         double error = 0;
00303         //std::cout << fabs(coords[0] - entry->getCoords(0));
00304         for (uint8_t i = 1; i < entry->getDim(); i++) {
00305             //ownCoords.push_back(entry->getCoords(i));
00306             //std::cout << ", " << fabs(coords[i] - entry->getCoords(i));
00307             error += pow(coords[i] - entry->getCoords(i), 2);
00308         }
00309         //std::cout << endl;
00310         error = sqrt(error);
00311 
00312         neighborCache->globalStatistics
00313           ->addStdDev("NPS: Coordinate difference", error);
00314 
00315         neighborCache->neighborCache.clear(); //TODO
00316         neighborCache->neighborCacheExpireMap.clear(); //TODO
00317 
00318         //neighborCache->getParentModule()->bubble("GNP/NSP coordinates calculated -> JOIN overlay!");
00319 
00320         if (coordBasedRouting) {
00321             int bitsPerDigit = neighborCache->overlay->getBitsPerDigit(); //TODO: bitsPerDigit in other protocols than Pastry??
00322             neighborCache->thisNode.setKey(
00323                 coordBasedRouting->getNodeId(coords, bitsPerDigit,
00324                                              OverlayKey::getLength()));
00325 
00326             EV << "[Nps::coordsReqRpcResponse() @ " << neighborCache->thisNode.getAddress()
00327                << " (" << neighborCache->thisNode.getKey().toString(16) << ")]"
00328                << "\n    -> nodeID ( 2): "
00329                << neighborCache->thisNode.getKey().toString(2)
00330                << "\n    -> nodeID (16): "
00331                << neighborCache->thisNode.getKey().toString(16) << endl;
00332 
00333             neighborCache->overlay->join(neighborCache->thisNode.getKey()); // returning to BaseOverlay
00334         } else {
00335             neighborCache->overlay->join(); // returning to BaseOverlay
00336         }
00337     } else {
00338         neighborCache->updateNode(srcNode, rtt, NodeHandle::UNSPECIFIED_NODE,
00339                                   tempCoords, 0);     // Ported neighborCache->insertAddressRtt(srcNode, rtt) to new method updateNode()
00340         neighborCache->setNodeLayer(srcNode, tempLayer);  // set layer
00341     }
00342 }
00343 
00344 #ifdef EXTJOIN_DISCOVERY
00345 void Nps::rttToNodeRpcResponse(RttToNodeResponse* response,
00346                                                cPolymorphic* context, int rpcId, simtime_t rtt)
00347 {
00348     uint dim = coordBasedRouting->getXmlDimensions();
00349     TransportAddress nodeToCheck = response->getPingedNode();
00350     std::vector<double> tempCoords;
00351     tempCoords.resize(dim);
00352     for (uint i = 0; i < dim; i++) {
00353         tempCoords[i] = response->getOwnCoordinates(i);
00354     }
00355     if (checkCoordinates(tempCoords, getNodeCoords(nodeToCheck), response->getRttToNode())) {
00356         updateNodeMeasurement(nodeToCheck, -1, 0, 1);
00357     } else {
00358         updateNodeMeasurement(nodeToCheck, -1, 0, 0);
00359     }
00360     delete context;
00361 }
00362 #endif
00363 
00364 void Nps::sendCoordRequests()
00365 {
00366     std::vector <TransportAddress> landmarks;
00367     landmarks = getLandmarks(npsDimensions + 1);
00368 //    std::cout << "Landmarks given to " << thisNode.getAddress() << ":" << endl;
00369 //    for (uint i = 0; i < landmarks.size(); i++) {
00370 //        std::cout << landmarks[i]->ip << ":" << landmarks[i]->port << endl;
00371 //    }
00372 //    std::cout << "**************************" << endl;
00373 
00374     simtime_t timeout = -1;
00375 
00376     if (landmarks.size() > 0) {
00377         for (size_t i = 0; i < landmarks.size(); i++) {
00378             const TransportAddress& tolm = landmarks[i];
00379             sendCoordsReqCall(tolm, timeout);
00380         }
00381         neighborCache->setLandmarkSet(npsDimensions + 1, npsMaxLayer,
00382                                       &landmarkSet);
00383     }
00384 }
00385 
00386 void Nps::sendCoordsReqCall(const TransportAddress& dest,
00387                             simtime_t timeout)
00388 {
00389     CoordsReqCall* coordReq = new CoordsReqCall("CoordsReq");
00390     coordReq->setBitLength(COORDSREQCALL_L(coordReq));
00391     neighborCache->sendRouteRpcCall(neighborCache->getThisCompType(), dest,
00392                                     coordReq, NULL, NO_OVERLAY_ROUTING,
00393                                     timeout, 0, -1, this);
00394     pendingRequests++;
00395 }
00396 
00397 void Nps::computeOwnLayer(const std::vector<LandmarkDataEntry>& landmarks)
00398 {
00399     int8_t computedLayer = getOwnLayer();
00400     for (uint i = 0; i < landmarks.size(); i++) {
00401         if (computedLayer <= landmarks[i].layer) {
00402             computedLayer = landmarks[i].layer + 1;
00403         }
00404     }
00405 //    std::cout << "Node computed Layer: " << (int) computedLayer << endl;
00406     setOwnLayer(computedLayer);
00407 }
00408 
00409 void Nps::setOwnLayer(int8_t layer)
00410 {
00411     ownLayer = layer;
00412 
00413     // Update in BootstrapOracle
00414     PeerInfo* thisInfo = globalNodeList->getPeerInfo(neighborCache->getThisNode());
00415     thisInfo->setNpsLayer(layer);
00416     if (layer > 0) globalNodeList->refreshEntry(neighborCache->overlay->getThisNode()); // Workaround against -1 ports in BS oracle
00417     if (layer < npsMaxLayer) {
00418         globalNodeList->incLandmarkPeerSize();
00419         globalNodeList->incLandmarkPeerSizePerType(thisInfo->getTypeID());
00420     }
00421 }
00422 
00423 #ifdef EXTJOIN_DISCOVERY
00424 bool Nps::checkCoordinates(std::vector<double> coordsOK, std::vector<double> coordsToCheck, simtime_t dist)
00425 {
00426     simtime_t predDist = 0.0;
00427 
00428     for (uint i = 0; i < coordsOK.size(); i++) {
00429         predDist += pow(coordsOK[i] - coordsToCheck[i], 2);
00430     }
00431     simtime_t predDistLow = sqrt(SIMTIME_DBL(predDist)) * 2 * (1 - /*(coordBasedRouting->getCoordCheckPercentage() / 100)*/0.3) / 1000;
00432     simtime_t predDistHigh = sqrt(SIMTIME_DBL(predDist)) * 2 * (1 + /*(coordBasedRouting->getCoordCheckPercentage() / 100)*/0.3) / 1000;
00433     if (dist > predDistLow && dist < predDistHigh) {
00434         return true;
00435     } else {
00436 //        std::cout << "check of Coordinates Failed! Intervall: [ " << predDistLow << " ; " << predDistHigh << " ] and dist: " << dist << endl;
00437         return false;
00438     }
00439 }
00440 #endif
00441 
00442 void Nps::computeOwnCoordinates(const std::vector<LandmarkDataEntry>& landmarks)
00443 {
00444     CoordCalcFunction coordcalcf(landmarks);
00445 
00446     Vec_DP initCoordinates(npsDimensions);
00447     Vec_DP bestCoordinates(npsDimensions);
00448     std::vector<double> computedCoordinatesStdVector(npsDimensions);
00449 
00450     double bestval;
00451     double resval;
00452 
00453     for (uint runs = 0; runs < coordCalcRuns; runs++) {
00454         // start with random coordinates (-100..100 in each dim)
00455         for (uint i = 0; i < npsDimensions; i++) {
00456             initCoordinates[i] = uniform(-100, 100);
00457             //initCoordinates[i] = (((double)(rand() % 200000)) / 1000);
00458             //initCoordinates[i] -= 100;
00459         }
00460         // compute minimum coordinates via Simplex-Downhill minimum
00461         // function value is returned, coords are written into initCoordinates (call by reference)
00462         resval = CoordCalcFunction::simplex_min(&coordcalcf, initCoordinates);
00463         if (runs == 0 || (runs > 0 && resval < bestval) ) {
00464             bestval = resval;
00465             bestCoordinates = initCoordinates;
00466         }
00467     }
00468 
00469     for (uint i = 0; i < npsDimensions; i++) {
00470         computedCoordinatesStdVector[i] = bestCoordinates[i];
00471     }
00472 
00473     setOwnCoordinates(computedCoordinatesStdVector);
00474 }
00475 
00476 std::vector<TransportAddress> Nps::getLandmarks(uint8_t howmany)
00477 {
00478     std::vector<TransportAddress> returnPool;
00479 
00480     if (howmany > globalNodeList->getLandmarkPeerSize()) {
00481         throw cRuntimeError("Not enough landmarks available in network!");
00482     }
00483 
00484     while (returnPool.size() < howmany) {
00485         TransportAddress* lm = globalNodeList->getRandomAliveNode();
00486         PeerInfo* lmInfo = globalNodeList->getPeerInfo(lm->getAddress());
00487         if (lmInfo->getNpsLayer() >= 0 &&
00488             lmInfo->getNpsLayer() < npsMaxLayer) {
00489             // already in returnPool?
00490             bool alreadyin = false;
00491             for (uint8_t i = 0; i < returnPool.size(); i++) {
00492                 if (returnPool[i] == *lm)
00493                     alreadyin = true;
00494             }
00495             if (alreadyin == false) {
00496                 returnPool.push_back(*lm);
00497             }
00498         }
00499     }
00500     return returnPool;
00501 }
00502 
00503 bool Nps::enoughLandmarks()
00504 {
00505     return (globalNodeList->getLandmarkPeerSize() > npsDimensions);
00506 }
00507 
00508 
00509 Prox Nps::getCoordinateBasedProx(const NodeCoordsInfo& info)
00510 {
00511     double dist = 0.0;
00512     uint32_t size = info.coordinates.size();
00513 
00514     for (uint32_t i = 0; i < size; i++) {
00515         dist += pow(ownCoordinates[i] - info.coordinates[i], 2);
00516     }
00517     dist = sqrt(dist);
00518 
00519     return Prox(dist, 0.0); //TODO accuracy
00520 }
00521 
00522 void Nps::showReceivedCoords()
00523 {
00524     std::cout << neighborCache->thisNode.getAddress() << " is still missing "
00525               << pendingRequests;
00526     std::cout << " responses! Results so far:" << std::endl;
00527     std::vector<LandmarkDataEntry> landmarkData =
00528         neighborCache->getLandmarkData(landmarkSet);
00529     for (uint i = 0; i < landmarkData.size(); i++) {
00530         std::cout << "RTT: " << SIMTIME_DBL(landmarkData[i].rtt)
00531                   << " -- Layer: " << (int) landmarkData[i].layer
00532                   << " -- Coords: ";
00533         for (uint j = 0; j < landmarkData[i].coordinates.size(); j++) {
00534             std::cout << " " << landmarkData[i].coordinates[j];
00535         }
00536         std::cout << " -- IP: " << landmarkData[i].ip;
00537         std::cout << std::endl;
00538     }
00539 }
00540 
00541 void Nps::updateNodeMeasurement(const TransportAddress& node,
00542                                           uint8_t pending,
00543                                           uint8_t sent,
00544                                           uint8_t passed)
00545 {
00546     bool alreadySet = false;
00547     for(uint i = 0; i < nodeMeasurements.size(); i++) {
00548         if (nodeMeasurements[i].measuredNode == node && sent == 0) {
00549             nodeMeasurements[i].rttsPending += pending;
00550             nodeMeasurements[i].rttsSent += sent;
00551             nodeMeasurements[i].coordsPassed += passed;
00552             alreadySet = true;
00553             i = nodeMeasurements.size();
00554         } else if (nodeMeasurements[i].measuredNode == node) {
00555             nodeMeasurements[i].rttsPending = pending;
00556             nodeMeasurements[i].rttsSent = sent;
00557             nodeMeasurements[i].coordsPassed = passed;
00558             alreadySet = true;
00559             i = nodeMeasurements.size();
00560         }
00561     }
00562     if (!alreadySet) {
00563         RttMeasurement newNode;
00564         newNode.measuredNode = node;
00565         newNode.rttsPending = pending;
00566         newNode.rttsSent = sent;
00567         newNode.coordsPassed = passed;
00568         nodeMeasurements.push_back(newNode);
00569     }
00570 }
00571 
00572 void Nps::deleteNodeMeasurement(const TransportAddress& node)
00573 {
00574     for(uint i = 0; i < nodeMeasurements.size(); i++) {
00575         if (nodeMeasurements[i].measuredNode == node) {
00576 #ifdef EXTJOIN_DISCOVERY
00577             delete nodeMeasurements[i].message;
00578 #endif
00579             nodeMeasurements.erase(nodeMeasurements.begin()+i);
00580             i--;
00581         }
00582     }
00583     if (nodeMeasurements.size() == 0) {
00584         //stopNodeMeasurement();
00585     }
00586 }
00587 
00588 
00589 double CoordCalcFunction::simplex_min(CoordCalcFunction *functionObject,
00590                                       Vec_DP& init)
00591 {
00592     double accf = 0.0000001;
00593     double accx = 0.0000001;
00594     uint32_t nmax = 30001;
00595     uint8_t dim = init.size();
00596     Simplex spx(dim);
00597 
00598     int ihi;    // Index of highest point at start of each iteration
00599     Vec_DP phi(dim);   // Highest point at start of each iteration.
00600     double vhi;    // Function value at highest point at start of each iteration.
00601     double vre;    // Function value at reflected point.
00602     double vlo, diff;  // for checking convergence.
00603     uint32_t count;
00604 
00605     // Initialize Simplex
00606     Vec_DP tmp(dim);
00607     spx.functionObject = functionObject;
00608     spx[0] = init;
00609     for (uint8_t i = 0; i < dim; i++) {
00610         tmp[i] = 1;
00611         spx[i+1] = init + tmp;
00612         tmp[i] = 0;
00613     }
00614 
00615     Vec_DP debugCoords(dim);
00616 
00617     for (count = 1; count <= nmax; count++) {
00618         /*
00619         if ((count % 10000) == 0) {
00620             std::cout << "running loop #" << count << " of " << nmax << endl;
00621             std::cout << "diff: " << diff << std::endl;
00622             std::cout << "vhi: " << vhi << std::endl;
00623             std::cout << "vlo: " << vlo << std::endl;
00624             debugCoords = spx[spx.low()];
00625             std::cout << "Coords: " << debugCoords << std::endl;
00626         }
00627         */
00628         ihi = spx.high(&vhi);
00629         phi = spx[ihi];
00630         spx.reflect();
00631         vre = functionObject->f(spx[ihi]);
00632         if (vre < functionObject->f(spx[spx.low()])) {
00633             spx[ihi] = phi;  // Undo reflection.
00634             spx.reflect_exp();
00635             vre = functionObject->f(spx[ihi]);
00636             if (vre > functionObject->f(spx[spx.low()])) {
00637                 spx[ihi] = phi;
00638                 spx.reflect();
00639             }
00640         } else if (vre >= vhi) { // Equal sign important!
00641             spx[ihi] = phi;  // Undo reflection.
00642             spx.contract();
00643             if (functionObject->f(spx[ihi]) > vhi) {
00644                 spx[ihi] = phi; // Undo contraction.
00645                 spx.reduce();
00646             } // else contraction ok.
00647         } // else reflection ok
00648 
00649         spx.high(&vhi);
00650         spx.low(&vlo);
00651         diff = vhi - vlo;
00652         if (diff < accf)
00653             if (spx.size() < accx)
00654                 break;
00655     }
00656     init = spx[spx.low()];
00657     return vlo;
00658 }
00659 
00660 double CoordCalcFunction::f(const Vec_DP& initCoordinates) const
00661 {
00662     double sum = 0;
00663     double rel_diff = 0;
00664 
00665     for (uint i = 0; i < landmarks.size(); i++) {
00666         // Distance = RTT in ms / 2
00667         double diff = SIMTIME_DBL(landmarks[i].rtt) / 2 * 1000 -
00668             endnodeDistance(initCoordinates, landmarks[i]);
00669 
00670         if (SIMTIME_DBL(landmarks[i].rtt) != 0) {
00671             rel_diff = diff / (SIMTIME_DBL(landmarks[i].rtt) / 2 * 1000);
00672         } else {
00673             opp_error("[CBR] RTT == 0. Node is landmark? This shouldn't happen.");
00674         }
00675         sum += rel_diff * rel_diff;
00676     }
00677     return sum;
00678 }
00679 
00680 double CoordCalcFunction::endnodeDistance(const Vec_DP& nodeCoordinates,
00681                                           LandmarkDataEntry landmark) const
00682 {
00683     double sum_of_squares = 0.0;
00684     for (int i = 0; i < nodeCoordinates.size(); i++) {
00685         sum_of_squares += pow(landmark.coordinates[i] - nodeCoordinates[i], 2);
00686     }
00687     double result = sqrt(sum_of_squares);
00688     return result;
00689 }
00690 

Generated on Tue Sep 8 17:26:53 2009 for OverSim by  doxygen 1.5.8