// File: /workspace/github_c_makefile_star2_O1/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 0x1b099
movl 0x1c(%r12), %ecx
testl %ecx, %ecx
jne 0x1b027
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)
cmpl $0x0, 0x20(%r12)
jne 0x1b05d
movq 0x10(%rsp), %rdx
movl 0x20(%rdx), %ecx
incl %ecx
movl %ecx, 0x20(%rdx)
movl %ecx, 0x20(%r12)
cmpq $0x0, 0x18(%rsp)
je 0x1b099
movl 0x20(%r12), %ecx
movq 0x20(%rsp), %rdi
movslq (%rdi), %rdx
leaq (%rdx,%rdx,2), %rdx
movq 0x18(%rsp), %r8
movl %ecx, (%r8,%rdx,4)
movslq (%rdi), %rcx
leaq (%rcx,%rcx,2), %rcx
movl %eax, 0x4(%r8,%rcx,4)
movslq (%rdi), %rax
leaq (%rax,%rax,2), %rax
movl %ebx, 0x8(%r8,%rax,4)
incl (%rdi)
movq 0x8(%rsi), %rbp
testq %rbp, %rbp
je 0x1b150
movq 0x68(%rsp), %r14
incl %ebx
movq 0x8(%r12), %r15
testq %r15, %r15
je 0x1b0d3
movq (%rbp), %r13
movq (%r15), %rdi
movq %r13, %rsi
callq 0x1140
testl %eax, %eax
je 0x1b11c
movq 0x8(%r15), %r15
testq %r15, %r15
jne 0x1b0bb
movq 0x18(%r14), %rdi
callq 0x1432b
movq %rax, %r13
movq (%rbp), %rdi
callq 0x14ba7
movq %rax, (%r13)
movl $0x1, 0x28(%r13)
movq 0x10(%r14), %rdi
callq 0x145b2
movq %rax, 0x18(%r13)
movq %r12, 0x10(%r13)
movq 0x8(%r12), %rcx
movq %rcx, 0x8(%r13)
movq %r13, 0x8(%r12)
movq 0x18(%rbp), %rsi
movq %rax, %rdi
jmp 0x1b124
movq 0x18(%r15), %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 0x1afe3
addq $0x10, %rsp
movq 0x8(%rbp), %rbp
testq %rbp, %rbp
jne 0x1b0ad
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq