// File: /workspace/github_cpp_makefile_star2_O3/big-data-lab-team[P]OrpailleCC/./src/mondrian_coarse.hpp
// Function: int CoarseMondrianForest<double, funct, KappaMetrics<2, false>, 4, 2, 6000>::count_sides<100>(int, int, double, int&, int&)
int count_sides(int const start_id, int const split_dimension, double const split_value, int& count_left, int& count_right){
	//Initialize an array to keep track of where we have to go at each tree level.
	//The max depth expected is MAX_DEPTH.
	int stack[max_stack_size];
	for(int i = 0; i < max_stack_size; ++i)
		stack[i] = -1;

	int node_id = start_id;
	int depth = 0;
	//a for loop instead of a while to avoid infinite loops. Since we don't expect to do more turn than node_count
	//*i* count the number of node deleted.
	int i = 0;
	while(i < node_count && node_id >= 0){
		Node& node = nodes()[node_id];
		if(!node.is_leaf()){  //Internal node
			if (stack[depth] == -1){ //Go right
				stack[depth] = 0;
				depth += 1;
				node_id = node.child_right;
			}
			else if (stack[depth] == 0){ //Go left
				stack[depth] = 1;
				depth += 1;
				node_id = node.child_left;
			}
			else if (stack[depth] == 1){ //Go up
				stack[depth] = -1; //Reset to -1
				depth -= 1;
				i += 1;
				if(node_id == start_id)
					break;
				node_id = node.parent;
			}
		}
		else{ //Leaf
			stack[depth] = -1; //Reset to -1
			depth -= 1;
			i += 1;

			int count = 0;
			for(int i = 0; i < label_count; ++i){
				count += node.counters[i];
			}
			double const lower = node.bound_lower[split_dimension];
			double const upper = node.bound_upper[split_dimension];
			if(split_value > lower && split_value < upper){
				double const percent = static_cast<double>(split_value-lower) / static_cast<double>(upper - lower);
				int left = static_cast<int>(static_cast<double>(count) * percent);
				int right = static_cast<int>(static_cast<double>(count) * (1-percent));
				int const err = count - left - right;
				if(err != 0 && func::rand_uniform() < 0.5)
					left += err;
				else if(err != 0)
					right += err;
				count_left += left;
				count_right += right;
			}
			else if(split_value <= lower)
				count_left += count;
			else if(split_value >= upper)
				count_right += count;

			if(node_id == start_id)
				break;
			node_id = node.parent;
		}
		if(depth >= max_stack_size)
			return -1;
	}
	if(depth != -1)
		return -1;
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x1a0, %rsp            # imm = 0x1A0
movq %r8, %rbx
movq %rcx, %r14
movsd %xmm0, 0x8(%rsp)
movl %edx, %r12d
movl %esi, %ebp
movq %rdi, %r15
leaq 0x10(%rsp), %rdi
movl $0x190, %edx            # imm = 0x190
movl $0xff, %esi
callq 0x1040
movl 0x17d4(%r15), %r10d
testl %r10d, %r10d
setle %cl
testl %ebp, %ebp
sets %dl
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
orb %cl, %dl
jne 0x4c01
leaq 0x44(%r15), %rcx
movslq %r12d, %rdx
xorl %edi, %edi
movsd 0x1549(%rip), %xmm0     # 0x6018
movl %ebp, %r8d
xorl %esi, %esi
movsd 0x8(%rsp), %xmm4
movl %r8d, %r11d
shlq $0x7, %r11
leaq (%rcx,%r11), %r9
cmpl $-0x1, (%rcx,%r11)
movslq %edi, %r11
je 0x4b21
movl 0x10(%rsp,%r11,4), %r12d
cmpl $-0x1, %r12d
je 0x4baf
cmpl $0x1, %r12d
je 0x4b94
testl %r12d, %r12d
jne 0x4be9
movl $0x50, %r8d
movl $0x1, %edi
jmp 0x4bb7
movl $0xffffffff, 0x10(%rsp,%r11,4) # imm = 0xFFFFFFFF
movl 0x6c(%r9), %r10d
movsd 0x10(%r9,%rdx,8), %xmm2
movsd 0x30(%r9,%rdx,8), %xmm1
addl 0x68(%r9), %r10d
ucomisd %xmm2, %xmm4
jbe 0x4b83
ucomisd %xmm4, %xmm1
jbe 0x4b83
movapd %xmm4, %xmm3
subsd %xmm2, %xmm3
subsd %xmm2, %xmm1
divsd %xmm1, %xmm3
movapd %xmm0, %xmm1
xorps %xmm2, %xmm2
cvtsi2sd %r10d, %xmm2
subsd %xmm3, %xmm1
mulsd %xmm1, %xmm2
cvttsd2si %xmm2, %r12d
subl %r12d, %r10d
addl %r10d, (%r14)
movq %rbx, %r11
movl %r12d, %r10d
jmp 0x4bc7
ucomisd %xmm4, %xmm2
jae 0x4bc4
ucomisd %xmm1, %xmm4
movq %rbx, %r11
jae 0x4bc7
jmp 0x4bca
movl $0xffffffff, 0x10(%rsp,%r11,4) # imm = 0xFFFFFFFF
movl %r11d, %edi
decl %edi
cmpl %ebp, %r8d
je 0x4bf7
incl %esi
movl 0x58(%r9), %r8d
jmp 0x4be9
movl $0x54, %r8d
xorl %edi, %edi
movl %edi, 0x10(%rsp,%r11,4)
incl %r11d
movl %r11d, %edi
jmp 0x4bd9
movq %r14, %r11
addl %r10d, (%r11)
decl %edi
cmpl %ebp, %r8d
je 0x4bf7
incl %esi
movl $0x58, %r8d
cmpl $0x63, %edi
jg 0x4c01
movl (%r9,%r8), %r8d
movl 0x17d4(%r15), %r10d
cmpl %r10d, %esi
jge 0x4bf7
testl %r8d, %r8d
jns 0x4ada
xorl %eax, %eax
cmpl $-0x1, %edi
setne %al
negl %eax
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop