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); } }
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(); }