static inline void reset_new_el(active_ring_t * aring, active_el_t * el) { el->id = ((uint64_t)evahash((uint8_t*)å->nextid, sizeof(uint64_t),aring->idseed) << 32) | (uint64_t)evahash((uint8_t*)å->nextid, sizeof(uint64_t),aring->idseed + 1); aring->nextid++; el->cnt = 0; el->acc = 0; el->total = aring->cnt_dist[rand_r(aring->kseed)%MAX_DISTRO]; el->bias = (evahash((uint8_t*)&el->id, sizeof(uint64_t),aring->mask) & 0xFF) == 0x11; // select q in ring int q = rand_r(aring->kseed) % aring->max; // add el to ring el->next = aring->qset[q].head; aring->qset[q].head = el; aring->qset[q].cnt++; }
int main(int argc, char ** argv) { udpt = udp_throw_init(0); if (!udpt) { fprintf(stderr,"ERROR: unable to generate data\n"); return -1; } read_cmd_options(argc,argv); // initialize RNG and seeds // use different keyoffsets in parallel, so key spaces are disjoint if (!kseed) kseed = (unsigned int) time(NULL); kseed += whichgen; vseed += whichgen; srand(kseed); keyoffset += whichgen*keyoffset; // create power-law distribution fprintf(stdout,"initializing power-law distribution ...\n"); power_law_distribution_t * power = power_law_initialize(concentration,maxkeys,RAND_MAX); // packet buffer length of 64 bytes per datum is ample int buflen = 64*perpacket; char *buf = (char *) malloc(buflen*sizeof(char)); memset(buf,0,buflen); // generate the datums in packets fprintf(stdout,"starting generator ...\n"); fflush(stdout); // plot //int *ycount = (int *) malloc(maxkeys*sizeof(int)); //for (int i = 0; i < maxkeys; i++) ycount[i] = 0; double timestart = myclock(); for (uint64_t i = 0; i < npacket; i++) { // packet header int offset = snprintf(buf,buflen,"packet %" PRIu64 "\n",i*numgen+whichgen); // generate one packet with perpacket datums uint64_t key; for (int j = 0; j < perpacket; j++) { uint64_t rn = rand_r(&kseed); while ((key = power_law_simulate(rn,power)) >= maxkeys) rn = rand_r(&kseed); // plot //ycount[key]++; key += keyoffset; uint32_t value = 0; uint32_t bias = 0; if ((evahash((uint8_t*) &key,sizeof(uint64_t),mask) & 0xFF) == 0x11) { bias = 1; value = ((rand_r(&vseed) & 0xF) == 0); } else value = rand_r(&vseed) & 0x1; offset += snprintf(buf+offset,buflen-offset, "%" PRIu64 ",%u,%u\n",key,value,bias); } // write packet to UDP port(s) udp_throw_data(udpt,buf,offset); // sleep if rate is throttled if (rate) { double n = 1.0*(i+1)*perpacket; double elapsed = myclock() - timestart; double actual_rate = n/elapsed; if (actual_rate > rate) { double delay = n/rate - elapsed; usleep(1.0e6*delay); } } } double timestop = myclock(); // plot //FILE *fp = fopen("tmp.plot","w"); //for (int i = 0; i < maxkeys; i++) // fprintf(fp,"%d %d\n",i,ycount[i]); //fclose(fp); uint64_t ndatum = npacket * perpacket; fprintf(stdout,"packets emitted = %" PRIu64 "\n",npacket); fprintf(stdout,"datums emitted = %" PRIu64 "\n",ndatum); fprintf(stdout,"elapsed time (secs) = %g\n",timestop-timestart); fprintf(stdout,"generation rate (datums/sec) = %g\n", ndatum/(timestop-timestart)); fclose(stdout); power_law_destroy(power); // loop on sending one-integer STOP packets, STOPRATE per sec // allows receivers to shut down cleanly, even if behind int offset = snprintf(buf,buflen,"%d\n",whichgen); while (1) { udp_throw_data(udpt,buf,offset); usleep(1000000/STOPRATE); } udp_throw_destroy(udpt); return 0; }