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

tags.cc

Go to the documentation of this file.
00001 // Author: Satish Kumar, kkumar@isi.edu
00002 
00003 
00004 
00005 extern "C" {
00006 #include <stdarg.h>
00007 #include <float.h>
00008 };
00009 
00010 
00011 #include "tags.h"
00012 #include "random.h"
00013 #include <string.h>
00014 
00015 
00016 #define MAX_P1 10
00017 #define MAX_P2 10
00018 
00019 // Split into 10 rectangles at each level. Have two levels for now.
00020 
00021 
00022 static class TagDbaseClass:public TclClass
00023 {
00024   public:
00025   TagDbaseClass ():TclClass ("TagDbase")
00026   {
00027   }
00028   TclObject *create (int, const char *const *)
00029   {
00030     return (new tags_database ());
00031   }
00032 } class_tags_database;
00033 
00034 
00035 
00036 
00037 void tags_database::
00038 trace (char *fmt,...)
00039 {
00040   va_list ap; // Define a variable ap that will refer to each argument in turn
00041 
00042   if (!tracetarget_)
00043     return;
00044 
00045   // Initializes ap to first argument
00046   va_start (ap, fmt); 
00047   // Prints the elements in turn
00048   vsprintf (tracetarget_->buffer (), fmt, ap); 
00049   tracetarget_->dump ();
00050   // Does the necessary clean-up before returning
00051   va_end (ap); 
00052 }
00053 
00054 
00055 
00056 
00057 int 
00058 tags_database::command (int argc, const char *const *argv)
00059 {
00060   if (argc == 7)
00061     {
00062       if (strcmp (argv[1], "create_database") == 0)
00063         {
00064           double x_min = atof(argv[2]);
00065           double x_max = atof(argv[3]);
00066           double y_min = atof(argv[4]);
00067           double y_max = atof(argv[5]);
00068           int num_tags = atoi(argv[6]);
00069           
00070           num_tags_ = num_tags;
00071           sensed_tag_list_ = new int[num_tags];
00072           freq_qry_tag_list_ = new int[num_tags];
00073           create_tags_database(x_min,x_max,y_min,y_max,num_tags);
00074           return (TCL_OK);
00075         }
00076     }
00077   else if (argc == 3)
00078     {
00079       if (strcasecmp (argv[1], "tracetarget") == 0)
00080         {
00081           TclObject *obj;
00082           if ((obj = TclObject::lookup (argv[2])) == 0)
00083             {
00084               fprintf (stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1],
00085                        argv[2]);
00086               return TCL_ERROR;
00087             }
00088           tracetarget_ = (Trace *) obj;
00089           return TCL_OK;
00090         }
00091     }
00092 
00093   return (TclObject::command(argc, argv));
00094 }
00095 
00096 
00097 
00098 
00099 void
00100 tags_database::create_tags_database(double x_min, double x_max, double y_min, double y_max, int num_tags)
00101 {
00102   dbase_node *dbnode;
00103   int i;
00104 
00105   assert((x_min <= x_max) && (y_min <= y_max));  
00106 
00107   // Creating the data structures for storing the tags information
00108   tags_db_ = new dbase_node(x_min, x_max, y_min, y_max);
00109 
00110   // Creates child nodes for tags_db_ and partitions x and y ranges
00111   add_level(x_min, x_max, y_min, y_max, tags_db_);
00112   
00113   // Creates child nodes for each of tags_db_'s children
00114   for(i = 0; i < NUM_RECTANGLES; ++i) {
00115     dbnode = tags_db_->list_node_[i];
00116     assert((dbnode->x_min_ <= dbnode->x_max_) && (dbnode->y_min_ <= dbnode->y_max_));
00117     add_level(dbnode->x_min_, dbnode->x_max_, dbnode->y_min_, dbnode->y_max_, dbnode);
00118   }
00119 
00120   // Creating the tags and adding them to the database
00121   tag *newtag = new tag();
00122   i = 0;
00123   int p1 = 1, p2 = 1, p3 = 1;
00124   int max_p1 = MAX_P1, max_p2 = MAX_P2;
00125   int max_p3 = num_tags/(MAX_P1 * MAX_P2);
00126 
00127   while(i < num_tags) {
00128     newtag->x_ = x_min + rn_->uniform(x_max-x_min);
00129     newtag->y_ = y_min + rn_->uniform(y_max-y_min);
00130     newtag->obj_name_ = (int)((p1 * pow(2,24)) + (p2 * pow(2,16)) + p3) ;
00131     ++p3;
00132 
00133     if(p3 == max_p3) {
00134       p3 = 1;
00135       ++p2;
00136       if(p2 == max_p2) {
00137         p2 = 1;
00138         ++p1;
00139         if(p1 == max_p1) {
00140           break;
00141         }
00142       }
00143     }
00144 
00145     Addtag(newtag);
00146 
00147     //    printf("Added object %d.%d.%d at (%f,%f)\n",(newtag->obj_name_ >> 24) & 0xFF,(newtag->obj_name_ >> 16) & 0xFF,(newtag->obj_name_) & 0xFFFF,newtag->x_,newtag->y_);
00148     ++i;
00149   }
00150   delete newtag;
00151 }
00152 
00153 
00154 
00155 void
00156 tags_database::add_level(double x_min, double x_max, double y_min, double y_max, dbase_node *dbnode)
00157 {
00158   double x1, x2, y1, y2, x_partition_size;
00159   int i;
00160 
00161 // Just partitioning along x-range for now
00162   x_partition_size = (x_max-x_min)/NUM_RECTANGLES;
00163   x2 = x_min;
00164   y1 = y_min;
00165   y2 = y_max;
00166   for(i = 0; i < NUM_RECTANGLES; ++i) {
00167     x1 = x2;                    // x_min for partition
00168     x2 = x1 + x_partition_size; // x_max for partition
00169     
00170     // The last partition should cover the remaining ranges
00171     if (i == (NUM_RECTANGLES - 1)) {
00172       x2 = x_max;
00173     }
00174     dbnode->list_node_[i] = new dbase_node(x1,x2,y1,y2);
00175   }
00176 }
00177 
00178 
00179 
00180 void
00181 tags_database::Addtag(const tag* tag_)
00182 {
00183   dbase_node *dbnode = tags_db_;
00184   int i, found = FALSE;
00185   tag *new_tag;
00186 
00187   while(dbnode->list_node_[0] != NULL) {
00188     for(i = 0; i < NUM_RECTANGLES; ++i) {
00189       if(((dbnode->list_node_[i])->x_min_ <= tag_->x_) && ((dbnode->list_node_[i])->x_max_ >= tag_->x_)) {
00190         found = TRUE;
00191         break;
00192       }
00193     }
00194     assert(found);
00195     dbnode = dbnode->list_node_[i];
00196   }
00197   
00198   if(dbnode->tags_list_ == NULL) {
00199     dbnode->tags_list_ = new tag;
00200     new_tag = dbnode->tags_list_;
00201   }
00202   else {
00203     new_tag = dbnode->tags_list_;
00204     while(new_tag->next_ != NULL) {
00205       new_tag = new_tag->next_;
00206     }
00207     new_tag->next_ = new tag;
00208     new_tag = new_tag->next_;
00209   }
00210 
00211   // tags do not have any attributes for now
00212   new_tag->x_ = tag_->x_;
00213   new_tag->y_ = tag_->y_;
00214   new_tag->obj_name_ = tag_->obj_name_;
00215 }
00216 
00217 
00218 
00219 void
00220 tags_database::Deletetag(const tag *tag_)
00221 {
00222   dbase_node *dbnode = tags_db_;
00223   int i, found = FALSE;
00224   tag *old_tag;
00225 
00226   while(dbnode->list_node_[0] != NULL) {
00227     for(i = 0; i < NUM_RECTANGLES; ++i) {
00228       if(((dbnode->list_node_[i])->x_min_ <= tag_->x_) && ((dbnode->list_node_[i])->x_max_ >= tag_->x_)) {
00229         found = TRUE;
00230         break;
00231       }
00232     }
00233     assert(found);
00234     dbnode = dbnode->list_node_[i];
00235   }
00236   
00237   assert(dbnode->tags_list_ != NULL);
00238 
00239   //old_tag will point to the tag entry that is to be deleted
00240   found = FALSE;
00241   old_tag = dbnode->tags_list_;
00242   tag *prev_tag = old_tag; // Should have previous tag in list
00243   while(old_tag != NULL) {
00244     if ((old_tag->x_== tag_->x_) && (old_tag->y_ == tag_->y_) && (old_tag->obj_name_ == tag_->obj_name_)) {
00245       found = TRUE;
00246       break;
00247     }
00248     prev_tag = old_tag;
00249     old_tag = old_tag->next_;
00250   }
00251   
00252   assert(found);
00253   prev_tag->next_ = old_tag->next_;
00254   delete old_tag;
00255 }
00256 
00257 
00258 
00259 compr_taglist *
00260 tags_database::Gettags(double x, double y, double r)
00261 {
00262   dbase_node *dbnode = tags_db_;
00263   compr_taglist *tptr;
00264   int i, found = FALSE;
00265   vtags_ = NULL;
00266   
00267   // This interior node should have child nodes
00268   //  assert(dbnode->list_node_[0] != NULL);
00269   search_tags_dbase(x,y,r,dbnode);
00270 
00271   tptr = vtags_;
00272   while(tptr) {
00273     found = FALSE;
00274     for(i = 0; i < num_sensed_tags_; ++i) {
00275       if(tptr->obj_name_ == sensed_tag_list_[i]) {
00276         found = TRUE;
00277         break;
00278       }
00279     }
00280     if(!found) {
00281       //      int r = Random::uniform(4);
00282 
00283       // 20 % of objects stored in frequently queried objects list; others
00284       // in sensed_tag_list_;
00285       //      if(r == 0) {
00286       //        freq_qry_tag_list_[num_freq_qry_tags_] = tptr->obj_name_;
00287       //        ++num_freq_qry_tags_;           
00288       //      }
00289       //      else {
00290         sensed_tag_list_[num_sensed_tags_] = tptr->obj_name_;
00291         ++num_sensed_tags_;
00292         //      }
00293     }
00294     tptr = tptr->next_;
00295   }
00296   assert(num_sensed_tags_ <= num_tags_);
00297   return(vtags_);
00298 }
00299 
00300 
00301 int
00302 tags_database::get_random_tag()
00303 {
00304 
00305   // Objects in freq_qry_tags_ are queried 10 times as often as those in
00306   // sensed_tag_list_
00307   //  int r = Random::uniform(10);
00308   //  if(r == 0) {
00309     int i = rn_->uniform(num_sensed_tags_);
00310     return(sensed_tag_list_[i]);
00311   //  }
00312   //  else {
00313   //    int i = rn_->uniform(num_freq_qry_tags_);
00314   //    return(freq_qry_tag_list_[i]);
00315     //  }
00316 }
00317 
00318 
00319 
00320 
00321 void
00322 tags_database::search_tags_dbase(double x, double y, double r, dbase_node *dbnode)
00323 {
00324   int i, found = FALSE, removed_tag = 0;
00325   compr_taglist **apt_tags;
00326   tag *prev_tag, *next_tag;
00327   tag *dbase_tags;
00328   dbase_node *child_dbnode;
00329 
00330   // If this is a leaf interior node, lookup the taglist for appropriate tags
00331   if(dbnode->list_node_[0] == NULL) {
00332 
00333     apt_tags = &vtags_;
00334     while((*apt_tags) != NULL)
00335       apt_tags = &((*apt_tags)->next_);
00336     
00337     dbase_tags = dbnode->tags_list_;
00338     prev_tag = dbase_tags;
00339     while(dbase_tags) {
00340       removed_tag = 0;
00341       double xpos = (dbase_tags->x_ - x) * (dbase_tags->x_ - x);
00342       double ypos = (dbase_tags->y_ - y) * (dbase_tags->y_ - y);
00343 
00344       if((xpos + ypos) < (r*r)) {
00345         *apt_tags = new compr_taglist;
00346         (*apt_tags)->obj_name_ = dbase_tags->obj_name_;
00347         apt_tags = &((*apt_tags)->next_);
00348 
00349         // Delete tag from the list so that only one sensor observes 
00350         // a particular tag
00351         removed_tag = 1;
00352         if(prev_tag == dbase_tags) {
00353           dbnode->tags_list_ = dbase_tags->next_;
00354           prev_tag = dbase_tags->next_;
00355         }
00356         else
00357           prev_tag->next_ = dbase_tags->next_;
00358 
00359         next_tag = dbase_tags->next_;
00360         delete dbase_tags;
00361       }
00362       if(!removed_tag) {
00363         prev_tag = dbase_tags;
00364         dbase_tags = dbase_tags->next_;
00365       }
00366       else {
00367         dbase_tags = next_tag;
00368       }
00369     }
00370     return;
00371   }
00372   
00373   for(i = 0; i < NUM_RECTANGLES; ++i) {
00374     found = FALSE;
00375 
00376     // Check if x-r is in the x-range of this node
00377     if(((dbnode->list_node_[i])->x_min_ <= (x - r)) && ((dbnode->list_node_[i])->x_max_ >= (x - r)))
00378       found = TRUE;
00379 
00380     // Check if x+r is in the x-range of this node
00381     if(((dbnode->list_node_[i])->x_min_ <= (x + r)) && ((dbnode->list_node_[i])->x_max_ >= (x + r)))
00382       found = TRUE;
00383 
00384     // Check if the range (x-r,x+r) covers the x-range of this node
00385     if(((dbnode->list_node_[i])->x_min_ >= (x - r)) && ((dbnode->list_node_[i])->x_max_ <= (x + r)))
00386       found = TRUE;
00387     if(found) {
00388       child_dbnode = dbnode->list_node_[i];
00389       search_tags_dbase(x,y,r,child_dbnode);
00390     }
00391   }
00392 }
00393 
00394 
00395 
00396 

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