// File: /workspace/github_c_makefile_star2_O1/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 0x2bcb(%rip), %xmm0     # 0x4028
movss %xmm0, 0x1c(%rsp)
movl $0x18, %edi
movl $0x5, %esi
callq 0x1110
movq %rax, %rbx
movl $0x5, %edi
movl $0x10, %esi
callq 0x1110
movq %rbx, %rdi
movq %rax, %r15
xorps %xmm0, %xmm0
cvtss2sd 0x1c(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movl $0x5, %r12d
xorl %r10d, %r10d
leaq 0x4d57(%rip), %r11      # 0x6200
leaq 0x4c60(%rip), %rbx      # 0x6110
xorl %r13d, %r13d
movl $0x5, %r14d
movq (%r11,%r10,8), %rax
cmpl $0x0, 0x8(%rax)
jle 0x1829
xorl %edx, %edx
movq %r10, 0x20(%rsp)
movq 0x28(%rax), %rax
imulq $0x38, %rdx, %rbp
cmpq $0x7fffffff, (%rax,%rbp) # imm = 0x7FFFFFFF
je 0x1815
addq %rbp, %rax
movq 0x10(%rax), %rax
xorps %xmm0, %xmm0
cvtsi2ssl (%rax), %xmm0
movss 0x1c(%rsp), %xmm1
ucomiss %xmm0, %xmm1
ja 0x1815
movl %r12d, 0x18(%rsp)
testl %r13d, %r13d
movq %rbp, 0x30(%rsp)
movq %rdi, 0x28(%rsp)
movl %r13d, 0x14(%rsp)
movq %rdx, 0x38(%rsp)
jle 0x1634
movl %r13d, %esi
xorl %r13d, %r13d
xorl %r12d, %r12d
movq %rsi, 0x8(%rsp)
movq (%rbx,%r10,8), %rcx
leaq (,%r13,2), %rax
addq %r13, %rax
movslq 0x8(%rdi,%rax,8), %rdx
movq (%rbx,%rdx,8), %rdx
notq %rdx
testq %rdx, %rcx
jne 0x1626
leaq (%rdi,%rax,8), %rax
movq (%r11,%r10,8), %rdx
movq 0x28(%rdx), %rdx
movq (%rax), %rsi
xorq (%rdx,%rbp), %rsi
testq %rcx, %rsi
jne 0x1621
testl %r12d, %r12d
jle 0x15c5
movl %r12d, %ecx
shlq $0x4, %rcx
xorl %esi, %esi
xorl %edx, %edx
movslq %edx, %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,%r10,8)
jne 0x15b8
leaq (%r15,%rsi), %rdi
movslq 0x8(%rax), %r8
movq (%rax), %r9
xorq (%rdi), %r9
testq %r9, (%rbx,%r8,8)
je 0x15ba
incl %edx
addq $0x10, %rsi
cmpq %rsi, %rcx
jne 0x1581
jmp 0x15c7
xorl %edx, %edx
movl 0x8(%rax), %ecx
movslq %edx, %r12
movq %r12, %rdx
shlq $0x4, %rdx
movl %ecx, 0x8(%r15,%rdx)
movq (%rax), %rax
movq %rax, (%r15,%rdx)
incl %r12d
cmpl %r14d, %r12d
jl 0x161c
addl %r14d, %r14d
movl %r14d, %ebp
movslq %r14d, %r14
movq %r14, %rsi
shlq $0x4, %rsi
movq %r15, %rdi
callq 0x1160
movq %rax, %r15
cmpl %r14d, %r12d
movl %ebp, %r14d
jge 0x15e8
movq 0x20(%rsp), %r10
leaq 0x4be9(%rip), %r11      # 0x6200
movq 0x30(%rsp), %rbp
movq 0x28(%rsp), %rdi
movq 0x8(%rsp), %rsi
incq %r13
cmpq %rsi, %r13
jne 0x1531
jmp 0x1637
xorl %r12d, %r12d
movl %r14d, 0x10(%rsp)
movl %r12d, %r13d
testl %r12d, %r12d
movl $0x0, %r14d
jle 0x1682
movq %r13, %rax
shlq $0x4, %rax
movq %rax, 0x8(%rsp)
xorl %ebp, %ebp
xorl %r14d, %r14d
movslq 0x8(%r15,%rbp), %rax
movq (%r11,%rax,8), %rdi
movq (%r15,%rbp), %rsi
callq 0x1d32
leaq 0x4b8c(%rip), %r11      # 0x6200
addl %eax, %r14d
addq $0x10, %rbp
cmpq %rbp, 0x8(%rsp)
jne 0x165b
testl %r12d, %r12d
jle 0x1722
movl $0x1, %r12d
xorl %ebp, %ebp
leaq 0x1(%rbp), %rax
movq %rax, 0x50(%rsp)
cmpq %r13, %rax
movq %r12, 0x8(%rsp)
jae 0x170c
shlq $0x4, %rbp
addq %r15, %rbp
movq (%rbp), %rax
movslq 0x8(%rbp), %rcx
movq (%rbx,%rcx,8), %rdx
movq %r12, %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 0x1704
orq %rdx, %rcx
xorl %edx, %edx
movq %rdx, %rdi
addq $0x8, %rdx
cmpq %rcx, (%rbx,%rdi)
jne 0x16e0
orq %rax, %rsi
movq -0x8(%rdx,%r11), %rdi
callq 0x1cd2
leaq 0x4aff(%rip), %r11      # 0x6200
subl %eax, %r14d
incq %r12
cmpq %r13, %r12
jne 0x16ad
movq 0x8(%rsp), %r12
incq %r12
movq 0x50(%rsp), %rbp
cmpq %r13, %rbp
jne 0x1693
movq 0x20(%rsp), %rax
movq (%r11,%rax,8), %rax
movq 0x28(%rax), %rax
movq 0x30(%rsp), %rcx
movq 0x10(%rax,%rcx), %rax
movl (%rax), %ebp
leal (,%rbp,2), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
ucomisd 0x28cf(%rip), %xmm0     # 0x4020
jb 0x1759
sqrtsd %xmm0, %xmm0
jmp 0x1765
callq 0x11c0
leaq 0x4a9b(%rip), %r11      # 0x6200
movq 0x28(%rsp), %rdi
movl 0x18(%rsp), %r12d
movl 0x14(%rsp), %r13d
movq 0x38(%rsp), %rdx
subl %r14d, %ebp
xorps %xmm1, %xmm1
cvtsi2sd %ebp, %xmm1
mulsd 0x288d(%rip), %xmm0     # 0x4018
addsd %xmm1, %xmm0
ucomisd 0x48(%rsp), %xmm0
jae 0x17a3
movq 0x20(%rsp), %r10
movl 0x10(%rsp), %r14d
jmp 0x1815
movq %rdx, %rbp
cmpl %r12d, %r13d
jl 0x17ca
addl %r12d, %r12d
movslq %r12d, %r14
leaq (,%r14,8), %rax
leaq (%rax,%rax,2), %rsi
callq 0x1160
movq %rax, %rdi
cmpl %r14d, %r13d
jge 0x17ab
movq 0x20(%rsp), %r10
leaq 0x4a2a(%rip), %r11      # 0x6200
movq (%r11,%r10,8), %rax
movq 0x28(%rax), %rax
movq 0x30(%rsp), %rsi
movq (%rax,%rsi), %rcx
movslq %r13d, %rdx
leaq (%rdx,%rdx,2), %rdx
movq %rcx, (%rdi,%rdx,8)
movl %r10d, 0x8(%rdi,%rdx,8)
movq 0x10(%rax,%rsi), %rcx
movl (%rcx), %ecx
movl %ecx, 0xc(%rdi,%rdx,8)
subl 0xc(%rax,%rsi), %ecx
movl %ecx, 0x10(%rdi,%rdx,8)
incl %r13d
movl 0x10(%rsp), %r14d
movq %rbp, %rdx
incq %rdx
movq (%r11,%r10,8), %rax
movslq 0x8(%rax), %rcx
cmpq %rcx, %rdx
jl 0x14ce
incq %r10
cmpq $0x19, %r10
jne 0x14b9
movq %rdi, %r14
movq %r15, %rdi
callq 0x1050
movslq %r13d, %rbx
leaq (,%rbx,8), %rax
leaq (%rax,%rax,2), %rsi
movq %r14, %rdi
callq 0x1160
movq 0x40(%rsp), %rcx
movl %ebx, (%rcx)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop