// File: /workspace/github_cpp_makefile_star2_O2/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, %r9
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, %r14
movl 0x8(%r14,%rbp), %r13d
cmpl $-0x1, %r13d
je 0x19d9
movl %ecx, %r12d
movl 0x18(%r15), %ecx
cmpl $0x3, %ecx
je 0x1a4b
xorl %eax, %eax
cmpl $0x2, %ecx
jne 0x1a65
movl (%rbx), %eax
jmp 0x1a65
movq %r9, %r13
movl %r8d, %r12d
movq %r15, %rdi
callq 0x2378
testl %eax, %eax
js 0x1a94
movslq 0x17dc(%r15), %rcx
imulq $-0x38, %rcx, %rcx
addq %rcx, %rbx
movl %eax, 0x8(%r14,%rbx)
movl %eax, %ecx
shlq $0x7, %rcx
orl $-0x1, 0x9c(%r15,%rcx)
orq $-0x1, 0x94(%r15,%rcx)
andq $0x0, 0xa4(%r15,%rcx)
addq %r14, %rbp
decl 0x17d8(%r15)
movq %r15, %rdi
movl %eax, %esi
movq %r13, %rdx
movl %r12d, %ecx
callq 0x23cc
incl 0x24(%rbp)
incl 0x30(%rbp)
movb $0x1, %bpl
jmp 0x1af8
movq %r15, %rdi
movl %r13d, %esi
movq %r9, %rdx
movl %r8d, %ebx
movq %r9, %r14
callq 0x240e
movq %r14, %r9
movl %ebx, %r8d
movl 0x3c(%r15), %ecx
movb $0x1, %bpl
cmpq $0x5, %rcx
ja 0x1af8
leaq 0x4603(%rip), %rdx      # 0x6080
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
cmpl $0x3, 0x17d8(%r15)
setge %bpl
jmp 0x1af8
xorl %ebp, %ebp
jmp 0x1af8
movq %r15, %rdi
movl %r13d, %esi
movl %r12d, %edx
movq %r9, %rcx
callq 0x30fe
jmp 0x1af8
movq %r15, %rdi
movl %r13d, %esi
movl %r12d, %edx
movq %r9, %rcx
callq 0x2cb0
jmp 0x1af8
movq %r15, %rdi
movl %r13d, %esi
movl %r12d, %edx
movq %r9, %rcx
callq 0x2882
jmp 0x1af8
movq %r15, %rdi
movl %r13d, %esi
movl %r12d, %edx
movq %r9, %rcx
callq 0x2444
jmp 0x1af8
movq %r15, %rdi
movl %r13d, %esi
movl %r12d, %edx
movq %r9, %rcx
movl %eax, %r9d
callq 0x352e
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop