// File: CK7[P]abawaca/src/ClusterSeparatorSplitScafs.cpp
// Function: ClusterSeparatorSplitScafs::separate_dimension(unsigned long)
void ClusterSeparatorSplitScafs::separate_dimension(size_t dimension_index)
{
	semaphore.wait();
	const Dimension& dimension = clustering_db.get_dimension(dimension_index);
	const set<double>& values = dimension.get_values();
	int values_checked = 0;

	// Initialize - curr_cluster1 will have no points while curr_cluster2 will have all dps
	Cluster 					curr_cluster1(scaf_db);
	Cluster 					curr_cluster2(scaf_db);
	ClusterSeparatorSplitScafs::IsScafIn		in_operator(fraction_dps_to_be_considered_in);
	ClusterSeparatorSplitScafs::ClusterStats	curr_cluster_stats1(curr_cluster1, scaf_db, in_operator);
	ClusterSeparatorSplitScafs::ClusterStats	curr_cluster_stats2(curr_cluster2, scaf_db, in_operator);
	vector<Dimension::DataPoint>			dps;

	set<size_t> useful_scafs;
	for(vector<Dimension::DataPoint>::const_iterator vit = dimension.begin(); vit!=dimension.end(); vit++) {
		curr_cluster_stats2 += vit->dp;
		dps.push_back(*vit);
		if(scaf_db.ndps(scaf_db.dp2scaf(vit->dp)) > 1)
			useful_scafs.insert(scaf_db.dp2scaf(vit->dp));
	}

	if(curr_cluster_stats2.num_scafs_in_this_cluster() != useful_scafs.size()) {
			cerr << "Error: # useful scafs=" << useful_scafs.size() << " but in cluster 2: " << curr_cluster_stats2.num_scafs_in_this_cluster() << endl;
		semaphore.notify();
		return;
	}
	sort(dps.begin(), dps.end(), comp_by_value);
	ClusterSeparatorSplitScafs::ClusteringResult	best_dimension_separation;

	for(auto vit=dps.begin(); vit!=dps.end();) {
		double value = vit->value;
		while(vit!=dps.end() && vit->value==value) {
			curr_cluster_stats1 += vit->dp;
			curr_cluster_stats2 -= vit->dp;
			vit++;
		}

		// Now do what we actually need to do in this specific class
		this->separate_specific(curr_cluster_stats1, curr_cluster_stats2, dimension_index, value, useful_scafs.size(), best_dimension_separation);
	}

	// Only a single access to the variables common to all threads
	unique_lock<mutex> lck(update_mtx);
	if(best_dimension_separation.is_better(*best_separation))
		best_separation->copy(best_dimension_separation);

	semaphore.notify();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x370, %rsp            # imm = 0x370
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x2d0(%rbp)
movq 0xe0(%rax), %rdi
callq 0x28420
movq -0x2d0(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x1e9d0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x28480
movq %rax, %rcx
movq -0x2d0(%rbp), %rax
movq %rcx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq 0x8(%rax), %rsi
leaq -0xc8(%rbp), %rdi
callq 0xac40
movq -0x2d0(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x168(%rbp), %rdi
callq 0xac40
jmp 0x2ae99
movq -0x2d0(%rbp), %rax
movsd 0xe8(%rax), %xmm0
leaq -0x180(%rbp), %rdi
callq 0x2b890
jmp 0x2aeb6
movq -0x2d0(%rbp), %rax
movq 0x8(%rax), %rdx
leaq -0x1a8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
leaq -0x180(%rbp), %rcx
callq 0x2b8b0
jmp 0x2aedd
movq -0x2d0(%rbp), %rax
movq 0x8(%rax), %rdx
leaq -0x1d0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
leaq -0x180(%rbp), %rcx
callq 0x2b8b0
jmp 0x2af04
leaq -0x1e8(%rbp), %rdi
callq 0x1cca0
leaq -0x218(%rbp), %rdi
callq 0xefa0
movq -0x18(%rbp), %rdi
callq 0x24aa0
movq %rax, -0x2d8(%rbp)
jmp 0x2af2e
movq -0x2d8(%rbp), %rax
movq %rax, -0x220(%rbp)
movq -0x18(%rbp), %rdi
callq 0x24b10
movq %rax, -0x2e0(%rbp)
jmp 0x2af4e
movq -0x2e0(%rbp), %rax
movq %rax, -0x228(%rbp)
leaq -0x220(%rbp), %rdi
leaq -0x228(%rbp), %rsi
callq 0x24ad0
testb $0x1, %al
jne 0x2af78
jmp 0x2b0f8
leaq -0x220(%rbp), %rdi
callq 0x24b40
movq (%rax), %rsi
leaq -0x1d0(%rbp), %rdi
callq 0x2a8c0
jmp 0x2af95
leaq -0x220(%rbp), %rdi
callq 0x28560
movq %rax, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x284f0
jmp 0x2afb2
movq -0x2d0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x2f0(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x24b40
movq -0x2f0(%rbp), %rdi
movq (%rax), %rsi
callq 0x13a40
movq %rax, -0x2e8(%rbp)
jmp 0x2afe8
movq -0x2e8(%rbp), %rsi
movq -0x2f0(%rbp), %rdi
callq 0x13b50
movq %rax, -0x2f8(%rbp)
jmp 0x2b004
movq -0x2f8(%rbp), %rax
cmpq $0x1, %rax
jbe 0x2b0dc
movq -0x2d0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x308(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x24b40
movq -0x308(%rbp), %rdi
movq (%rax), %rsi
callq 0x13a40
movq %rax, -0x300(%rbp)
jmp 0x2b04b
movq -0x300(%rbp), %rax
movq %rax, -0x230(%rbp)
leaq -0x218(%rbp), %rdi
leaq -0x230(%rbp), %rsi
callq 0x28580
movb %dl, -0x311(%rbp)
movq %rax, -0x310(%rbp)
jmp 0x2b07b
movb -0x311(%rbp), %al
movq -0x310(%rbp), %rcx
movq %rcx, -0x240(%rbp)
movb %al, -0x238(%rbp)
jmp 0x2b0dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x2b4e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x2b4d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
jmp 0x2b4bf
jmp 0x2b0de
leaq -0x220(%rbp), %rdi
xorl %esi, %esi
callq 0x24b60
movq %rax, -0x248(%rbp)
jmp 0x2af3c
leaq -0x1d0(%rbp), %rdi
callq 0x2b900
movl %eax, -0x318(%rbp)
jmp 0x2b10c
movl -0x318(%rbp), %eax
cltq
movq %rax, -0x320(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x2b920
movq %rax, %rcx
movq -0x320(%rbp), %rax
cmpq %rcx, %rax
je 0x2b1fe
movq 0x21ea7(%rip), %rdi     # 0x4cfe8
leaq 0xb273(%rip), %rsi      # 0x363bb
callq 0x53f0
movq %rax, -0x328(%rbp)
jmp 0x2b156
leaq -0x218(%rbp), %rdi
callq 0x2b920
movq -0x328(%rbp), %rdi
movq %rax, %rsi
callq 0x50f0
movq %rax, -0x330(%rbp)
jmp 0x2b17a
movq -0x330(%rbp), %rdi
leaq 0xb24a(%rip), %rsi      # 0x363d2
callq 0x53f0
movq %rax, -0x338(%rbp)
jmp 0x2b196
leaq -0x1d0(%rbp), %rdi
callq 0x2b900
movl %eax, -0x33c(%rbp)
jmp 0x2b1aa
movl -0x33c(%rbp), %esi
movq -0x338(%rbp), %rdi
callq 0x5710
movq %rax, -0x348(%rbp)
jmp 0x2b1c5
movq -0x348(%rbp), %rdi
movq 0x21dbd(%rip), %rsi     # 0x4cf90
callq 0x5440
jmp 0x2b1da
movq -0x2d0(%rbp), %rax
movq 0xe0(%rax), %rdi
callq 0x28720
jmp 0x2b1ef
movl $0x1, -0x24c(%rbp)
jmp 0x2b486
leaq -0x1e8(%rbp), %rdi
movq %rdi, -0x350(%rbp)
callq 0x1e270
movq -0x350(%rbp), %rdi
movq %rax, -0x258(%rbp)
callq 0x1e0f0
movq %rax, -0x260(%rbp)
movq -0x258(%rbp), %rdi
movq -0x260(%rbp), %rsi
leaq -0x5a80(%rip), %rdx     # 0x257c0
callq 0x285d0
jmp 0x2b247
leaq -0x290(%rbp), %rdi
callq 0x2b940
jmp 0x2b255
leaq -0x1e8(%rbp), %rdi
callq 0x1e270
movq %rax, -0x298(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x1e0f0
movq %rax, -0x2a0(%rbp)
leaq -0x298(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
callq 0x28620
testb $0x1, %al
jne 0x2b297
jmp 0x2b3cf
leaq -0x298(%rbp), %rdi
callq 0x28660
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x2a8(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x1e0f0
movq %rax, -0x2b0(%rbp)
leaq -0x298(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0x28620
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x351(%rbp)
jne 0x2b2e7
jmp 0x2b30e
leaq -0x298(%rbp), %rdi
callq 0x28660
movsd 0x8(%rax), %xmm0
ucomisd -0x2a8(%rbp), %xmm0
sete %al
setnp %cl
andb %cl, %al
movb %al, -0x351(%rbp)
movb -0x351(%rbp), %al
testb $0x1, %al
jne 0x2b31a
jmp 0x2b36e
leaq -0x298(%rbp), %rdi
callq 0x28660
movq (%rax), %rsi
leaq -0x1a8(%rbp), %rdi
callq 0x2a8c0
jmp 0x2b337
leaq -0x298(%rbp), %rdi
callq 0x28660
movq (%rax), %rsi
leaq -0x1d0(%rbp), %rdi
callq 0x2aa90
jmp 0x2b354
leaq -0x298(%rbp), %rdi
xorl %esi, %esi
callq 0x286a0
movq %rax, -0x2b8(%rbp)
jmp 0x2b2b0
movq -0x10(%rbp), %rax
movq %rax, -0x368(%rbp)
movsd -0x2a8(%rbp), %xmm0
movsd %xmm0, -0x360(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x2b920
movq -0x2d0(%rbp), %rdi
movq -0x368(%rbp), %rcx
movsd -0x360(%rbp), %xmm0
movq %rax, %r8
leaq -0x1a8(%rbp), %rsi
leaq -0x1d0(%rbp), %rdx
leaq -0x290(%rbp), %r9
callq 0x2b500
jmp 0x2b3ca
jmp 0x2b268
movq -0x2d0(%rbp), %rsi
addq $0xb8, %rsi
leaq -0x2c8(%rbp), %rdi
callq 0x286e0
jmp 0x2b3eb
movq -0x2d0(%rbp), %rax
movq 0xa8(%rax), %rsi
leaq -0x290(%rbp), %rdi
callq 0x2b9a0
movb %al, -0x369(%rbp)
jmp 0x2b40d
movb -0x369(%rbp), %al
testb $0x1, %al
jne 0x2b419
jmp 0x2b45b
movq -0x2d0(%rbp), %rax
movq 0xa8(%rax), %rdi
movq (%rdi), %rax
movq 0x8(%rax), %rax
leaq -0x290(%rbp), %rsi
callq *%rax
jmp 0x2b439
jmp 0x2b45b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x170(%rbp)
movl %eax, -0x174(%rbp)
leaq -0x2c8(%rbp), %rdi
callq 0x28770
jmp 0x2b4bf
movq -0x2d0(%rbp), %rax
movq 0xe0(%rax), %rdi
callq 0x28720
jmp 0x2b470
leaq -0x2c8(%rbp), %rdi
callq 0x28770
movl $0x0, -0x24c(%rbp)
leaq -0x218(%rbp), %rdi
callq 0xc190
leaq -0x1e8(%rbp), %rdi
callq 0x1ce90
leaq -0x168(%rbp), %rdi
callq 0xa610
leaq -0xc8(%rbp), %rdi
callq 0xa610
addq $0x370, %rsp            # imm = 0x370
popq %rbp
retq
leaq -0x218(%rbp), %rdi
callq 0xc190
leaq -0x1e8(%rbp), %rdi
callq 0x1ce90
leaq -0x168(%rbp), %rdi
callq 0xa610
leaq -0xc8(%rbp), %rdi
callq 0xa610
movq -0x170(%rbp), %rdi
callq 0x5750
nopl (%rax,%rax)