// File: big-data-lab-team[P]OrpailleCC/./src/mondrian_coarse.hpp
// Function: int CoarseMondrianForest<double, funct, KappaMetrics<2, false>, 4, 2, 6000>::adjust_counters<100>(int, int, double, bool, int*)
int adjust_counters(int const start_id, int split_dimension, double split_value, bool discharge_left, int* to_remove){
	//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;


			//Compute size of box
			double const max_value = node.bound_upper[split_dimension] - node.bound_lower[split_dimension];
			//Get the percentage on the left (below the split value)
			double percentage = Utils::min(Utils::max((split_value - node.bound_lower[split_dimension]) / max_value, 0.0), 1.0);
			//If this sub-tree is not on the left, invert percentage
			if(!discharge_left)
				percentage = 1 - percentage;
			for(int i = 0; i < label_count; ++i){
				int counter_out = Utils::round(static_cast<double>(node.counters[i]) * percentage);
				int counter_in = Utils::round(static_cast<double>(node.counters[i]) * (1 - percentage));
				int const err = node.counters[i] - counter_in - counter_out;
				if(err != 0)
					cout << "Error counters" << endl;
				to_remove[i] += counter_out;
				node.counters[i] = counter_in;
			}
			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 $0x210, %rsp            # imm = 0x210
movb %cl, %al
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movsd %xmm0, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
movq %r8, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x200(%rbp)
movl $0x0, -0x1c4(%rbp)
cmpl $0x64, -0x1c4(%rbp)
jge 0x90b6
movslq -0x1c4(%rbp), %rax
movl $0xffffffff, -0x1c0(%rbp,%rax,4) # imm = 0xFFFFFFFF
movl -0x1c4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c4(%rbp)
jmp 0x908a
movl -0x14(%rbp), %eax
movl %eax, -0x1c8(%rbp)
movl $0x0, -0x1cc(%rbp)
movl $0x0, -0x1d0(%rbp)
movq -0x200(%rbp), %rdx
movl -0x1d0(%rbp), %ecx
xorl %eax, %eax
cmpl 0x17d4(%rdx), %ecx
movb %al, -0x201(%rbp)
jge 0x9100
cmpl $0x0, -0x1c8(%rbp)
setge %al
movb %al, -0x201(%rbp)
movb -0x201(%rbp), %al
testb $0x1, %al
jne 0x910f
jmp 0x9423
movq -0x200(%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 0x9239
movslq -0x1cc(%rbp), %rax
cmpl $-0x1, -0x1c0(%rbp,%rax,4)
jne 0x918b
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 0x9234
movslq -0x1cc(%rbp), %rax
cmpl $0x0, -0x1c0(%rbp,%rax,4)
jne 0x91cf
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 0x9232
movslq -0x1cc(%rbp), %rax
cmpl $0x1, -0x1c0(%rbp,%rax,4)
jne 0x9230
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 0x9220
jmp 0x9423
movq -0x1d8(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0x1c8(%rbp)
jmp 0x9232
jmp 0x9234
jmp 0x940c
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)
movq -0x1d8(%rbp), %rax
movslq -0x18(%rbp), %rcx
movsd 0x30(%rax,%rcx,8), %xmm0
movq -0x1d8(%rbp), %rax
movslq -0x18(%rbp), %rcx
subsd 0x10(%rax,%rcx,8), %xmm0
movsd %xmm0, -0x1e0(%rbp)
movsd -0x20(%rbp), %xmm0
movq -0x1d8(%rbp), %rax
movslq -0x18(%rbp), %rcx
subsd 0x10(%rax,%rcx,8), %xmm0
divsd -0x1e0(%rbp), %xmm0
xorps %xmm1, %xmm1
callq 0x2a80
movsd 0x1d57(%rip), %xmm1     # 0xb018
callq 0x8bc0
movsd %xmm0, -0x1e8(%rbp)
testb $0x1, -0x21(%rbp)
jne 0x92ec
movsd 0x1d3c(%rip), %xmm0     # 0xb018
subsd -0x1e8(%rbp), %xmm0
movsd %xmm0, -0x1e8(%rbp)
movl $0x0, -0x1ec(%rbp)
cmpl $0x2, -0x1ec(%rbp)
jge 0x93ef
movq -0x1d8(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
cvtsi2sdl 0x68(%rax,%rcx,4), %xmm0
mulsd -0x1e8(%rbp), %xmm0
callq 0x9d40
movl %eax, -0x1f0(%rbp)
movq -0x1d8(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
cvtsi2sdl 0x68(%rax,%rcx,4), %xmm0
movsd 0x1cd2(%rip), %xmm1     # 0xb018
subsd -0x1e8(%rbp), %xmm1
mulsd %xmm1, %xmm0
callq 0x9d40
movl %eax, -0x1f4(%rbp)
movq -0x1d8(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
movl 0x68(%rax,%rcx,4), %eax
subl -0x1f4(%rbp), %eax
subl -0x1f0(%rbp), %eax
movl %eax, -0x1f8(%rbp)
cmpl $0x0, -0x1f8(%rbp)
je 0x93ac
movq 0x3c47(%rip), %rdi      # 0xcfd8
leaq 0x1caa(%rip), %rsi      # 0xb042
callq 0x1050
movq %rax, %rdi
movq 0x3c21(%rip), %rsi      # 0xcfc8
callq 0x1060
movl -0x1f0(%rbp), %edx
movq -0x30(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
addl (%rax,%rcx,4), %edx
movl %edx, (%rax,%rcx,4)
movl -0x1f4(%rbp), %edx
movq -0x1d8(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
movl %edx, 0x68(%rax,%rcx,4)
movl -0x1ec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1ec(%rbp)
jmp 0x92f6
movl -0x1c8(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0x93fc
jmp 0x9423
movq -0x1d8(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0x1c8(%rbp)
cmpl $0x64, -0x1cc(%rbp)
jl 0x941e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x943c
jmp 0x90d3
cmpl $-0x1, -0x1cc(%rbp)
je 0x9435
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x943c
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
nopl (%rax,%rax)