// File: /workspace/github_cpp_makefile_star2_O2/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 %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
xorl %eax, %eax
cmpq $0x64, %rax
je 0x44e5
orl $-0x1, -0x80(%rsp,%rax,4)
incq %rax
jmp 0x44d5
leaq 0x44(%rdi), %r9
movslq %edx, %rdx
xorl %r10d, %r10d
movsd 0x1b21(%rip), %xmm1     # 0x6018
movabsq $0x58, %r11
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %r15d, %r15d
movl %esi, %r13d
cmpl 0x17d4(%rdi), %r10d
setl %bl
testl %r13d, %r13d
setns %r14b
andb %bl, %r14b
movl %r13d, %r12d
shlq $0x7, %r12
addq %r9, %r12
movslq %r15d, %rbx
testb %r14b, %r14b
je 0x462e
cmpl $-0x1, (%r12)
je 0x4577
movl -0x80(%rsp,%rbx,4), %ebp
cmpl $-0x1, %ebp
je 0x45cf
testl %ebp, %ebp
je 0x45dd
cmpl $0x1, %ebp
jne 0x452d
orl $-0x1, -0x80(%rsp,%rbx,4)
movl %ebx, %r15d
decl %r15d
cmpl %esi, %r13d
je 0x462e
incl %r10d
addq $0x58, %r12
jmp 0x4625
orl $-0x1, -0x80(%rsp,%rbx,4)
movl 0x6c(%r12), %ebx
movsd 0x10(%r12,%rdx,8), %xmm3
movsd 0x30(%r12,%rdx,8), %xmm2
addl 0x68(%r12), %ebx
ucomisd %xmm3, %xmm0
jbe 0x45f7
ucomisd %xmm0, %xmm2
jbe 0x45f7
movapd %xmm0, %xmm4
subsd %xmm3, %xmm4
subsd %xmm3, %xmm2
divsd %xmm2, %xmm4
movapd %xmm1, %xmm2
cvtsi2sd %ebx, %xmm3
subsd %xmm4, %xmm2
mulsd %xmm2, %xmm3
cvttsd2si %xmm3, %ebp
subl %ebp, %ebx
addl %ebx, (%rcx)
movq %r8, %r14
movl %ebp, %ebx
jmp 0x460b
xorl %ebp, %ebp
movabsq $0x54, %r14
jmp 0x45ec
movl $0x1, %ebp
movabsq $0x50, %r14
movl %ebp, -0x80(%rsp,%rbx,4)
incl %ebx
movl %ebx, %r15d
jmp 0x461c
ucomisd %xmm0, %xmm3
jae 0x4608
ucomisd %xmm2, %xmm0
movq %r8, %r14
jae 0x460b
jmp 0x460e
movq %rcx, %r14
addl %ebx, (%r14)
decl %r15d
cmpl %esi, %r13d
je 0x462e
incl %r10d
movq %r11, %r14
cmpl $0x63, %r15d
jg 0x4639
addq %r14, %r12
movl (%r12), %r13d
jmp 0x450c
xorl %eax, %eax
cmpl $-0x1, %r15d
setne %al
negl %eax
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop