// File: /workspace/github_c_makefile_star2_O0/ranbenbasat[P]RHHH/randhhh1D.c
// Function: output
HeavyHitter * output(int threshold, int * numhitters, int streamLen) {
	LL ** hashtable; //for transferring counts to parents
	int htsize; //size of hash table;
#ifdef PROB
	float adjustedThreshold = (1-ignoreProb) * threshold / ((float) NUM_COUNTERS);
#else
	float adjustedThreshold = threshold / ((float) NUM_COUNTERS);
#endif
	HeavyHitter * output; //This will be the heavy hitters to output
	int n = 0; //the number of items in output
	int outputspace = 5;
	int i, j;
	LL * tmp;
	int s; //double count
	int z = 4; //TODO: replace with a function of delta_s

	output = (HeavyHitter *) calloc(sizeof(HeavyHitter), outputspace); 

	htsize = (((int)(1.0/SSepsval)) + 1) | 1;
	hashtable = HT_Init(htsize);
	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
				//first calculate the doublecount s
				tmp = HT_Find(hashtable, ((int64__t) counters[i]->COUNTERS[j].item) << 32 | ((int64__t)i), htsize);
				s = (tmp ? tmp->val : 0); //if there are no doublecounts recoreded assume s=0
				//now erase tmp, we don't need it again
				if (tmp) {
					if (tmp->next) tmp->next->prev = tmp->prev;

					if (tmp->prev) tmp->prev->next = tmp->next; //if prev just update it
					else *(HT_FindEntry(hashtable, ((int64__t)counters[i]->COUNTERS[j].item) << 32 | ((int64__t)i), htsize)) = tmp->next; //else update the start of the list
					free(tmp);
				}

				//now compare to the adjustedThreshold 
#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	
					while (outputspace <= n) {outputspace *= 2; output = (HeavyHitter *) realloc(output, sizeof(HeavyHitter) * outputspace);}
					//Add this item to our list of heavy hitters
					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;
					
					//update s
					s = output[n].lower;
					n++;
				}

				//passs up the doublecount s
				if (s != 0 && i + 1 < NUM_COUNTERS) { //check that there is a positive doublecount and someone to pass up to
					tmp = HT_Insert(hashtable, ((int64__t)(counters[i]->COUNTERS[j].item & masks[i+1])) << 32 | ((int64__t) (i+1)), 0, htsize);
					tmp->val += s;
				}
			}
		}
	}

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

	*numhitters = n;

	return output;
}

// Assembly:
subq $0x78, %rsp
movl %edi, 0x74(%rsp)
movq %rsi, 0x68(%rsp)
movl %edx, 0x64(%rsp)
cvtsi2ssl 0x74(%rsp), %xmm0
movss 0x3a99(%rip), %xmm1     # 0x5018
divss %xmm1, %xmm0
movss %xmm0, 0x50(%rsp)
movl $0x0, 0x44(%rsp)
movl $0x5, 0x40(%rsp)
movl $0x4, 0x28(%rsp)
movslq 0x40(%rsp), %rsi
movl $0x10, %edi
callq 0x10f0
movq %rax, 0x48(%rsp)
movsd 0x3a4b(%rip), %xmm0     # 0x5008
divsd 0x5b8b(%rip), %xmm0     # 0x7150
cvttsd2si %xmm0, %eax
addl $0x1, %eax
orl $0x1, %eax
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %edi
callq 0x2e60
movq %rax, 0x58(%rsp)
movl $0x0, 0x3c(%rsp)
cmpl $0x5, 0x3c(%rsp)
jge 0x19ca
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
movslq 0x3c(%rsp), %rdx
leaq 0x5b54(%rip), %rcx      # 0x7160
movq (%rcx,%rdx,8), %rcx
cmpl 0x8(%rcx), %eax
jge 0x19b8
movslq 0x3c(%rsp), %rcx
leaq 0x5b3b(%rip), %rax      # 0x7160
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
cmpl $0x7fffffff, (%rax)     # imm = 0x7FFFFFFF
je 0x19a6
movq 0x58(%rsp), %rdi
movslq 0x3c(%rsp), %rcx
leaq 0x5b0a(%rip), %rax      # 0x7160
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, %esi
shlq $0x20, %rsi
movslq 0x3c(%rsp), %rax
orq %rax, %rsi
movl 0x54(%rsp), %edx
callq 0x3030
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
je 0x169e
movq 0x30(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x24(%rsp)
jmp 0x16a6
xorl %eax, %eax
movl %eax, 0x24(%rsp)
jmp 0x16a6
movl 0x24(%rsp), %eax
movl %eax, 0x2c(%rsp)
cmpq $0x0, 0x30(%rsp)
je 0x175e
movq 0x30(%rsp), %rax
cmpq $0x0, 0x10(%rax)
je 0x16dc
movq 0x30(%rsp), %rax
movq 0x18(%rax), %rcx
movq 0x30(%rsp), %rax
movq 0x10(%rax), %rax
movq %rcx, 0x18(%rax)
movq 0x30(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x1700
movq 0x30(%rsp), %rax
movq 0x10(%rax), %rcx
movq 0x30(%rsp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x10(%rax)
jmp 0x1754
movq 0x30(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x58(%rsp), %rdi
movslq 0x3c(%rsp), %rcx
leaq 0x5a41(%rip), %rax      # 0x7160
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, %esi
shlq $0x20, %rsi
movslq 0x3c(%rsp), %rax
orq %rax, %rsi
movl 0x54(%rsp), %edx
callq 0x30c0
movq 0x18(%rsp), %rcx
movq %rcx, (%rax)
movq 0x30(%rsp), %rdi
callq 0x1040
movslq 0x3c(%rsp), %rcx
leaq 0x59f6(%rip), %rax      # 0x7160
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl (%rax), %eax
subl 0x2c(%rsp), %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x28(%rsp), %eax
shll %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x10(%rsp)
movslq 0x3c(%rsp), %rcx
leaq 0x59b2(%rip), %rax      # 0x7160
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl (%rax), %eax
shll %eax
cvtsi2sd %eax, %xmm0
callq 0x11a0
movsd 0x8(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x10(%rsp), %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movss 0x50(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x1923
jmp 0x1800
movl 0x40(%rsp), %eax
cmpl 0x44(%rsp), %eax
jg 0x182e
movl 0x40(%rsp), %eax
shll %eax
movl %eax, 0x40(%rsp)
movq 0x48(%rsp), %rdi
movslq 0x40(%rsp), %rsi
shlq $0x4, %rsi
callq 0x1140
movq %rax, 0x48(%rsp)
jmp 0x1800
movslq 0x3c(%rsp), %rcx
leaq 0x5926(%rip), %rax      # 0x7160
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %ecx
movq 0x48(%rsp), %rax
movslq 0x44(%rsp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
movl 0x3c(%rsp), %ecx
movq 0x48(%rsp), %rax
movslq 0x44(%rsp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, 0x4(%rax)
movslq 0x3c(%rsp), %rcx
leaq 0x58d9(%rip), %rax      # 0x7160
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movl (%rax), %ecx
movq 0x48(%rsp), %rax
movslq 0x44(%rsp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
movq 0x48(%rsp), %rax
movslq 0x44(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %ecx
movslq 0x3c(%rsp), %rdx
leaq 0x588b(%rip), %rax      # 0x7160
movq (%rax,%rdx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
subl 0x8(%rax), %ecx
movq 0x48(%rsp), %rax
movslq 0x44(%rsp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, 0xc(%rax)
movq 0x48(%rsp), %rax
movslq 0x44(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
movl %eax, 0x2c(%rsp)
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
cmpl $0x0, 0x2c(%rsp)
je 0x19a4
movl 0x3c(%rsp), %eax
addl $0x1, %eax
cmpl $0x5, %eax
jge 0x19a4
movq 0x58(%rsp), %rdi
movslq 0x3c(%rsp), %rcx
leaq 0x5819(%rip), %rax      # 0x7160
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rax
movslq 0x38(%rsp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl 0x3c(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rdx
leaq 0x5792(%rip), %rcx      # 0x7100
andl (%rcx,%rdx,4), %eax
movl %eax, %eax
movl %eax, %esi
shlq $0x20, %rsi
movl 0x3c(%rsp), %eax
addl $0x1, %eax
cltq
orq %rax, %rsi
movl 0x54(%rsp), %ecx
xorl %edx, %edx
callq 0x2f10
movq %rax, 0x30(%rsp)
movl 0x2c(%rsp), %ecx
movq 0x30(%rsp), %rax
addl 0x8(%rax), %ecx
movl %ecx, 0x8(%rax)
jmp 0x19a6
jmp 0x19a8
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x15fc
jmp 0x19ba
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0x15e9
movq 0x58(%rsp), %rdi
movl 0x54(%rsp), %esi
callq 0x2e80
movq 0x48(%rsp), %rdi
movslq 0x44(%rsp), %rsi
shlq $0x4, %rsi
callq 0x1140
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rdi
movslq 0x44(%rsp), %rsi
movl $0x10, %edx
leaq -0x566(%rip), %rcx      # 0x14a0
callq 0x1060
movl 0x44(%rsp), %ecx
movq 0x68(%rsp), %rax
movl %ecx, (%rax)
movq 0x48(%rsp), %rax
addq $0x78, %rsp
retq