// File: /workspace/github_c_makefile_star2_O2/ranbenbasat[P]RHHH/randhhh2D.c
// Function: output2
HeavyHitter * output2(int threshold, int * numhitters) {
	HeavyHitter * output; //This will be the heavy hitters to output
	int n = 0; //the number of items in output
	int outputspace = 5, hpspace = 5;
#ifdef PROB
	float adjustedThreshold = (1-ignoreProb) * threshold / ((float) NUM_COUNTERS);
#else
	float adjustedThreshold = threshold / ((float) NUM_COUNTERS);
#endif	
	int i, j, k, l, m, im;
	LCLitem_t newIP;
	int s;
	Descendant * Hp; //the direct descendants
	int numdescendants;
	int z = 4; //TODO: replace with a function of delta_s

	output = (HeavyHitter*) calloc(sizeof(HeavyHitter), outputspace); //ensure that it is sufficient
	Hp = (Descendant*) calloc(hpspace, sizeof(Descendant));
	
	for (i = 0; i < NUM_COUNTERS; i++) {
		for (j = 0; j < counters[i]->COUNTERSIZE; j++) {
			if (counters[i]->COUNTERS[j].item != LCL_NULLITEM) {
				//Now we just have to check that the counts are sufficient
				//s = amount that needs to be subtracted from the count
				
				if (counters[i]->COUNTERS[j].COUNT < adjustedThreshold) continue; // no point continuing

				numdescendants = 0; // |Hp| = 0
				for (k = 0; k < n; k++) {
					if ((masks[i] & masks[output[k].mask]) == masks[i] && (counters[i]->COUNTERS[j].item & masks[i]) == (output[k].item & masks[i])) {
						//output[k] is a descendant---is it direct?
						//assume it is for now, but check to make sure the assumption was valid for the previous ones
						l = 0;
						for (m = 0; m < numdescendants; m++) {
							Hp[l] = Hp[m];
							if ((masks[i] & masks[Hp[m].mask]) != masks[i] || (Hp[m].id & masks[output[k].mask]) != (output[k].item & masks[output[k].mask])) l++;
						}	
						numdescendants = l;
						Hp[numdescendants].mask = output[k].mask;
						Hp[numdescendants].id = output[k].item;
						numdescendants++;
						while (numdescendants >= hpspace) {hpspace *= 2; Hp = (Descendant*) realloc(Hp, sizeof(Descendant)*hpspace);}
					}
				}

				//now compute s
				s = 0;
				for (k = 0; k < numdescendants; k++) {
					s += LCU_PointEstLow(counters[Hp[k].mask], Hp[k].id);
				}
				for (k = 0; k < numdescendants; k++) {
					for (l = k + 1; l < numdescendants; l++) {

						if ((Hp[k].id & (masks[Hp[k].mask] & masks[Hp[l].mask])) != (Hp[l].id & (masks[Hp[k].mask] & masks[Hp[l].mask]))) continue; //there is no ip common to the subnets k and l

						newIP = (Hp[k].id | Hp[l].id);
						//compute the right mask
						im = 0; while(masks[im] != (masks[Hp[k].mask] | masks[Hp[l].mask])) im++;
						assert(masks[im] == (masks[Hp[k].mask] | masks[Hp[l].mask]));
						s -= LCU_PointEstUpp(counters[im], newIP);
					}
				}

				//now compare to the threshold
#ifdef PROB				
				if ((counters[i]->COUNTERS[j].COUNT - s  + 2*z*sqrt((1-ignoreProb) * 2 * counters[i]->COUNTERS[j].COUNT ) >= adjustedThreshold ) ){
#else
				if ((counters[i]->COUNTERS[j].COUNT - s  + 2*z*sqrt( 2 * counters[i]->COUNTERS[j].COUNT ) >= adjustedThreshold ) ){	
#endif	
					//Add this item to our list of heavy hitters
					while (n >= outputspace) {outputspace *= 2; output = (HeavyHitter *) realloc(output, outputspace * sizeof(HeavyHitter));}
					output[n].item = counters[i]->COUNTERS[j].item;
					output[n].mask = i;
					output[n].upper = counters[i]->COUNTERS[j].COUNT;
					output[n].lower = output[n].upper - counters[i]->COUNTERS[j].delta;
					n++;
				}

			}
		}
	}
	
	free(Hp);

	//now clean up the output
	output = (HeavyHitter*) realloc(output, n * sizeof(HeavyHitter));
	//qsort(output, n, sizeof(HeavyHitter), &cmpHH);

	*numhitters = n;

	return output;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
cvtsi2ss %edi, %xmm0
movq %rsi, 0x38(%rsp)
divss 0x1c05(%rip), %xmm0     # 0x3028
movss %xmm0, 0x24(%rsp)
pushq $0x18
popq %rdi
pushq $0x5
popq %r15
movq %r15, %rsi
callq 0x1100
movq %rax, %r12
pushq $0x10
popq %rsi
movq %r15, %rdi
callq 0x1100
movq %rax, %r15
cvtss2sd 0x24(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
xorl %ebp, %ebp
pushq $0x5
popq %r9
leaq 0x3cae(%rip), %rbx      # 0x5110
movl %r9d, %r13d
xorl %r14d, %r14d
cmpq $0x19, %rbp
je 0x17a9
xorl %edx, %edx
movq %r12, %rdi
movq %rbp, 0x48(%rsp)
leaq 0x3d7d(%rip), %rax      # 0x5200
movq (%rax,%rbp,8), %rax
movslq 0x8(%rax), %rcx
cmpq %rcx, %rdx
jge 0x179e
movq 0x28(%rax), %rax
movq %rdx, 0x10(%rsp)
imulq $0x38, %rdx, %rcx
cmpq $0x7fffffff, (%rax,%rcx) # imm = 0x7FFFFFFF
je 0x178e
movq %rcx, 0x30(%rsp)
addq %rcx, %rax
movq 0x10(%rax), %rax
cvtsi2ssl (%rax), %xmm0
movss 0x24(%rsp), %xmm1
ucomiss %xmm0, %xmm1
ja 0x178e
movl %r13d, 0x1c(%rsp)
xorl %r13d, %r13d
testl %r14d, %r14d
movl $0x0, %r12d
movl %r14d, 0x20(%rsp)
cmovgl %r14d, %r12d
xorl %r14d, %r14d
movq %rdi, 0x28(%rsp)
cmpq %r12, %r13
je 0x15cf
movq (%rbx,%rbp,8), %rcx
imulq $0x18, %r13, %rax
movslq 0x8(%rdi,%rax), %rdx
movq (%rbx,%rdx,8), %rdx
notq %rdx
testq %rdx, %rcx
jne 0x153a
addq %rdi, %rax
leaq 0x3ce4(%rip), %rdx      # 0x5200
movq (%rdx,%rbp,8), %rdx
movq 0x28(%rdx), %rdx
movq (%rax), %rsi
movq 0x30(%rsp), %rdi
xorq (%rdx,%rdi), %rsi
testq %rcx, %rsi
je 0x153f
movq 0x28(%rsp), %rdi
incq %r13
jmp 0x14f0
xorl %ecx, %ecx
testl %r14d, %r14d
cmovlel %ecx, %r14d
movq %r14, %rdx
shlq $0x4, %rdx
xorl %r14d, %r14d
movslq %r14d, %rsi
cmpq %rcx, %rdx
je 0x1597
shlq $0x4, %rsi
movups (%r15,%rcx), %xmm0
movups %xmm0, (%r15,%rsi)
movslq 0x8(%r15,%rcx), %rsi
movq (%rbx,%rsi,8), %rsi
notq %rsi
testq %rsi, (%rbx,%rbp,8)
jne 0x158e
leaq (%r15,%rcx), %rsi
movslq 0x8(%rax), %rdi
movq (%rax), %r8
xorq (%rsi), %r8
testq %r8, (%rbx,%rdi,8)
je 0x1591
incl %r14d
addq $0x10, %rcx
jmp 0x1552
movl 0x8(%rax), %ecx
shlq $0x4, %rsi
movl %ecx, 0x8(%r15,%rsi)
movq (%rax), %rax
movq %rax, (%r15,%rsi)
incl %r14d
cmpl %r9d, %r14d
jl 0x1535
addl %r9d, %r9d
movslq %r9d, %rsi
shlq $0x4, %rsi
movq %r15, %rdi
movl %r9d, %r15d
callq 0x1150
movl %r15d, %r9d
movq %rax, %r15
jmp 0x15ad
movl %r9d, 0xc(%rsp)
xorl %r12d, %r12d
testl %r14d, %r14d
movl $0x0, %ebp
cmovgl %r14d, %ebp
movq %rbp, 0x50(%rsp)
shlq $0x4, %rbp
xorl %r13d, %r13d
cmpq %r12, %rbp
je 0x1616
movslq 0x8(%r15,%r12), %rax
leaq 0x3c00(%rip), %rcx      # 0x5200
movq (%rcx,%rax,8), %rdi
movq (%r15,%r12), %rsi
callq 0x1bd1
addl %eax, %r13d
addq $0x10, %r12
jmp 0x15ef
xorl %r12d, %r12d
pushq $0x1
popq %rbp
movq 0x30(%rsp), %r8
cmpq 0x50(%rsp), %r12
je 0x16b9
movq %r12, 0x60(%rsp)
shlq $0x4, %r12
addq %r15, %r12
movq %rbp, 0x58(%rsp)
cmpl %ebp, %r14d
jle 0x16a4
movq (%r12), %rax
movslq 0x8(%r12), %rcx
movq (%rbx,%rcx,8), %rdx
movq %rbp, %rsi
shlq $0x4, %rsi
movslq 0x8(%r15,%rsi), %rcx
movq (%rbx,%rcx,8), %rcx
movq (%r15,%rsi), %rsi
movq %rsi, %rdi
xorq %rax, %rdi
andq %rdx, %rdi
testq %rcx, %rdi
jne 0x169f
orq %rdx, %rcx
xorl %edx, %edx
movq %rdx, %rdi
addq $0x8, %rdx
cmpq %rcx, (%rbx,%rdi)
jne 0x1676
orq %rax, %rsi
leaq 0x3b73(%rip), %rax      # 0x5200
movq -0x8(%rdx,%rax), %rdi
callq 0x1b6e
subl %eax, %r13d
movq 0x30(%rsp), %r8
incq %rbp
jmp 0x163d
movq 0x60(%rsp), %r12
incq %r12
movq 0x58(%rsp), %rbp
incq %rbp
jmp 0x1621
movq 0x48(%rsp), %rbp
leaq 0x3b3b(%rip), %rax      # 0x5200
movq (%rax,%rbp,8), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax,%r8), %rax
movl (%rax), %r14d
leal (%r14,%r14), %eax
cvtsi2sd %eax, %xmm0
ucomisd 0x193b(%rip), %xmm0     # 0x3020
jb 0x16ed
sqrtsd %xmm0, %xmm0
jmp 0x16f2
callq 0x11b0
movq 0x28(%rsp), %rdi
movl 0xc(%rsp), %r9d
movq 0x10(%rsp), %rax
subl %r13d, %r14d
cvtsi2sd %r14d, %xmm1
mulsd 0x1907(%rip), %xmm0     # 0x3018
addsd %xmm1, %xmm0
ucomisd 0x40(%rsp), %xmm0
jae 0x1729
movl 0x20(%rsp), %r14d
movl 0x1c(%rsp), %r13d
jmp 0x1793
movl 0x20(%rsp), %r14d
movl 0x1c(%rsp), %r13d
cmpl %r13d, %r14d
jl 0x1751
addl %r13d, %r13d
movslq %r13d, %rax
imulq $0x18, %rax, %rsi
callq 0x1150
movl 0xc(%rsp), %r9d
movq %rax, %rdi
jmp 0x1733
leaq 0x3aa8(%rip), %rax      # 0x5200
movq (%rax,%rbp,8), %rax
movq 0x28(%rax), %rax
movq 0x30(%rsp), %rsi
movq (%rax,%rsi), %rcx
movslq %r14d, %rdx
imulq $0x18, %rdx, %rdx
movq %rcx, (%rdi,%rdx)
movl %ebp, 0x8(%rdi,%rdx)
movq 0x10(%rax,%rsi), %rcx
movl (%rcx), %ecx
movl %ecx, 0xc(%rdi,%rdx)
subl 0xc(%rax,%rsi), %ecx
movl %ecx, 0x10(%rdi,%rdx)
incl %r14d
movq 0x10(%rsp), %rax
incq %rax
movq %rax, %rdx
jmp 0x147c
movq %rdi, %r12
incq %rbp
jmp 0x1468
movq %r15, %rdi
callq 0x1050
movslq %r14d, %rbx
imulq $0x18, %rbx, %rsi
movq %r12, %rdi
callq 0x1150
movq 0x38(%rsp), %rcx
movl %ebx, (%rcx)
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop