// File: /workspace/github_c_makefile_star2_O3/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 $0x58, %rsp
cvtsi2ss %edi, %xmm0
movq %rsi, 0x40(%rsp)
divss 0x1bdb(%rip), %xmm0     # 0x3028
movss %xmm0, 0x20(%rsp)
movl $0x18, %edi
movl $0x5, %esi
callq 0x1100
movq %rax, %rbx
movl $0x5, %edi
movl $0x10, %esi
callq 0x1100
movq %rbx, %r11
movq %rax, %r15
xorps %xmm0, %xmm0
cvtss2sd 0x20(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movl $0x5, %ebp
xorl %r12d, %r12d
leaq 0x3d68(%rip), %r10      # 0x5200
leaq 0x3c71(%rip), %rbx      # 0x5110
xorl %r14d, %r14d
movl $0x5, 0x24(%rsp)
movq (%r10,%r12,8), %rax
cmpl $0x0, 0x8(%rax)
jle 0x1827
xorl %edx, %edx
movq %r12, 0x38(%rsp)
movq 0x28(%rax), %rcx
imulq $0x38, %rdx, %r8
cmpq $0x7fffffff, (%rcx,%r8) # imm = 0x7FFFFFFF
je 0x1817
addq %r8, %rcx
movq 0x10(%rcx), %rcx
xorps %xmm0, %xmm0
cvtsi2ssl (%rcx), %xmm0
movss 0x20(%rsp), %xmm1
ucomiss %xmm0, %xmm1
ja 0x1817
movl %ebp, 0x1c(%rsp)
testl %r14d, %r14d
movl %r14d, 0x4(%rsp)
movq %r8, 0x10(%rsp)
movq %r11, 0x28(%rsp)
jle 0x1720
movq %rdx, 0x30(%rsp)
movl %r14d, %r9d
xorl %ebp, %ebp
xorl %r14d, %r14d
movq %r9, 0x8(%rsp)
movq (%rbx,%r12,8), %rcx
leaq (,%rbp,2), %rax
addq %rbp, %rax
movslq 0x8(%r11,%rax,8), %rdx
movq (%rbx,%rdx,8), %rsi
notq %rsi
testq %rsi, %rcx
jne 0x161c
leaq (%r11,%rax,8), %rax
movq (%r10,%r12,8), %rsi
movq 0x28(%rsi), %rdi
movq (%rax), %rsi
movq (%rdi,%r8), %rdi
xorq %rsi, %rdi
testq %rcx, %rdi
jne 0x161c
testl %r14d, %r14d
jle 0x15bd
movl %r14d, %edx
shlq $0x4, %rdx
xorl %esi, %esi
xorl %ecx, %ecx
movslq %ecx, %rdi
shlq $0x4, %rdi
movups (%r15,%rsi), %xmm0
movups %xmm0, (%r15,%rdi)
movslq 0x8(%r15,%rsi), %rdi
movq (%rbx,%rdi,8), %rdi
notq %rdi
testq %rdi, (%rbx,%r12,8)
jne 0x15aa
leaq (%r15,%rsi), %rdi
movslq 0x8(%rax), %r8
movq (%rax), %r9
xorq (%rdi), %r9
testq %r9, (%rbx,%r8,8)
je 0x15ac
incl %ecx
addq $0x10, %rsi
cmpq %rsi, %rdx
jne 0x1573
movl 0x8(%rax), %edx
movq (%rax), %rsi
jmp 0x15bf
xorl %ecx, %ecx
movslq %ecx, %r14
movq %r14, %rax
shlq $0x4, %rax
movl %edx, 0x8(%r15,%rax)
movq %rsi, (%r15,%rax)
incl %r14d
movl 0x24(%rsp), %r13d
cmpl %r13d, %r14d
jl 0x1612
addl %r13d, %r13d
movslq %r13d, %r12
movq %r12, %rsi
shlq $0x4, %rsi
movq %r15, %rdi
callq 0x1150
movq %rax, %r15
cmpl %r12d, %r14d
jge 0x15df
movl %r13d, 0x24(%rsp)
movq 0x38(%rsp), %r12
leaq 0x3bf3(%rip), %r10      # 0x5200
movq 0x28(%rsp), %r11
movq 0x10(%rsp), %r8
movq 0x8(%rsp), %r9
incq %rbp
cmpq %r9, %rbp
jne 0x1520
testl %r14d, %r14d
jle 0x1724
movl %r14d, %r12d
movq %r12, %rax
shlq $0x4, %rax
movq %rax, 0x8(%rsp)
xorl %r13d, %r13d
xorl %ebp, %ebp
movslq 0x8(%r15,%r13), %rax
movq (%r10,%rax,8), %rdi
movq (%r15,%r13), %rsi
callq 0x1cdb
leaq 0x3ba2(%rip), %r10      # 0x5200
addl %eax, %ebp
addq $0x10, %r13
cmpq %r13, 0x8(%rsp)
jne 0x1645
testl %r14d, %r14d
jle 0x170a
movl $0x1, %r13d
xorl %r14d, %r14d
leaq 0x1(%r14), %rax
movq %rax, 0x50(%rsp)
cmpq %r12, %rax
movq %r13, 0x8(%rsp)
jae 0x16f4
shlq $0x4, %r14
addq %r15, %r14
movq (%r14), %rax
movslq 0x8(%r14), %rcx
movq (%rbx,%rcx,8), %rdx
movq %r13, %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 0x16ec
orq %rdx, %rcx
xorl %edx, %edx
movq %rdx, %rdi
addq $0x8, %rdx
cmpq %rcx, (%rbx,%rdi)
jne 0x16c9
orq %rax, %rsi
movq -0x8(%rdx,%r10), %rdi
callq 0x1c7b
leaq 0x3b16(%rip), %r10      # 0x5200
subl %eax, %ebp
incq %r13
cmpq %r12, %r13
jne 0x1697
movq 0x8(%rsp), %r13
incq %r13
movq 0x50(%rsp), %r14
cmpq %r12, %r14
jne 0x167d
movq 0x28(%rsp), %r11
movq 0x38(%rsp), %r12
movq 0x30(%rsp), %rdx
movq 0x10(%rsp), %r8
jmp 0x172b
xorl %ebp, %ebp
jmp 0x172b
xorl %ebp, %ebp
movq 0x30(%rsp), %rdx
movq (%r10,%r12,8), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax,%r8), %rax
movl (%rax), %r14d
leal (%r14,%r14), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
ucomisd 0x18d2(%rip), %xmm0     # 0x3020
jb 0x1756
sqrtsd %xmm0, %xmm0
jmp 0x176d
movq %rdx, %r13
callq 0x11b0
movq 0x28(%rsp), %r11
movq %r13, %rdx
leaq 0x3a93(%rip), %r10      # 0x5200
subl %ebp, %r14d
xorps %xmm1, %xmm1
cvtsi2sd %r14d, %xmm1
mulsd 0x1898(%rip), %xmm0     # 0x3018
addsd %xmm1, %xmm0
ucomisd 0x48(%rsp), %xmm0
jae 0x179b
movq (%r10,%r12,8), %rax
movl 0x1c(%rsp), %ebp
movl 0x4(%rsp), %r14d
jmp 0x1817
movl 0x1c(%rsp), %ebp
movl 0x4(%rsp), %r14d
movq %rdx, %r13
cmpl %ebp, %r14d
jl 0x17d4
addl %ebp, %ebp
movslq %ebp, %r14
leaq (,%r14,8), %rax
leaq (%rax,%rax,2), %rsi
movq %r11, %rdi
callq 0x1150
movq %rax, %r11
cmpl %r14d, 0x4(%rsp)
movl 0x4(%rsp), %r14d
jge 0x17ac
leaq 0x3a25(%rip), %r10      # 0x5200
movq (%r10,%r12,8), %rax
movq 0x28(%rax), %rcx
movq 0x10(%rsp), %rdi
movq (%rcx,%rdi), %rdx
movslq %r14d, %rsi
leaq (%rsi,%rsi,2), %rsi
movq %rdx, (%r11,%rsi,8)
movl %r12d, 0x8(%r11,%rsi,8)
movq 0x10(%rcx,%rdi), %rdx
movl (%rdx), %edx
movl %edx, 0xc(%r11,%rsi,8)
subl 0xc(%rcx,%rdi), %edx
movl %edx, 0x10(%r11,%rsi,8)
incl %r14d
movq %r13, %rdx
incq %rdx
movslq 0x8(%rax), %rcx
cmpq %rcx, %rdx
jl 0x14bf
incq %r12
cmpq $0x19, %r12
jne 0x14aa
movq %r15, %rdi
movq %r11, %r15
callq 0x1050
movslq %r14d, %rbx
leaq (,%rbx,8), %rax
leaq (%rax,%rax,2), %rsi
movq %r15, %rdi
callq 0x1150
movq 0x40(%rsp), %rcx
movl %ebx, (%rcx)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq