// File: /workspace/github_c_makefile_star2_O2/pwelke[P]GraphMiningTools/searchTree.c
// Function: mergeSearchTrees
void mergeSearchTrees(struct Vertex* globalTree, struct Vertex* localTree, int divisor, struct compInfo* results, int* pos, struct Vertex* trueRoot, int depth, struct GraphPool* p) {


	/* process current vertex */

	/* if some string ends here, write it to the output array and update data structure */
	if (localTree->visited) {
		if (globalTree->visited == 0) {
			++trueRoot->d;
		}

		/* add current number of elements (divided by divisor) to global number */
		globalTree->visited += localTree->visited / divisor;
		trueRoot->number += localTree->visited / divisor;

		/* if the current string has no global id yet, get the next one */
		if (globalTree->lowPoint == 0) {
			trueRoot->lowPoint++;
			globalTree->lowPoint = trueRoot->lowPoint;
		}

		/* if we have a results array, store the (id, count)-pair in the array */
		if (results) {

			results[*pos].id = globalTree->lowPoint;
			results[*pos].count = localTree->visited / divisor;
			results[*pos].depth = depth;
			*pos += 1;

		}

	}

	/* if the current vertex is no leaf, merge search trees recursively */
	if (localTree->neighborhood) {

		struct VertexList* locNb;

		/* TODO this is the ugliest, most inefficient stuff */

		/* process neighbors */
		for (locNb=localTree->neighborhood; locNb; locNb=locNb->next) {
			struct VertexList* globNb;
			char found = 0;

			for (globNb=globalTree->neighborhood; globNb; globNb=globNb->next) {

				/* if the next label is already in the tree, continue recursively */
				if (strcmp(globNb->label, locNb->label) == 0) {
					mergeSearchTrees(globNb->endPoint, locNb->endPoint, divisor, results, pos, trueRoot, depth+1, p);
					found = 1;
					break;
				}
			}

			if (!found) {

				/* we reach this point, iff locNb->label is not found in the labels of the global neigbors
				 * thus we have to add the edge and the vertex to the globalTree. This copying has to be a real
				 * copy, no shallow, as any label or vertex that the local tree refers to is dumped when
				 * processing of the current vertex is done.
				 */
				globNb = getVertexList(p->listPool);
				globNb->label = copyString(locNb->label);
				globNb->isStringMaster = 1;
				globNb->endPoint = getVertex(p->vertexPool);
				globNb->startPoint = globalTree;

				/* add this edge at the head of globalTree->neighborhood */
				globNb->next = globalTree->neighborhood;
				globalTree->neighborhood = globNb;

				/* recursive call to merge search trees from this point on */
				mergeSearchTrees(globNb->endPoint, locNb->endPoint, divisor, results, pos, trueRoot, depth+1, p);
			}
		}

		/* at this point, any subtrees (i.e. vertices) dangling at the localTree->neighborhood edges are dumped
		 * so dump the vertex list.
		 * TODO think about this. dumping of the search tree can be handled by dumpSearchTree with no
		 *  additional asymptotic expenses. */
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, 0x10(%rsp)
movq %r8, 0x20(%rsp)
movq %rcx, 0x18(%rsp)
movl %edx, 0xc(%rsp)
movq %rdi, %r12
movl 0x60(%rsp), %ebx
movl 0x1c(%rsi), %eax
testl %eax, %eax
je 0x1882c
movl 0x1c(%r12), %ecx
testl %ecx, %ecx
jne 0x187be
movq 0x10(%rsp), %rdx
incl 0x28(%rdx)
cltd
movl 0xc(%rsp), %edi
idivl %edi
addl %ecx, %eax
movl %eax, 0x1c(%r12)
movl 0x1c(%rsi), %eax
cltd
idivl %edi
movq 0x10(%rsp), %rcx
addl %eax, 0x18(%rcx)
movl 0x20(%r12), %ecx
testl %ecx, %ecx
jne 0x187f5
movq 0x10(%rsp), %rdx
movl 0x20(%rdx), %ecx
incl %ecx
movl %ecx, 0x20(%rdx)
movl %ecx, 0x20(%r12)
cmpq $0x0, 0x18(%rsp)
je 0x1882c
movq 0x20(%rsp), %rdi
movslq (%rdi), %rdx
imulq $0xc, %rdx, %rdx
movq 0x18(%rsp), %r8
movl %ecx, (%r8,%rdx)
movslq (%rdi), %rcx
imulq $0xc, %rcx, %rcx
movl %eax, 0x4(%r8,%rcx)
movslq (%rdi), %rax
imulq $0xc, %rax, %rax
movl %ebx, 0x8(%r8,%rax)
incl (%rdi)
movq 0x8(%rsi), %rbp
testq %rbp, %rbp
je 0x188e4
movq 0x68(%rsp), %r14
leaq 0x8(%r12), %r15
incl %ebx
testq %rbp, %rbp
je 0x188e4
movq %r15, %r13
movq (%r13), %r13
testq %r13, %r13
je 0x18871
movq (%r13), %rdi
movq (%rbp), %rsi
callq 0x1130
testl %eax, %eax
je 0x188b6
addq $0x8, %r13
jmp 0x18851
movq 0x18(%r14), %rdi
callq 0x11307
movq %rax, %r13
movq (%rbp), %rdi
callq 0x118b2
movq %rax, (%r13)
movl $0x1, 0x28(%r13)
movq 0x10(%r14), %rdi
callq 0x114a5
movq %rax, %rdi
movq %rax, 0x18(%r13)
movq %r12, 0x10(%r13)
movq 0x8(%r12), %rax
movq %rax, 0x8(%r13)
movq %r13, 0x8(%r12)
jmp 0x188ba
movq 0x18(%r13), %rdi
movq 0x18(%rbp), %rsi
movl 0xc(%rsp), %edx
movq 0x18(%rsp), %rcx
movq 0x20(%rsp), %r8
movq 0x10(%rsp), %r9
pushq %r14
pushq %rbx
callq 0x1877e
popq %rax
popq %rcx
movq 0x8(%rbp), %rbp
jmp 0x18845
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq