gridkeeper.cc

Go to the documentation of this file.
00001 /*
00002  * An optimizer for some wireless simulations
00003  *
00004  * Helps most when some nodes are mostly stationary.
00005  * We hope you can share your experience with the gridkeeper with us.
00006  *
00007  * Ported from Sun's mobility code
00008  */
00009 
00010 #include "gridkeeper.h"
00011 
00012 static double d2(double x1, double x2, double y1, double y2)
00013 {
00014   return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
00015 }
00016 
00017 GridHandler::GridHandler()
00018 {
00019 }
00020 
00021 void GridHandler::handle(Event *e)
00022 {
00023   MoveEvent *me = (MoveEvent *)e;
00024   MobileNode **pptr;
00025   MobileNode * token_ = me->token_;
00026 
00027   if ((pptr = me->leave_)) {
00028     while (*pptr) {
00029       if ((*pptr)->address() == token_->address()) break;
00030       pptr = &((*pptr)->next());
00031     }
00032     if (!(*pptr)) abort();
00033     else {
00034       *pptr = token_->next();
00035       token_->next() = 0;
00036     }
00037     
00038   }
00039   if ((pptr = me->enter_)) {
00040     if (token_->next()) abort();  // can't be in more than one grid
00041     token_->next() = *pptr;
00042     *pptr = token_;
00043   }
00044   delete me;
00045 
00046   // dump info in the gridkeeper for debug only
00047   // dump();
00048 
00049 }
00050 
00051 GridKeeper* GridKeeper::instance_; 
00052 
00053 static class GridKeeperClass : public TclClass {
00054 public:
00055   GridKeeperClass() : TclClass("GridKeeper") {}
00056   TclObject* create(int, const char*const*) {
00057       return (new GridKeeper);
00058   }
00059 } class_grid_keeper;
00060 
00061 GridKeeper::GridKeeper() : size_(0),grid_(NULL), dim_x_(0), dim_y_(0)
00062 {
00063   gh_ = new GridHandler();
00064 }
00065 
00066 GridKeeper::~GridKeeper()
00067 {
00068   int i;
00069   for (i = 0; i <= dim_x_; i++) {
00070     delete [] grid_[i];
00071   }
00072   delete [] grid_;
00073 }
00074 
00075 int GridKeeper::command(int argc, const char*const* argv)
00076 {
00077   int i, grid_x, grid_y;
00078   Tcl& tcl = Tcl::instance();
00079   MobileNode *mn;
00080 
00081   if (argc == 2) {
00082     if (strcmp(argv[1], "dump") == 0) {
00083       dump();
00084       return (TCL_OK);
00085     }
00086   }
00087 
00088   if (argc == 3) {
00089     if (strcmp(argv[1], "addnode") == 0) {
00090     mn = (MobileNode *)TclObject::lookup(argv[2]);
00091     grid_x = aligngrid((int)mn->X(), dim_x_);
00092         grid_y = aligngrid((int)mn->Y(), dim_y_);
00093     mn->next() = grid_[grid_x][grid_y];
00094     grid_[grid_x][grid_y] = mn;
00095     size_++;
00096         return (TCL_OK);
00097     }
00098   }
00099   if (argc == 4 && strcmp(argv[1], "dimension") == 0) {
00100     if (instance_ == 0) instance_ = this;
00101 
00102     dim_x_ = strtol(argv[2], (char**)0, 0);
00103     dim_y_ = strtol(argv[3], (char**)0, 0);
00104 
00105     if (dim_x_ <= 0 || dim_y_ <= 0) {
00106       tcl.result("illegal grid dimension");
00107       return (TCL_ERROR);
00108     }
00109 
00110     grid_ = new MobileNode **[dim_x_];
00111     for (i = 0; i < dim_x_; i++) {
00112       grid_[i] = new MobileNode *[dim_y_];
00113       bzero((void *)grid_[i], sizeof(MobileNode *)*dim_y_);
00114     }
00115     return (TCL_OK);
00116   }
00117   return (TclObject::command(argc, argv));
00118 }
00119 
00120 void GridKeeper::new_moves(MobileNode *mn)
00121 {
00122   double x = mn->X(), y = mn->Y(); 
00123   double ss = mn->speed();
00124   double vx = (mn->dX())*ss, vy = (mn->dY())*ss;
00125 
00126   double endx, endy, pother, tm;
00127   int i, j, endi, gother, grid_x, grid_y;
00128   MoveEvent *me;
00129 
00130   Scheduler& s = Scheduler::instance();
00131 
00132   endx = mn->destX();
00133   endy = mn->destY();
00134 
00135   if (vx > 0) {
00136     endi = MIN(dim_x_-1, (int)endx);
00137     for (i = (int)x+1; i <= endi; i++) {
00138       tm = (i-x)/vx;
00139       pother = vy*tm + y;
00140       j = (int)pother;
00141       me = new MoveEvent;
00142       if (j == pother && j != 0 && j != dim_y_) {
00143     if (vy > 0) gother = j - 1;
00144     else if (vy < 0) gother = j + 1;
00145     else gother = j;
00146       }
00147       else {
00148     gother = j;
00149       }
00150       me->leave_ = &(grid_[aligngrid(i-1, dim_x_)][aligngrid(gother, dim_y_)]);
00151 
00152       me->grid_x_ = grid_x = aligngrid(i, dim_x_);
00153       me->grid_y_ = grid_y = aligngrid(j, dim_y_);
00154       me->enter_ = &(grid_[grid_x][grid_y]);
00155       me->token_ = mn;
00156       s.schedule(gh_, me, tm);
00157     }
00158   }
00159   else if (vx < 0) {
00160     endi = (int)endx;
00161     for (i = (int)x; i > endi; i--) {
00162       if (i == dim_x_) continue;
00163       tm = (i-x)/vx;
00164       pother = vy*tm + y;
00165       j = (int)pother;
00166       me = new MoveEvent;
00167       if (j == pother && j != 0 && j != dim_y_) {
00168     if (vy > 0) gother = j - 1;
00169     else if (vy < 0) gother = j + 1;
00170     else gother = j;
00171       }
00172       else {
00173     gother = j;
00174       }
00175       me->leave_ = &grid_[aligngrid(i, dim_x_)][aligngrid(gother, dim_y_)];
00176 
00177       me->grid_x_ = grid_x = aligngrid(i-1, dim_x_);
00178       me->grid_y_ = grid_y = aligngrid(j, dim_y_);
00179       me->enter_ = &grid_[grid_x][grid_y];
00180       me->token_ = mn;
00181       s.schedule(gh_, me, tm);
00182     }
00183   }
00184   if (vy > 0) {
00185     endi = MIN(dim_y_-1, (int)endy);
00186     for (j = (int)y+1; j <= endi; j++) {
00187       tm = (j-y)/vy;
00188       pother = vx*tm + x;
00189       i = (int)pother;
00190       me = new MoveEvent;
00191       if (i == pother && i != 0 && i != dim_x_ && vx != 0) continue;
00192       me->leave_ = &grid_[aligngrid(i, dim_x_)][aligngrid(j-1, dim_y_)];
00193 
00194       me->grid_x_ = grid_x = aligngrid(i, dim_x_);
00195       me->grid_y_ = grid_y = aligngrid(j, dim_y_);
00196       me->enter_ = &grid_[grid_x][grid_y];
00197       me->token_ = mn;
00198 
00199       s.schedule(gh_, me, tm);
00200     }
00201   }
00202   else if (vy < 0) {
00203     endi = (int)endy;
00204     for (j = (int)y; j > endi; j--) {
00205       if (j == dim_y_) continue;
00206       tm = (j-y)/vy;
00207       pother = vx*tm + x;
00208       i = (int)pother;
00209       me = new MoveEvent;
00210       if (i == pother && i != 0 && i != dim_x_ && vx != 0) continue;
00211       me->leave_ = &grid_[aligngrid(i, dim_x_)][aligngrid(j, dim_y_)];
00212 
00213       me->grid_x_ = grid_x = aligngrid(i, dim_x_);
00214       me->grid_y_ = grid_y = aligngrid(j-1, dim_y_);
00215       me->enter_ = &grid_[grid_x][grid_y];
00216       me->token_ = mn;
00217       s.schedule(gh_, me, tm);
00218     }
00219   }
00220 
00221 }
00222 
00223 int GridKeeper::get_neighbors(MobileNode* mn, MobileNode **output)
00224 {
00225   int grid_x, grid_y, index = 0, i, j, ulx, uly, lly, adj;
00226   MobileNode *pgd;
00227   double mnx, mny, mnr, sqmnr;
00228   
00229   mn->update_position();
00230   mnx = mn->X();
00231   mny = mn->Y();
00232 
00233   grid_x = aligngrid((int)mn->X(), dim_x_);
00234   grid_y = aligngrid((int)mn->Y(), dim_y_);
00235 
00236   mnr = mn->radius();
00237   sqmnr = mnr * mnr;
00238 
00239   adj = (int)ceil(mnr);
00240 
00241   ulx = MIN(dim_x_-1, grid_x + adj);
00242   uly = MIN(dim_y_-1, grid_y + adj);
00243   lly = MAX(0, grid_y - adj);
00244 
00245   for (i = MAX(0, grid_x - adj); i <= ulx; i++) {
00246     for (j = lly; j <= uly; j++) {
00247       for (pgd = grid_[i][j]; pgd != 0; pgd = pgd->next()) {
00248     if (mn->address() == pgd->address()) 
00249         continue;
00250     pgd->update_position();
00251     if (d2(pgd->X(), mnx, pgd->Y(), mny) < sqmnr)
00252      output[index++] = pgd;
00253       }
00254     }
00255   }
00256 
00257   return index;
00258 }
00259 
00260 void GridKeeper::dump()
00261 {
00262     int i,j;
00263     MobileNode *pgd;
00264 
00265     for (i = 0; i< dim_x_; i++) {
00266       for (j = 0; j < dim_y_; j++) {
00267     if (grid_[i][j] == 0) continue;
00268     printf("grid[%d][%d]: ",i,j);
00269     for (pgd = grid_[i][j]; pgd != 0; pgd = pgd->next()) {
00270       printf("%d ",pgd->address());
00271     }
00272     printf("\n");
00273       }
00274     }
00275     printf("-------------------------------\n");
00276 
00277 }
00278 
00279 

Generated on Tue Mar 6 16:47:45 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6