// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %r8d
movq %rsi, %r14
movq %rdi, %r15
leaq 0x17b4(%rdi), %rbx
movslq 0x17dc(%rdi), %rax
imulq $-0x38, %rax, %rax
leaq (%rdi,%rax), %rbp
addq $0x17b4, %rbp           # imm = 0x17B4
movslq %ecx, %rax
imulq $0x38, %rax, %r12
movl 0x8(%r12,%rbp), %r13d
cmpl $-0x1, %r13d
je 0x1b82
movl 0x18(%r15), %edx
cmpl $0x3, %edx
je 0x1c16
xorl %eax, %eax
cmpl $0x2, %edx
jne 0x1c2e
movl (%rbx), %eax
jmp 0x1c2e
movl %r8d, %r13d
movq %r15, %rdi
callq 0x26e4
testl %eax, %eax
js 0x1c59
addq %r12, %rbp
movslq 0x17dc(%r15), %rcx
imulq $-0x38, %rcx, %rcx
addq %rcx, %rbx
movl %eax, 0x8(%r12,%rbx)
movl %eax, %eax
shlq $0x7, %rax
addq %r15, %rax
addq $0x44, %rax
movl $0xffffffff, 0x58(%rax) # imm = 0xFFFFFFFF
movq $-0x1, 0x50(%rax)
movq $0x0, 0x60(%rax)
decl 0x17d8(%r15)
xorl %ecx, %ecx
movsd (%r14,%rcx,8), %xmm0
movsd %xmm0, 0x10(%rax,%rcx,8)
movsd %xmm0, 0x30(%rax,%rcx,8)
incq %rcx
cmpq $0x4, %rcx
jne 0x1bd8
movslq %r13d, %rcx
incl 0x68(%rax,%rcx,4)
movsd 0x17e8(%r15), %xmm0
movsd %xmm0, 0x60(%rax)
incl 0x24(%rbp)
incl 0x30(%rbp)
movb $0x1, %bpl
jmp 0x1cb8
movq %r15, %rdi
movl %r13d, %esi
movq %r14, %rdx
movl %r8d, %ebx
movl %ecx, %ebp
callq 0x273a
movl %ebp, %ecx
movl %ebx, %r8d
movl 0x3c(%r15), %esi
movb $0x1, %bpl
cmpq $0x5, %rsi
ja 0x1cb8
leaq 0x447e(%rip), %rdx      # 0x60c0
movslq (%rdx,%rsi,4), %rsi
addq %rdx, %rsi
jmpq *%rsi
cmpl $0x3, 0x17d8(%r15)
setge %bpl
jmp 0x1cb8
xorl %ebp, %ebp
jmp 0x1cb8
movq %r15, %rdi
movl %r13d, %esi
movl %ecx, %edx
movq %r14, %rcx
callq 0x35a6
jmp 0x1cb8
movq %r15, %rdi
movl %r13d, %esi
movl %ecx, %edx
movq %r14, %rcx
callq 0x30f4
jmp 0x1cb8
movq %r15, %rdi
movl %r13d, %esi
movl %ecx, %edx
movq %r14, %rcx
callq 0x2c50
jmp 0x1cb8
movq %r15, %rdi
movl %r13d, %esi
movl %ecx, %edx
movq %r14, %rcx
callq 0x279a
jmp 0x1cb8
movq %r15, %rdi
movl %r13d, %esi
movl %ecx, %edx
movq %r14, %rcx
movl %eax, %r9d
callq 0x3a44
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop