// File: Windfisch[P]production-flow/factory.cpp
// Function: Factory::build_topological_sort()
void Factory::build_topological_sort()
{
	facility_toposort.resize(MAX_ITEM);
	facility_toposort_inv.resize(MAX_ITEM);

	for (int item = 0; item < MAX_ITEM; item++)
	{
		vector<size_t>& toposort = facility_toposort[item];
		vector<size_t>& toposort_inv = facility_toposort_inv[item];
		toposort.clear();
		toposort_inv.resize(facilities.size());


		vector<size_t> relevant_facilities = collect_relevant_facilities(item_t(item));


		// calculate incident / outgoing edges
		vector< unordered_set<size_t> > incident_edges(facilities.size());
		vector< unordered_set<size_t> > outgoing_edges(facilities.size());
		for (size_t edge_id = 0; edge_id < transport_lines.size(); edge_id++)
		{
			const auto& edge = transport_lines[edge_id];

			if (edge.item_type == item)
			{
				incident_edges[edge.to].insert(edge_id);
				outgoing_edges[edge.from].insert(edge_id);
			}
		}


		// do the actual topological sorting
		size_t root;
		while ((root = pop_root_node(relevant_facilities, incident_edges)) != INVALID_INDEX)
		{
			toposort.push_back(root);
			toposort_inv[root] = toposort.size()-1;

			for (size_t edge_id : outgoing_edges[root])
				incident_edges[transport_lines[edge_id].to].erase(edge_id);
		}

		for (const auto& edges : incident_edges)
			if (!edges.empty())
				throw runtime_error("Factory is not a directed acyclic graph for item " + to_string(item));
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x150(%rbp)
addq $0x30, %rdi
movl $0xb, %esi
callq 0xa080
movq -0x150(%rbp), %rdi
addq $0x48, %rdi
movl $0xb, %esi
callq 0xa080
movl $0x0, -0xc(%rbp)
cmpl $0xb, -0xc(%rbp)
jge 0x8883
movq -0x150(%rbp), %rdi
addq $0x30, %rdi
movslq -0xc(%rbp), %rsi
callq 0x5850
movq -0x150(%rbp), %rdi
movq %rax, -0x18(%rbp)
addq $0x48, %rdi
movslq -0xc(%rbp), %rsi
callq 0x5850
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0xa110
movq -0x150(%rbp), %rdi
movq -0x20(%rbp), %rax
movq %rax, -0x168(%rbp)
callq 0x5710
movq -0x168(%rbp), %rdi
movq %rax, %rsi
callq 0xa130
movq -0x150(%rbp), %rsi
movl -0xc(%rbp), %edx
leaq -0x38(%rbp), %rdi
callq 0x7fa0
movq -0x150(%rbp), %rdi
callq 0x5710
movq %rax, -0x160(%rbp)
leaq -0x51(%rbp), %rdi
movq %rdi, -0x158(%rbp)
callq 0xa1c0
movq -0x160(%rbp), %rsi
movq -0x158(%rbp), %rdx
leaq -0x50(%rbp), %rdi
callq 0xa1e0
jmp 0x83fc
leaq -0x51(%rbp), %rdi
callq 0xa250
movq -0x150(%rbp), %rdi
callq 0x5710
movq %rax, -0x178(%rbp)
leaq -0x81(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0xa1c0
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdx
leaq -0x80(%rbp), %rdi
callq 0xa1e0
jmp 0x8444
leaq -0x81(%rbp), %rdi
callq 0xa250
movq $0x0, -0x90(%rbp)
movq -0x150(%rbp), %rdi
movq -0x90(%rbp), %rax
movq %rax, -0x180(%rbp)
addq $0x18, %rdi
callq 0x5770
movq %rax, %rcx
movq -0x180(%rbp), %rax
cmpq %rcx, %rax
jae 0x85b7
movq -0x150(%rbp), %rdi
addq $0x18, %rdi
movq -0x90(%rbp), %rsi
callq 0xa270
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movl (%rax), %eax
cmpl -0xc(%rbp), %eax
jne 0x859e
movq -0x98(%rbp), %rax
movq 0x10(%rax), %rsi
leaq -0x50(%rbp), %rdi
callq 0xa290
movq %rax, %rdi
leaq -0x90(%rbp), %rsi
callq 0xa2b0
movb %dl, -0x189(%rbp)
movq %rax, -0x188(%rbp)
jmp 0x84ee
movb -0x189(%rbp), %al
movq -0x188(%rbp), %rcx
movq %rcx, -0xa8(%rbp)
movb %al, -0xa0(%rbp)
movq -0x98(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x80(%rbp), %rdi
callq 0xa290
movq %rax, %rdi
leaq -0x90(%rbp), %rsi
callq 0xa2b0
movb %dl, -0x199(%rbp)
movq %rax, -0x198(%rbp)
jmp 0x853a
movb -0x199(%rbp), %al
movq -0x198(%rbp), %rcx
movq %rcx, -0xb8(%rbp)
movb %al, -0xb0(%rbp)
jmp 0x859e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x51(%rbp), %rdi
callq 0xa250
jmp 0x8878
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x81(%rbp), %rdi
callq 0xa250
jmp 0x886f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x8866
jmp 0x85a0
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x845b
jmp 0x85b9
leaq -0x38(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x8a10
movq %rax, -0x1a8(%rbp)
jmp 0x85cf
movq -0x1a8(%rbp), %rax
movq %rax, -0xc0(%rbp)
cmpq $-0x1, %rax
je 0x86dd
movq -0x18(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x9ca0
jmp 0x85f9
movq -0x18(%rbp), %rdi
callq 0x5870
subq $0x1, %rax
movq %rax, -0x1b0(%rbp)
movq -0x20(%rbp), %rdi
movq -0xc0(%rbp), %rsi
callq 0x5890
movq -0x1b0(%rbp), %rcx
movq %rcx, (%rax)
movq -0xc0(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0xa290
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rdi
callq 0xa2f0
movq %rax, -0xd0(%rbp)
movq -0xc8(%rbp), %rdi
callq 0xa320
movq %rax, -0xd8(%rbp)
leaq -0xd0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0xa350
testb $0x1, %al
jne 0x867d
jmp 0x86d8
leaq -0xd0(%rbp), %rdi
callq 0xa380
movq -0x150(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0xe0(%rbp)
addq $0x18, %rdi
movq -0xe0(%rbp), %rsi
callq 0xa270
movq 0x10(%rax), %rsi
leaq -0x50(%rbp), %rdi
callq 0xa290
movq %rax, %rdi
leaq -0xe0(%rbp), %rsi
callq 0xa3b0
jmp 0x86c8
jmp 0x86ca
leaq -0xd0(%rbp), %rdi
callq 0xa3e0
jmp 0x8664
jmp 0x85b9
leaq -0x50(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rdi
callq 0xa410
movq %rax, -0xf0(%rbp)
movq -0xe8(%rbp), %rdi
callq 0xa440
movq %rax, -0xf8(%rbp)
leaq -0xf0(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0xa470
testb $0x1, %al
jne 0x872a
jmp 0x883d
leaq -0xf0(%rbp), %rdi
callq 0xa4b0
movq %rax, -0x100(%rbp)
movq -0x100(%rbp), %rdi
callq 0xa4d0
testb $0x1, %al
jne 0x882a
movb $0x1, -0x141(%rbp)
movl $0x10, %edi
callq 0x3170
movq %rax, -0x1b8(%rbp)
movl -0xc(%rbp), %esi
leaq -0x140(%rbp), %rdi
callq 0xa540
jmp 0x877a
leaq 0x1cba9(%rip), %rsi     # 0x2532a
leaq -0x120(%rbp), %rdi
leaq -0x140(%rbp), %rdx
callq 0xa4f0
jmp 0x8796
movq -0x1b8(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x3480
jmp 0x87ab
movq -0x1b8(%rbp), %rdi
movb $0x0, -0x141(%rbp)
movq 0x30830(%rip), %rsi     # 0x38ff0
movq 0x307f9(%rip), %rdx     # 0x38fc0
callq 0x34c0
jmp 0x8895
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x8811
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x8805
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x3588
leaq -0x140(%rbp), %rdi
callq 0x3588
testb $0x1, -0x141(%rbp)
jne 0x881c
jmp 0x8828
movq -0x1b8(%rbp), %rdi
callq 0x3230
jmp 0x8866
jmp 0x882c
leaq -0xf0(%rbp), %rdi
callq 0xa660
jmp 0x870e
leaq -0x80(%rbp), %rdi
callq 0xa680
leaq -0x50(%rbp), %rdi
callq 0xa680
leaq -0x38(%rbp), %rdi
callq 0x5af0
movl -0xc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc(%rbp)
jmp 0x8344
leaq -0x80(%rbp), %rdi
callq 0xa680
leaq -0x50(%rbp), %rdi
callq 0xa680
leaq -0x38(%rbp), %rdi
callq 0x5af0
jmp 0x888c
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x34f0
nopw %cs:(%rax,%rax)