// File: /workspace/github_cpp_makefile_star2_O1/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
movsd 0x8(%rsp), %xmm4
leaq 0x44(%r15), %rax
movslq %r12d, %rcx
xorl %edx, %edx
movsd 0x1606(%rip), %xmm0     # 0x6018
xorl %edi, %edi
movl %ebp, %esi
cmpl 0x17d4(%r15), %edx
jge 0x4b6e
testl %esi, %esi
js 0x4b6e
movl %esi, %r9d
shlq $0x7, %r9
leaq (%rax,%r9), %r8
cmpl $-0x1, (%rax,%r9)
movslq %edi, %r9
je 0x4a72
movl 0x10(%rsp,%r9,4), %r10d
cmpl $-0x1, %r10d
je 0x4b19
cmpl $0x1, %r10d
je 0x4af6
testl %r10d, %r10d
jne 0x4b55
movl $0x50, %r11d
movl $0x1, %esi
jmp 0x4b21
movl $0xffffffff, 0x10(%rsp,%r9,4) # imm = 0xFFFFFFFF
movl %r9d, %edi
decl %edi
xorl %r10d, %r10d
xorl %r9d, %r9d
addl 0x68(%r8,%r10,4), %r9d
incq %r10
cmpq $0x1, %r10
je 0x4a86
movsd 0x10(%r8,%rcx,8), %xmm2
movsd 0x30(%r8,%rcx,8), %xmm1
ucomisd %xmm2, %xmm4
jbe 0x4ae5
ucomisd %xmm4, %xmm1
jbe 0x4ae5
movapd %xmm4, %xmm3
subsd %xmm2, %xmm3
subsd %xmm2, %xmm1
divsd %xmm1, %xmm3
movapd %xmm0, %xmm1
xorps %xmm2, %xmm2
cvtsi2sd %r9d, %xmm2
subsd %xmm3, %xmm1
mulsd %xmm1, %xmm2
cvttsd2si %xmm2, %r11d
subl %r11d, %r9d
addl %r9d, (%r14)
movq %rbx, %r10
movl %r11d, %r9d
jmp 0x4b35
ucomisd %xmm4, %xmm2
jae 0x4b32
ucomisd %xmm1, %xmm4
movq %rbx, %r10
jae 0x4b35
jmp 0x4b38
movl $0xffffffff, 0x10(%rsp,%r9,4) # imm = 0xFFFFFFFF
decl %r9d
incl %edx
movl $0x58, %r11d
movl $0x6, %r10d
movl %r9d, %edi
cmpl %ebp, %esi
jne 0x4b29
jmp 0x4b5f
movl $0x54, %r11d
xorl %esi, %esi
movl %esi, 0x10(%rsp,%r9,4)
incl %r9d
movl (%r8,%r11), %esi
movl %r9d, %edi
jmp 0x4b55
movq %r14, %r10
addl %r9d, (%r10)
movl $0x6, %r10d
movl %esi, %r9d
cmpl %ebp, %esi
je 0x4b4c
movl 0x58(%r8), %r9d
xorl %r10d, %r10d
incl %edx
cmpl %ebp, %esi
movl %r9d, %esi
je 0x4b5f
xorl %r10d, %r10d
cmpl $0x64, %edi
setge %r10b
testl %r10d, %r10d
je 0x4a16
cmpl $0x6, %r10d
jne 0x4b7a
xorl %eax, %eax
cmpl $-0x1, %edi
setne %al
negl %eax
jmp 0x4b7f
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop