void Merge(const int& first, const int& second) {
		Tree<int>* first_tree;
		Tree<int>* second_tree;
		if (vertices_by_objects.count(first) == 0) {
			first_tree = new Tree<int>(first);
			trees_by_roots[first_tree->root] = first_tree;
			vertices_by_objects[first] = first_tree->root;
		} else {
			first_tree = trees_by_roots[Tree<int>::FindRoot(vertices_by_objects[first])];
		}
		if (vertices_by_objects.count(second) == 0) {
			second_tree = new Tree<int>(second);
			trees_by_roots[second_tree->root] = second_tree;
			vertices_by_objects[second] = second_tree->root;
		} else {
			second_tree = trees_by_roots[Tree<int>::FindRoot(vertices_by_objects[second])];
		}
		if (first_tree != second_tree) {
//			std::cout << "MERGE(" << first << ", " << second << ")\n";

			first_tree->Merge(second_tree);
			trees_by_roots.erase(first_tree->root);
			delete trees_by_roots[second_tree->root];
			trees_by_roots.erase(second_tree->root);
			trees_by_roots[first_tree->root] = first_tree;


//			Vertex<int>* a = second_tree->root;
//			first_tree->Merge(second_tree);
//			std::cout << "END MERGE\n";
//			trees_by_roots.erase(a);
		}

	}
Example #2
0
int main(int argc, char **argv)
{
  read_cmd_options(argc,argv);

  // sender stats and stop flags

  count = new uint64_t[nsenders];
  shut = new int[nsenders];
  for (int i = 0; i < nsenders; i++) count[i] = shut[i] = 0;

  // setup UDP port

  const int socket = ::socket(PF_INET6, SOCK_DGRAM, 0);
  if (socket == -1)
    throw std::runtime_error(std::string("socket(): ") + ::strerror(errno));

  struct sockaddr_in6 address;
  ::memset(&address, 0, sizeof(address));
  address.sin6_family = AF_INET6;
  address.sin6_addr = in6addr_any;
  address.sin6_port = htons(port);
  if (-1 == ::bind(socket, reinterpret_cast<sockaddr*>(&address),
                   sizeof(address)))
    throw std::runtime_error(std::string("bind(): ") + ::strerror(errno));

  // scale maxactive by number of generators
  // oset/iset = active key sets for outer/inner keys
  // olist/ilist = doubly-linked lists so can delete least recently used
  // mactive = # of keys in active set for inner keys
  // okv/ikv = outer/inner key-value hash tables
  // ofree = index of 1st free element in linked list of free oset elements

  maxactive *= nsenders;
  Kouter *oset = new Kouter[maxactive];
  Kinner *iset = new Kinner[maxactive];
  MyDoubleLinkedList<Kouter*> olist;
  MyDoubleLinkedList<Kinner*> ilist;
  int mactive = 0;

  Kouter *ofree = oset;
  for (int i = 0; i < maxactive; i++)
    oset[i].next = &oset[i+1];
  oset[maxactive-1].next = NULL;

  // pre-allocate to maxactive per generator, in agreement with generator #3
  
  okv.rehash(ceil(maxactive / okv.max_load_factor()));
  ikv.rehash(ceil(maxactive / ikv.max_load_factor()));

  // packet buffer length of 64 bytes per datum is ample

  int maxbuf = 64*perpacket;
  std::vector<char> buffer(maxbuf);
  int ipacket;

  // loop on reading packets

  Kouter *okey;
  Kinner *ikey;

  int max = 0;

  while (true) {

    // read a packet with Nbytes

    const int nbytes = ::recv(socket,&buffer[0],buffer.size()-1,0);
    buffer[nbytes] = '\0';

    // check if STOP packet
    // exit if have received STOP packet from every sender
    
    if (nbytes < 8) {
      if (shutdown(&buffer[0])) break;
      continue;
    }

    nrecv++;
    
    // tally stats on packets from each sender

    if (countflag) {
      sscanf(&buffer[0],"packet %d",&ipacket);
      count[ipacket % nsenders]++;
    }

    // scan past header line

    strtok(&buffer[0],"\n");

    // process perpacket datums in packet

    for (int i = 0; i < perpacket; i++) {
      uint64_t key = strtoul(strtok(NULL,",\n"),NULL,0);
      char *value = strtok(NULL,",\n");
      int count = atoi(strtok(NULL,",\n"));

      // store outer key in okv hash table
      // if new key, add to active set, deleting LRU key if necessary
      // count = # of times key has been seen
      // discard key if its count is not consistent with okv count
      // build up inner key 16-bits at a time

      if (!okv.count(key)) {
        if (count > 1) continue;
        nunique++;
        if (ofree) {
          okey = ofree;
          ofree = ofree->next;
          okv[key] = okey;
        } else {
          okey = olist.last;
          olist.remove(okey);
          okv.erase(okey->key);
          okv[key] = okey;
        }
        okey->key = key;
        okey->inner = atoi(value);
        okey->count = 1;
        olist.prepend(okey);

      } else {
        okey = okv[key];
        if (okey->count != count-1) {
          okv.erase(okey->key);
          olist.remove(okey);
          okey->next = ofree;
          ofree = okey;
          continue;
        }
        if (count <= 4) {
          olist.move2front(okey);
          uint64_t ivalue = atoi(value);
          ivalue = ivalue << (16*okey->count);
          okey->inner |= ivalue;
          okey->count++;
          continue;
        }

        // 5th occurrence of outer key, discard it
        // value of inner key = low-order digit of value
        // truth of inner key = hi-order digit of value

        okv.erase(okey->key);
        olist.remove(okey);
        okey->next = ofree;
        ofree = okey;

        key = okey->inner;
        uint32_t innervalue,truth;
        if (value[0] == '0') truth = 0;
        else truth = 1;
        if (value[1] == '0') innervalue = 0;
        else innervalue = 1;

        if (!ikv.count(key)) {
          munique++;
          if (mactive < maxactive) {
            ikey = &iset[mactive++];
            ikv[key] = ikey;
          } else {
            ikey = ilist.last;
            ilist.remove(ikey);
            ikv.erase(ikey->key);
            ikv[key] = ikey;
          }
          ikey->key = key;
          ikey->count = 1;
          ikey->value = innervalue;
          ilist.prepend(ikey);
          
        } else {
          ikey = ikv[key];
          ilist.move2front(ikey);

          if (ikey->value < 0) {
            ikey->count++;
            continue;
          }
        
          ikey->count++;
          ikey->value += innervalue;

          if (ikey->count > max) max = ikey->count;

          if (ikey->count == nthresh) {
            if (ikey->value > mthresh) {
              if (truth) {
                nfalse++;
                printf("false negative = %" PRIu64 "\n",key);
              } else ntrue++;
            } else {
              if (truth) {
                ptrue++;
                printf("true anomaly = %" PRIu64 "\n",key);
              } else {
                pfalse++;
                printf("false positive = %" PRIu64 "\n",key);
              }
            }
            ikey->value = -1;
          }
        }
      }
    }
  }

  //printf("IFLAG %d %d\n",olist.check(),ilist.check());

  // close UDP port and print stats

  ::close(socket);
  stats();
}