Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

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   sqmnr = (mnr = mn->radius())*mnr;
00237 
00238   adj = (int)ceil(mnr);
00239 
00240   ulx = min(dim_x_-1, grid_x + adj);
00241   uly = min(dim_y_-1, grid_y + adj);
00242   lly = max(0, grid_y - adj);
00243 
00244   for (i = max(0, grid_x - adj); i <= ulx; i++) {
00245     for (j = lly; j <= uly; j++) {
00246       for (pgd = grid_[i][j]; pgd != 0; pgd = pgd->next()) {
00247         if (mn->address() == pgd->address()) 
00248                 continue;
00249         pgd->update_position();
00250         if (d2(pgd->X(), mnx, pgd->Y(), mny) < sqmnr)
00251          output[index++] = pgd;
00252       }
00253     }
00254   }
00255 
00256   return index;
00257 }
00258 
00259 void GridKeeper::dump()
00260 {
00261     int i,j;
00262     MobileNode *pgd;
00263 
00264     for (i = 0; i< dim_x_; i++) {
00265       for (j = 0; j < dim_y_; j++) {
00266         if (grid_[i][j] == 0) continue;
00267         printf("grid[%d][%d]: ",i,j);
00268         for (pgd = grid_[i][j]; pgd != 0; pgd = pgd->next()) {
00269           printf("%d ",pgd->address());
00270         }
00271         printf("\n");
00272       }
00273     }
00274     printf("-------------------------------\n");
00275 
00276 }
00277 
00278 

Generated on Tue Apr 20 12:14:19 2004 for NS2.26SourcesOriginal by doxygen 1.3.3