tags.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:9k
源码类别:

通讯编程

开发平台:

Visual C++

  1. // Author: Satish Kumar, kkumar@isi.edu
  2. extern "C" {
  3. #include <stdarg.h>
  4. #include <float.h>
  5. };
  6. #include "tags.h"
  7. #include "random.h"
  8. #include <string.h>
  9. #define MAX_P1 10
  10. #define MAX_P2 10
  11. // Split into 10 rectangles at each level. Have two levels for now.
  12. static class TagDbaseClass:public TclClass
  13. {
  14.   public:
  15.   TagDbaseClass ():TclClass ("TagDbase")
  16.   {
  17.   }
  18.   TclObject *create (int, const char *const *)
  19.   {
  20.     return (new tags_database ());
  21.   }
  22. } class_tags_database;
  23. void tags_database::
  24. trace (char *fmt,...)
  25. {
  26.   va_list ap; // Define a variable ap that will refer to each argument in turn
  27.   if (!tracetarget_)
  28.     return;
  29.   // Initializes ap to first argument
  30.   va_start (ap, fmt); 
  31.   // Prints the elements in turn
  32.   vsprintf (tracetarget_->buffer (), fmt, ap); 
  33.   tracetarget_->dump ();
  34.   // Does the necessary clean-up before returning
  35.   va_end (ap); 
  36. }
  37. int 
  38. tags_database::command (int argc, const char *const *argv)
  39. {
  40.   if (argc == 7)
  41.     {
  42.       if (strcmp (argv[1], "create_database") == 0)
  43.         {
  44.   double x_min = atof(argv[2]);
  45.   double x_max = atof(argv[3]);
  46.   double y_min = atof(argv[4]);
  47.   double y_max = atof(argv[5]);
  48.   int num_tags = atoi(argv[6]);
  49.   
  50.   num_tags_ = num_tags;
  51.   sensed_tag_list_ = new int[num_tags];
  52.   freq_qry_tag_list_ = new int[num_tags];
  53.   create_tags_database(x_min,x_max,y_min,y_max,num_tags);
  54.           return (TCL_OK);
  55.         }
  56.     }
  57.   else if (argc == 3)
  58.     {
  59.       if (strcasecmp (argv[1], "tracetarget") == 0)
  60.         {
  61.           TclObject *obj;
  62.   if ((obj = TclObject::lookup (argv[2])) == 0)
  63.             {
  64.               fprintf (stderr, "%s: %s lookup of %s failedn", __FILE__, argv[1],
  65.                        argv[2]);
  66.               return TCL_ERROR;
  67.             }
  68.           tracetarget_ = (Trace *) obj;
  69.           return TCL_OK;
  70.         }
  71.     }
  72.   return (TclObject::command(argc, argv));
  73. }
  74. void
  75. tags_database::create_tags_database(double x_min, double x_max, double y_min, double y_max, int num_tags)
  76. {
  77.   dbase_node *dbnode;
  78.   int i;
  79.   assert((x_min <= x_max) && (y_min <= y_max));  
  80.   // Creating the data structures for storing the tags information
  81.   tags_db_ = new dbase_node(x_min, x_max, y_min, y_max);
  82.   // Creates child nodes for tags_db_ and partitions x and y ranges
  83.   add_level(x_min, x_max, y_min, y_max, tags_db_);
  84.   
  85.   // Creates child nodes for each of tags_db_'s children
  86.   for(i = 0; i < NUM_RECTANGLES; ++i) {
  87.     dbnode = tags_db_->list_node_[i];
  88.     assert((dbnode->x_min_ <= dbnode->x_max_) && (dbnode->y_min_ <= dbnode->y_max_));
  89.     add_level(dbnode->x_min_, dbnode->x_max_, dbnode->y_min_, dbnode->y_max_, dbnode);
  90.   }
  91.   // Creating the tags and adding them to the database
  92.   tag *newtag = new tag();
  93.   i = 0;
  94.   int p1 = 1, p2 = 1, p3 = 1;
  95.   int max_p1 = MAX_P1, max_p2 = MAX_P2;
  96.   int max_p3 = num_tags/(MAX_P1 * MAX_P2);
  97.   while(i < num_tags) {
  98.     newtag->x_ = x_min + rn_->uniform(x_max-x_min);
  99.     newtag->y_ = y_min + rn_->uniform(y_max-y_min);
  100.     newtag->obj_name_ = (int)((p1 * pow(2,24)) + (p2 * pow(2,16)) + p3) ;
  101.     ++p3;
  102.     if(p3 == max_p3) {
  103.       p3 = 1;
  104.       ++p2;
  105.       if(p2 == max_p2) {
  106. p2 = 1;
  107. ++p1;
  108. if(p1 == max_p1) {
  109.   break;
  110. }
  111.       }
  112.     }
  113.     Addtag(newtag);
  114.     //    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_);
  115.     ++i;
  116.   }
  117.   delete newtag;
  118. }
  119. void
  120. tags_database::add_level(double x_min, double x_max, double y_min, double y_max, dbase_node *dbnode)
  121. {
  122.   double x1, x2, y1, y2, x_partition_size;
  123.   int i;
  124. // Just partitioning along x-range for now
  125.   x_partition_size = (x_max-x_min)/NUM_RECTANGLES;
  126.   x2 = x_min;
  127.   y1 = y_min;
  128.   y2 = y_max;
  129.   for(i = 0; i < NUM_RECTANGLES; ++i) {
  130.     x1 = x2;                    // x_min for partition
  131.     x2 = x1 + x_partition_size; // x_max for partition
  132.     
  133.     // The last partition should cover the remaining ranges
  134.     if (i == (NUM_RECTANGLES - 1)) {
  135.       x2 = x_max;
  136.     }
  137.     dbnode->list_node_[i] = new dbase_node(x1,x2,y1,y2);
  138.   }
  139. }
  140. void
  141. tags_database::Addtag(const tag* tag_)
  142. {
  143.   dbase_node *dbnode = tags_db_;
  144.   int i, found = FALSE;
  145.   tag *new_tag;
  146.   while(dbnode->list_node_[0] != NULL) {
  147.     for(i = 0; i < NUM_RECTANGLES; ++i) {
  148.       if(((dbnode->list_node_[i])->x_min_ <= tag_->x_) && ((dbnode->list_node_[i])->x_max_ >= tag_->x_)) {
  149. found = TRUE;
  150. break;
  151.       }
  152.     }
  153.     assert(found);
  154.     dbnode = dbnode->list_node_[i];
  155.   }
  156.   
  157.   if(dbnode->tags_list_ == NULL) {
  158.     dbnode->tags_list_ = new tag;
  159.     new_tag = dbnode->tags_list_;
  160.   }
  161.   else {
  162.     new_tag = dbnode->tags_list_;
  163.     while(new_tag->next_ != NULL) {
  164.       new_tag = new_tag->next_;
  165.     }
  166.     new_tag->next_ = new tag;
  167.     new_tag = new_tag->next_;
  168.   }
  169.   // tags do not have any attributes for now
  170.   new_tag->x_ = tag_->x_;
  171.   new_tag->y_ = tag_->y_;
  172.   new_tag->obj_name_ = tag_->obj_name_;
  173. }
  174. void
  175. tags_database::Deletetag(const tag *tag_)
  176. {
  177.   dbase_node *dbnode = tags_db_;
  178.   int i, found = FALSE;
  179.   tag *old_tag;
  180.   while(dbnode->list_node_[0] != NULL) {
  181.     for(i = 0; i < NUM_RECTANGLES; ++i) {
  182.       if(((dbnode->list_node_[i])->x_min_ <= tag_->x_) && ((dbnode->list_node_[i])->x_max_ >= tag_->x_)) {
  183. found = TRUE;
  184. break;
  185.       }
  186.     }
  187.     assert(found);
  188.     dbnode = dbnode->list_node_[i];
  189.   }
  190.   
  191.   assert(dbnode->tags_list_ != NULL);
  192.   //old_tag will point to the tag entry that is to be deleted
  193.   found = FALSE;
  194.   old_tag = dbnode->tags_list_;
  195.   tag *prev_tag = old_tag; // Should have previous tag in list
  196.   while(old_tag != NULL) {
  197.     if ((old_tag->x_== tag_->x_) && (old_tag->y_ == tag_->y_) && (old_tag->obj_name_ == tag_->obj_name_)) {
  198.       found = TRUE;
  199.       break;
  200.     }
  201.     prev_tag = old_tag;
  202.     old_tag = old_tag->next_;
  203.   }
  204.   
  205.   assert(found);
  206.   prev_tag->next_ = old_tag->next_;
  207.   delete old_tag;
  208. }
  209. compr_taglist *
  210. tags_database::Gettags(double x, double y, double r)
  211. {
  212.   dbase_node *dbnode = tags_db_;
  213.   compr_taglist *tptr;
  214.   int i, found = FALSE;
  215.   vtags_ = NULL;
  216.   
  217.   // This interior node should have child nodes
  218.   //  assert(dbnode->list_node_[0] != NULL);
  219.   search_tags_dbase(x,y,r,dbnode);
  220.   tptr = vtags_;
  221.   while(tptr) {
  222.     found = FALSE;
  223.     for(i = 0; i < num_sensed_tags_; ++i) {
  224.       if(tptr->obj_name_ == sensed_tag_list_[i]) {
  225. found = TRUE;
  226. break;
  227.       }
  228.     }
  229.     if(!found) {
  230.       //      int r = Random::uniform(4);
  231.       // 20 % of objects stored in frequently queried objects list; others
  232.       // in sensed_tag_list_;
  233.       //      if(r == 0) {
  234.       // freq_qry_tag_list_[num_freq_qry_tags_] = tptr->obj_name_;
  235.       // ++num_freq_qry_tags_;   
  236.       //      }
  237.       //      else {
  238. sensed_tag_list_[num_sensed_tags_] = tptr->obj_name_;
  239. ++num_sensed_tags_;
  240. //      }
  241.     }
  242.     tptr = tptr->next_;
  243.   }
  244.   assert(num_sensed_tags_ <= num_tags_);
  245.   return(vtags_);
  246. }
  247. int
  248. tags_database::get_random_tag()
  249. {
  250.   // Objects in freq_qry_tags_ are queried 10 times as often as those in
  251.   // sensed_tag_list_
  252.   //  int r = Random::uniform(10);
  253.   //  if(r == 0) {
  254.     int i = rn_->uniform(num_sensed_tags_);
  255.     return(sensed_tag_list_[i]);
  256.   //  }
  257.   //  else {
  258.   //    int i = rn_->uniform(num_freq_qry_tags_);
  259.   //    return(freq_qry_tag_list_[i]);
  260.     //  }
  261. }
  262. void
  263. tags_database::search_tags_dbase(double x, double y, double r, dbase_node *dbnode)
  264. {
  265.   int i, found = FALSE, removed_tag = 0;
  266.   compr_taglist **apt_tags;
  267.   tag *prev_tag, *next_tag;
  268.   tag *dbase_tags;
  269.   dbase_node *child_dbnode;
  270.   // If this is a leaf interior node, lookup the taglist for appropriate tags
  271.   if(dbnode->list_node_[0] == NULL) {
  272.     apt_tags = &vtags_;
  273.     while((*apt_tags) != NULL)
  274.       apt_tags = &((*apt_tags)->next_);
  275.     
  276.     dbase_tags = dbnode->tags_list_;
  277.     prev_tag = dbase_tags;
  278.     while(dbase_tags) {
  279.       removed_tag = 0;
  280.       double xpos = (dbase_tags->x_ - x) * (dbase_tags->x_ - x);
  281.       double ypos = (dbase_tags->y_ - y) * (dbase_tags->y_ - y);
  282.       if((xpos + ypos) < (r*r)) {
  283. *apt_tags = new compr_taglist;
  284. (*apt_tags)->obj_name_ = dbase_tags->obj_name_;
  285. apt_tags = &((*apt_tags)->next_);
  286. // Delete tag from the list so that only one sensor observes 
  287. // a particular tag
  288. removed_tag = 1;
  289. if(prev_tag == dbase_tags) {
  290.   dbnode->tags_list_ = dbase_tags->next_;
  291.   prev_tag = dbase_tags->next_;
  292. }
  293. else
  294.   prev_tag->next_ = dbase_tags->next_;
  295. next_tag = dbase_tags->next_;
  296. delete dbase_tags;
  297.       }
  298.       if(!removed_tag) {
  299. prev_tag = dbase_tags;
  300. dbase_tags = dbase_tags->next_;
  301.       }
  302.       else {
  303. dbase_tags = next_tag;
  304.       }
  305.     }
  306.     return;
  307.   }
  308.   
  309.   for(i = 0; i < NUM_RECTANGLES; ++i) {
  310.     found = FALSE;
  311.     // Check if x-r is in the x-range of this node
  312.     if(((dbnode->list_node_[i])->x_min_ <= (x - r)) && ((dbnode->list_node_[i])->x_max_ >= (x - r)))
  313.       found = TRUE;
  314.     // Check if x+r is in the x-range of this node
  315.     if(((dbnode->list_node_[i])->x_min_ <= (x + r)) && ((dbnode->list_node_[i])->x_max_ >= (x + r)))
  316.       found = TRUE;
  317.     // Check if the range (x-r,x+r) covers the x-range of this node
  318.     if(((dbnode->list_node_[i])->x_min_ >= (x - r)) && ((dbnode->list_node_[i])->x_max_ <= (x + r)))
  319.       found = TRUE;
  320.     if(found) {
  321.       child_dbnode = dbnode->list_node_[i];
  322.       search_tags_dbase(x,y,r,child_dbnode);
  323.     }
  324.   }
  325. }