// File: big-data-lab-team[P]OrpailleCC/./src/mondrian_coarse.hpp
// Function: CoarseMondrianForest<double, funct, KappaMetrics<2, false>, 4, 2, 6000>::train_tree(double const*, int, int)
bool train_tree(feature_type const* features, int const label, int const tree_id){
	int root_id;
	TreeBase& base = tree_bases()[tree_id];
	bool ret = true;
#ifdef DEBUG
	cout << "Training Tree " << tree_id << endl;
#endif
	if (base.is_empty()){ //The root of the tree does not exist yet
		//Pick a new node
		root_id = available_node();
		if(root_id >= 0){
			//Initialize this node as the root for this tree
			tree_bases()[tree_id].root = root_id;
			Node& root = nodes()[root_id];
			///TODO to change in order to separate node from forest
			root.parent = -1;
			root.child_right = -1;
			root.child_left = -1;
			root.tau = 0;

			node_available -= 1;

			//Sample the root with the new data point
			sample_block(root_id, features, label);
			base.statistics.increase_error();
		}
		else{
			ret = false;
		}
	}
	else{ //Partial fit
		root_id = base.root;
		//add the sum of forced_extend, or the total_count
		int summy = 0;
		if(fe_split_trigger == SPLIT_TRIGGER_TOTAL)
			summy = total_count;
		else if(fe_split_trigger == SPLIT_TRIGGER_SFE)
			summy = count_fe_down(base.root, features);

		if(extend_type == EXTEND_ORIGINAL)
			extend_block0(root_id, tree_id, features, label);
		else if(extend_type == EXTEND_NONE && node_available <= 2)
			ret = false;
		else if(extend_type == EXTEND_PARTIAL_UPDATE)
			extend_block2(root_id, tree_id, features, label);
		else if(extend_type == EXTEND_GHOST)
			extend_block1(root_id, tree_id, features, label);
		else if(extend_type == EXTEND_COUNTER_NO_UPDATE)
			extend_block3(root_id, tree_id, features, label);
		else if(extend_type == EXTEND_BARYCENTER)
			extend_block4(root_id, tree_id, features, label, summy);
	}
	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x48(%rbp)
callq 0x1a50
movslq -0x18(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movb $0x1, -0x29(%rbp)
movq -0x28(%rbp), %rdi
callq 0x28d0
testb $0x1, %al
jne 0x1ff8
jmp 0x20b2
movq -0x48(%rbp), %rdi
callq 0x3860
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jl 0x20a9
movq -0x48(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, -0x4c(%rbp)
callq 0x1a50
movl -0x4c(%rbp), %ecx
movq -0x48(%rbp), %rdi
movslq -0x18(%rbp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
callq 0x1b00
movq -0x48(%rbp), %rdi
movslq -0x1c(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movl $0xffffffff, 0x58(%rax) # imm = 0xFFFFFFFF
movq -0x38(%rbp), %rax
movl $0xffffffff, 0x54(%rax) # imm = 0xFFFFFFFF
movq -0x38(%rbp), %rax
movl $0xffffffff, 0x50(%rax) # imm = 0xFFFFFFFF
movq -0x38(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x60(%rax)
movl 0x17d8(%rdi), %eax
subl $0x1, %eax
movl %eax, 0x17d8(%rdi)
movl -0x1c(%rbp), %esi
movq -0x10(%rbp), %rdx
movl -0x14(%rbp), %ecx
callq 0x3900
movq -0x28(%rbp), %rdi
addq $0x20, %rdi
movl $0x1, %esi
callq 0x39b0
jmp 0x20ad
movb $0x0, -0x29(%rbp)
jmp 0x21df
movq -0x48(%rbp), %rax
movq -0x28(%rbp), %rcx
movl 0x8(%rcx), %ecx
movl %ecx, -0x1c(%rbp)
movl $0x0, -0x3c(%rbp)
cmpl $0x2, 0x18(%rax)
jne 0x20dc
movq -0x48(%rbp), %rax
movl 0x17b4(%rax), %eax
movl %eax, -0x3c(%rbp)
jmp 0x20ff
movq -0x48(%rbp), %rax
cmpl $0x3, 0x18(%rax)
jne 0x20fd
movq -0x48(%rbp), %rdi
movq -0x28(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x10(%rbp), %rdx
callq 0x39e0
movl %eax, -0x3c(%rbp)
jmp 0x20ff
movq -0x48(%rbp), %rax
cmpl $0x1, 0x3c(%rax)
jne 0x2125
movq -0x48(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x18(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
callq 0x3aa0
jmp 0x21dd
movq -0x48(%rbp), %rax
cmpl $0x0, 0x3c(%rax)
jne 0x2145
movq -0x48(%rbp), %rax
cmpl $0x2, 0x17d8(%rax)
jg 0x2145
movb $0x0, -0x29(%rbp)
jmp 0x21db
movq -0x48(%rbp), %rax
cmpl $0x3, 0x3c(%rax)
jne 0x2168
movq -0x48(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x18(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
callq 0x4620
jmp 0x21d9
movq -0x48(%rbp), %rax
cmpl $0x2, 0x3c(%rax)
jne 0x218b
movq -0x48(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x18(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
callq 0x5160
jmp 0x21d7
movq -0x48(%rbp), %rax
cmpl $0x4, 0x3c(%rax)
jne 0x21ae
movq -0x48(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x18(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
callq 0x5d70
jmp 0x21d5
movq -0x48(%rbp), %rax
cmpl $0x5, 0x3c(%rax)
jne 0x21d3
movq -0x48(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x18(%rbp), %edx
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %r8d
movl -0x3c(%rbp), %r9d
callq 0x68b0
jmp 0x21d5
jmp 0x21d7
jmp 0x21d9
jmp 0x21db
jmp 0x21dd
jmp 0x21df
movb -0x29(%rbp), %al
andb $0x1, %al
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)