// File: 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
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movsd %xmm0, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x210(%rbp)
movl $0x0, -0x1c4(%rbp)
cmpl $0x64, -0x1c4(%rbp)
jge 0x8c63
movslq -0x1c4(%rbp), %rax
movl $0xffffffff, -0x1c0(%rbp,%rax,4) # imm = 0xFFFFFFFF
movl -0x1c4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c4(%rbp)
jmp 0x8c37
movl -0x14(%rbp), %eax
movl %eax, -0x1c8(%rbp)
movl $0x0, -0x1cc(%rbp)
movl $0x0, -0x1d0(%rbp)
movq -0x210(%rbp), %rdx
movl -0x1d0(%rbp), %ecx
xorl %eax, %eax
cmpl 0x17d4(%rdx), %ecx
movb %al, -0x211(%rbp)
jge 0x8cad
cmpl $0x0, -0x1c8(%rbp)
setge %al
movb %al, -0x211(%rbp)
movb -0x211(%rbp), %al
testb $0x1, %al
jne 0x8cbc
jmp 0x9025
movq -0x210(%rbp), %rdi
callq 0x1b00
movslq -0x1c8(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movq %rax, -0x1d8(%rbp)
movq -0x1d8(%rbp), %rdi
callq 0x29e0
testb $0x1, %al
jne 0x8de6
movslq -0x1cc(%rbp), %rax
cmpl $-0x1, -0x1c0(%rbp,%rax,4)
jne 0x8d38
movslq -0x1cc(%rbp), %rax
movl $0x0, -0x1c0(%rbp,%rax,4)
movl -0x1cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1cc(%rbp)
movq -0x1d8(%rbp), %rax
movl 0x54(%rax), %eax
movl %eax, -0x1c8(%rbp)
jmp 0x8de1
movslq -0x1cc(%rbp), %rax
cmpl $0x0, -0x1c0(%rbp,%rax,4)
jne 0x8d7c
movslq -0x1cc(%rbp), %rax
movl $0x1, -0x1c0(%rbp,%rax,4)
movl -0x1cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1cc(%rbp)
movq -0x1d8(%rbp), %rax
movl 0x50(%rax), %eax
movl %eax, -0x1c8(%rbp)
jmp 0x8ddf
movslq -0x1cc(%rbp), %rax
cmpl $0x1, -0x1c0(%rbp,%rax,4)
jne 0x8ddd
movslq -0x1cc(%rbp), %rax
movl $0xffffffff, -0x1c0(%rbp,%rax,4) # imm = 0xFFFFFFFF
movl -0x1cc(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x1cc(%rbp)
movl -0x1d0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1d0(%rbp)
movl -0x1c8(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0x8dcd
jmp 0x9025
movq -0x1d8(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0x1c8(%rbp)
jmp 0x8ddf
jmp 0x8de1
jmp 0x900e
movslq -0x1cc(%rbp), %rax
movl $0xffffffff, -0x1c0(%rbp,%rax,4) # imm = 0xFFFFFFFF
movl -0x1cc(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x1cc(%rbp)
movl -0x1d0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1d0(%rbp)
movl $0x0, -0x1dc(%rbp)
movl $0x0, -0x1e0(%rbp)
cmpl $0x2, -0x1e0(%rbp)
jge 0x8e62
movq -0x1d8(%rbp), %rax
movslq -0x1e0(%rbp), %rcx
movl 0x68(%rax,%rcx,4), %eax
addl -0x1dc(%rbp), %eax
movl %eax, -0x1dc(%rbp)
movl -0x1e0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1e0(%rbp)
jmp 0x8e2a
movq -0x1d8(%rbp), %rax
movslq -0x18(%rbp), %rcx
movsd 0x10(%rax,%rcx,8), %xmm0
movsd %xmm0, -0x1e8(%rbp)
movq -0x1d8(%rbp), %rax
movslq -0x18(%rbp), %rcx
movsd 0x30(%rax,%rcx,8), %xmm0
movsd %xmm0, -0x1f0(%rbp)
movsd -0x20(%rbp), %xmm0
ucomisd -0x1e8(%rbp), %xmm0
jbe 0x8fad
movsd -0x20(%rbp), %xmm1
movsd -0x1f0(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x8fad
movsd -0x20(%rbp), %xmm0
subsd -0x1e8(%rbp), %xmm0
movsd -0x1f0(%rbp), %xmm1
subsd -0x1e8(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x1f8(%rbp)
cvtsi2sdl -0x1dc(%rbp), %xmm0
mulsd -0x1f8(%rbp), %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x1fc(%rbp)
cvtsi2sdl -0x1dc(%rbp), %xmm0
movsd 0x2107(%rip), %xmm1     # 0xb018
subsd -0x1f8(%rbp), %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x200(%rbp)
movl -0x1dc(%rbp), %eax
subl -0x1fc(%rbp), %eax
subl -0x200(%rbp), %eax
movl %eax, -0x204(%rbp)
cmpl $0x0, -0x204(%rbp)
je 0x8f72
callq 0x35a0
movaps %xmm0, %xmm1
movsd 0x20d8(%rip), %xmm0     # 0xb030
ucomisd %xmm1, %xmm0
jbe 0x8f72
movl -0x204(%rbp), %eax
addl -0x1fc(%rbp), %eax
movl %eax, -0x1fc(%rbp)
jmp 0x8f8f
cmpl $0x0, -0x204(%rbp)
je 0x8f8d
movl -0x204(%rbp), %eax
addl -0x200(%rbp), %eax
movl %eax, -0x200(%rbp)
jmp 0x8f8f
movl -0x1fc(%rbp), %ecx
movq -0x28(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
movl -0x200(%rbp), %ecx
movq -0x30(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
jmp 0x8ff1
movsd -0x20(%rbp), %xmm1
movsd -0x1e8(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x8fd0
movl -0x1dc(%rbp), %ecx
movq -0x28(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
jmp 0x8fef
movsd -0x20(%rbp), %xmm0
ucomisd -0x1f0(%rbp), %xmm0
jb 0x8fed
movl -0x1dc(%rbp), %ecx
movq -0x30(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
jmp 0x8fef
jmp 0x8ff1
movl -0x1c8(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0x8ffe
jmp 0x9025
movq -0x1d8(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0x1c8(%rbp)
cmpl $0x64, -0x1cc(%rbp)
jl 0x9020
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x903e
jmp 0x8c80
cmpl $-0x1, -0x1cc(%rbp)
je 0x9037
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x903e
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq
nopw (%rax,%rax)