// File: mapequation[P]partition-validation/./partition-validation.h
// Function: Partitions::readPartitionsFile()
void Partitions::readPartitionsFile() {
    cout << "Reading partitions file " << flush;

    string line;
    string buf;

    // Count number of nodes and boot partitions
    getline(ifs, line);
    nNodes++; // First line corresponds to first node

    {
        istringstream read(line);
        while (read >> buf) nPartitions++;
    }

    if (crossValidateK > 0) {
        nValidationPartitions = nPartitions / crossValidateK;
    }

    if (nTrainingPartitions == 0) {
        if (nPartitions - nValidationPartitions > 0) {
            nTrainingPartitions = nPartitions - nValidationPartitions;
        } else {
            cout << "-- Not enough partitions for validation. Will not validate." << endl;
        }
    } else if (nPartitions - nValidationPartitions - nTrainingPartitions < 0) {
        cout << "-- Not enough partitions for training and validation." << endl;
    }

    cout << "with " << nPartitions << " partitions..." << flush;

    // Count remaining nodes
    while (getline(ifs, line)) {
        nNodes++;
    }

    if (ifs.bad()) {
        cout << "Error while reading file" << endl;
    }

    cout << "of " << nNodes << " nodes..." << flush;

    partitions = vector<Partition>(nPartitions);

    for (int i = 0; i < nPartitions; i++) {
        partitions[i] = Partition(i, nNodes);
    }

    // Restart from beginning of file
    vector<map<string, int> > partitionsAssignmentId(nPartitions);
    vector<int> partitionsAssignmentIds(nPartitions, 0);
    ifs.clear();
    ifs.seekg(0, ios::beg);

    // Read partitions data
    int nodeNr = 0;

    while (getline(ifs, line)) {
        istringstream read(line);
        int i = 0;

        while (read >> buf) {
            vector<string> assignments = tokenize(buf, ':');
            string assignmentKey;

            for (auto &assignment: assignments) {
                assignmentKey += assignment + ":";

                auto lookup = partitionsAssignmentId[i].find(assignmentKey);
                int assignmentId = partitionsAssignmentIds[i];

                if (lookup != end(partitionsAssignmentId[i])) {
                    assignmentId = lookup->second;
                } else {
                    partitionsAssignmentId[i][assignmentKey] = partitionsAssignmentIds[i];
                    partitionsAssignmentIds[i]++;
                }

                partitions[i].assignments[nodeNr].push_back(assignmentId);
                partitions[i].clusterSizes[assignmentId]++;
            }
            i++;
        }
        nodeNr++;
    }

    cout << "done!" << endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x5b0, %rsp            # imm = 0x5B0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x4c0(%rbp)
movq 0x2031f(%rip), %rdi     # 0x24fd0
leaq 0x13405(%rip), %rsi     # 0x180bd
callq 0x32c0
movq %rax, %rdi
movq 0x20311(%rip), %rsi     # 0x24fd8
callq 0x3310
leaq -0x28(%rbp), %rdi
movq %rdi, -0x4b8(%rbp)
callq 0x3400
leaq -0x48(%rbp), %rdi
callq 0x3400
movq -0x4c0(%rbp), %rdi
movq -0x4b8(%rbp), %rsi
addq $0xb0, %rdi
callq 0x3080
jmp 0x4d01
movq -0x4c0(%rbp), %rax
movl 0x4d8(%rax), %ecx
incl %ecx
movl %ecx, 0x4d8(%rax)
leaq -0x1d8(%rbp), %rdi
leaq -0x28(%rbp), %rsi
movl $0x8, %edx
callq 0x3470
jmp 0x4d2d
jmp 0x4d2f
leaq -0x1d8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x33c0
movq %rax, -0x4c8(%rbp)
jmp 0x4d48
movq -0x4c8(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x33b0
movb %al, -0x4c9(%rbp)
jmp 0x4d66
movb -0x4c9(%rbp), %al
testb $0x1, %al
jne 0x4d72
jmp 0x4db8
movq -0x4c0(%rbp), %rax
movl 0x4dc(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4dc(%rax)
jmp 0x4d2f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x571b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x3160
jmp 0x571b
leaq -0x1d8(%rbp), %rdi
callq 0x3160
movq -0x4c0(%rbp), %rax
cmpl $0x0, 0x68(%rax)
jle 0x4df1
movq -0x4c0(%rbp), %rcx
movl 0x4dc(%rcx), %eax
cltd
idivl 0x68(%rcx)
movl %eax, %ecx
movq -0x4c0(%rbp), %rax
movl %ecx, 0x4e8(%rax)
movq -0x4c0(%rbp), %rax
cmpl $0x0, 0x4e4(%rax)
jne 0x4e69
movq -0x4c0(%rbp), %rcx
movl 0x4dc(%rcx), %eax
subl 0x4e8(%rcx), %eax
cmpl $0x0, %eax
jle 0x4e34
movq -0x4c0(%rbp), %rax
movl 0x4dc(%rax), %ecx
subl 0x4e8(%rax), %ecx
movl %ecx, 0x4e4(%rax)
jmp 0x4e67
movq 0x20195(%rip), %rdi     # 0x24fd0
leaq 0x13294(%rip), %rsi     # 0x180d6
callq 0x32c0
movq %rax, -0x4d8(%rbp)
jmp 0x4e50
movq -0x4d8(%rbp), %rdi
movq 0x20162(%rip), %rsi     # 0x24fc0
callq 0x3310
jmp 0x4e65
jmp 0x4e67
jmp 0x4ebc
movq -0x4c0(%rbp), %rcx
movl 0x4dc(%rcx), %eax
subl 0x4e8(%rcx), %eax
subl 0x4e4(%rcx), %eax
cmpl $0x0, %eax
jge 0x4eba
movq 0x20142(%rip), %rdi     # 0x24fd0
leaq 0x1327d(%rip), %rsi     # 0x18112
callq 0x32c0
movq %rax, -0x4e0(%rbp)
jmp 0x4ea3
movq -0x4e0(%rbp), %rdi
movq 0x2010f(%rip), %rsi     # 0x24fc0
callq 0x3310
jmp 0x4eb8
jmp 0x4eba
jmp 0x4ebc
movq 0x2010d(%rip), %rdi     # 0x24fd0
leaq 0x1327e(%rip), %rsi     # 0x18148
callq 0x32c0
movq %rax, -0x4e8(%rbp)
jmp 0x4ed8
movq -0x4e8(%rbp), %rdi
movq -0x4c0(%rbp), %rax
movl 0x4dc(%rax), %esi
callq 0x3490
movq %rax, -0x4f0(%rbp)
jmp 0x4efa
movq -0x4f0(%rbp), %rdi
leaq 0x13246(%rip), %rsi     # 0x1814e
callq 0x32c0
movq %rax, -0x4f8(%rbp)
jmp 0x4f16
movq -0x4f8(%rbp), %rdi
movq 0x200b4(%rip), %rsi     # 0x24fd8
callq 0x3310
jmp 0x4f2b
jmp 0x4f2d
movq -0x4c0(%rbp), %rdi
addq $0xb0, %rdi
leaq -0x28(%rbp), %rsi
callq 0x3080
movq %rax, -0x500(%rbp)
jmp 0x4f4d
movq -0x500(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x33b0
movb %al, -0x501(%rbp)
jmp 0x4f6b
movb -0x501(%rbp), %al
testb $0x1, %al
jne 0x4f77
jmp 0x4f8f
movq -0x4c0(%rbp), %rax
movl 0x4d8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4d8(%rax)
jmp 0x4f2d
movq -0x4c0(%rbp), %rax
movq 0xb0(%rax), %rcx
movq -0x18(%rcx), %rcx
leaq 0xb0(%rax,%rcx), %rdi
callq 0x34d0
movb %al, -0x502(%rbp)
jmp 0x4fb6
movb -0x502(%rbp), %al
testb $0x1, %al
jne 0x4fc2
jmp 0x4ff5
movq 0x20007(%rip), %rdi     # 0x24fd0
leaq 0x1318d(%rip), %rsi     # 0x1815d
callq 0x32c0
movq %rax, -0x510(%rbp)
jmp 0x4fde
movq -0x510(%rbp), %rdi
movq 0x1ffd4(%rip), %rsi     # 0x24fc0
callq 0x3310
jmp 0x4ff3
jmp 0x4ff5
movq 0x1ffd4(%rip), %rdi     # 0x24fd0
leaq 0x13078(%rip), %rsi     # 0x1807b
callq 0x32c0
movq %rax, -0x518(%rbp)
jmp 0x5011
movq -0x518(%rbp), %rdi
movq -0x4c0(%rbp), %rax
movl 0x4d8(%rax), %esi
callq 0x3490
movq %rax, -0x520(%rbp)
jmp 0x5033
movq -0x520(%rbp), %rdi
leaq 0x13135(%rip), %rsi     # 0x18176
callq 0x32c0
movq %rax, -0x528(%rbp)
jmp 0x504f
movq -0x528(%rbp), %rdi
movq 0x1ff7b(%rip), %rsi     # 0x24fd8
callq 0x3310
jmp 0x5064
movq -0x4c0(%rbp), %rax
movslq 0x4dc(%rax), %rax
movq %rax, -0x538(%rbp)
leaq -0x1f1(%rbp), %rdi
movq %rdi, -0x530(%rbp)
callq 0x8fb0
movq -0x538(%rbp), %rsi
movq -0x530(%rbp), %rdx
leaq -0x1f0(%rbp), %rdi
callq 0x8fd0
jmp 0x50a8
movq -0x4c0(%rbp), %rdi
addq $0x50, %rdi
leaq -0x1f0(%rbp), %rsi
callq 0x9040
leaq -0x1f0(%rbp), %rdi
callq 0x9070
leaq -0x1f1(%rbp), %rdi
callq 0x90d0
movl $0x0, -0x1f8(%rbp)
movq -0x4c0(%rbp), %rcx
movl -0x1f8(%rbp), %eax
cmpl 0x4dc(%rcx), %eax
jge 0x517b
movq -0x4c0(%rbp), %rax
movl -0x1f8(%rbp), %esi
movl 0x4d8(%rax), %edx
leaq -0x250(%rbp), %rdi
callq 0x90f0
jmp 0x511b
movq -0x4c0(%rbp), %rdi
addq $0x50, %rdi
movslq -0x1f8(%rbp), %rsi
callq 0x8b10
movq %rax, %rdi
leaq -0x250(%rbp), %rsi
callq 0x91b0
leaq -0x250(%rbp), %rdi
callq 0x9200
movl -0x1f8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1f8(%rbp)
jmp 0x50e1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1f1(%rbp), %rdi
callq 0x90d0
jmp 0x571b
movq -0x4c0(%rbp), %rax
movslq 0x4dc(%rax), %rax
movq %rax, -0x548(%rbp)
leaq -0x269(%rbp), %rdi
movq %rdi, -0x540(%rbp)
callq 0x9230
movq -0x548(%rbp), %rsi
movq -0x540(%rbp), %rdx
leaq -0x268(%rbp), %rdi
callq 0x9250
jmp 0x51bf
leaq -0x269(%rbp), %rdi
callq 0x92c0
movq -0x4c0(%rbp), %rax
movslq 0x4dc(%rax), %rax
movq %rax, -0x558(%rbp)
movl $0x0, -0x28c(%rbp)
leaq -0x28d(%rbp), %rdi
movq %rdi, -0x550(%rbp)
callq 0x8d70
movq -0x558(%rbp), %rsi
movq -0x550(%rbp), %rcx
leaq -0x288(%rbp), %rdi
leaq -0x28c(%rbp), %rdx
callq 0x8d90
jmp 0x5220
leaq -0x28d(%rbp), %rdi
callq 0x8e10
movq -0x4c0(%rbp), %rax
movq 0xb0(%rax), %rcx
movq -0x18(%rcx), %rcx
leaq 0xb0(%rax,%rcx), %rdi
xorl %esi, %esi
callq 0x3480
jmp 0x524f
movq -0x4c0(%rbp), %rdi
addq $0xb0, %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x33f0
jmp 0x5268
movl $0x0, -0x294(%rbp)
movq -0x4c0(%rbp), %rdi
addq $0xb0, %rdi
leaq -0x28(%rbp), %rsi
callq 0x3080
movq %rax, -0x560(%rbp)
jmp 0x5292
movq -0x560(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x33b0
movb %al, -0x561(%rbp)
jmp 0x52b0
movb -0x561(%rbp), %al
testb $0x1, %al
jne 0x52bf
jmp 0x569f
leaq -0x418(%rbp), %rdi
leaq -0x28(%rbp), %rsi
movl $0x8, %edx
callq 0x3470
jmp 0x52d6
movl $0x0, -0x41c(%rbp)
leaq -0x418(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x33c0
movq %rax, -0x570(%rbp)
jmp 0x52f9
movq -0x570(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x33b0
movb %al, -0x571(%rbp)
jmp 0x5317
movb -0x571(%rbp), %al
testb $0x1, %al
jne 0x5326
jmp 0x5671
leaq -0x438(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movl $0x3a, %edx
callq 0x3680
jmp 0x533d
leaq -0x458(%rbp), %rdi
callq 0x3400
leaq -0x438(%rbp), %rax
movq %rax, -0x460(%rbp)
movq -0x460(%rbp), %rdi
callq 0x92e0
movq %rax, -0x468(%rbp)
movq -0x460(%rbp), %rdi
callq 0x9310
movq %rax, -0x470(%rbp)
leaq -0x468(%rbp), %rdi
leaq -0x470(%rbp), %rsi
callq 0x9340
testb $0x1, %al
jne 0x5399
jmp 0x562b
leaq -0x468(%rbp), %rdi
callq 0x9380
movq %rax, -0x478(%rbp)
movq -0x478(%rbp), %rsi
leaq 0x133f4(%rip), %rdx     # 0x187ae
leaq -0x498(%rbp), %rdi
callq 0x93a0
jmp 0x53c8
leaq -0x458(%rbp), %rdi
leaq -0x498(%rbp), %rsi
callq 0x33d0
jmp 0x53dd
leaq -0x498(%rbp), %rdi
callq 0x31a0
movslq -0x41c(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x9420
movq %rax, %rdi
leaq -0x458(%rbp), %rsi
callq 0x9440
movq %rax, -0x580(%rbp)
jmp 0x5414
movq -0x580(%rbp), %rax
movq %rax, -0x4a0(%rbp)
movslq -0x41c(%rbp), %rsi
leaq -0x288(%rbp), %rdi
callq 0x8e30
movl (%rax), %eax
movl %eax, -0x4a4(%rbp)
movslq -0x41c(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x9420
movq %rax, %rdi
callq 0x94a0
movq %rax, -0x588(%rbp)
jmp 0x5461
movq -0x588(%rbp), %rax
movq %rax, -0x4b0(%rbp)
leaq -0x4a0(%rbp), %rdi
leaq -0x4b0(%rbp), %rsi
callq 0x9470
testb $0x1, %al
jne 0x548b
jmp 0x552f
leaq -0x4a0(%rbp), %rdi
callq 0x94d0
movl 0x20(%rax), %eax
movl %eax, -0x4a4(%rbp)
jmp 0x559e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x269(%rbp), %rdi
callq 0x92c0
jmp 0x571b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x28d(%rbp), %rdi
callq 0x8e10
jmp 0x570f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x5703
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x5691
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x5657
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x498(%rbp), %rdi
callq 0x31a0
jmp 0x5657
movslq -0x41c(%rbp), %rsi
leaq -0x288(%rbp), %rdi
callq 0x8e30
movl (%rax), %eax
movl %eax, -0x594(%rbp)
movslq -0x41c(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x9420
movq %rax, %rdi
leaq -0x458(%rbp), %rsi
callq 0x94f0
movq %rax, -0x590(%rbp)
jmp 0x5575
movq -0x590(%rbp), %rax
movl -0x594(%rbp), %ecx
movl %ecx, (%rax)
movslq -0x41c(%rbp), %rsi
leaq -0x288(%rbp), %rdi
callq 0x8e30
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x4c0(%rbp), %rdi
addq $0x50, %rdi
movslq -0x41c(%rbp), %rsi
callq 0x8b10
movq %rax, %rdi
addq $0x8, %rdi
movslq -0x294(%rbp), %rsi
callq 0x83d0
movq %rax, %rdi
leaq -0x4a4(%rbp), %rsi
callq 0x95d0
jmp 0x55d9
movq -0x4c0(%rbp), %rdi
addq $0x50, %rdi
movslq -0x41c(%rbp), %rsi
callq 0x8b10
movq %rax, %rdi
addq $0x20, %rdi
leaq -0x4a4(%rbp), %rsi
callq 0x8600
movq %rax, -0x5a0(%rbp)
jmp 0x560c
movq -0x5a0(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
leaq -0x468(%rbp), %rdi
callq 0x9640
jmp 0x537d
movl -0x41c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x41c(%rbp)
leaq -0x458(%rbp), %rdi
callq 0x31a0
leaq -0x438(%rbp), %rdi
callq 0x8150
jmp 0x52e0
leaq -0x458(%rbp), %rdi
callq 0x31a0
leaq -0x438(%rbp), %rdi
callq 0x8150
jmp 0x5691
movl -0x294(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x294(%rbp)
leaq -0x418(%rbp), %rdi
callq 0x3160
jmp 0x5272
leaq -0x418(%rbp), %rdi
callq 0x3160
jmp 0x5703
movq 0x1f92a(%rip), %rdi     # 0x24fd0
leaq 0x12ad3(%rip), %rsi     # 0x18180
callq 0x32c0
movq %rax, -0x5a8(%rbp)
jmp 0x56bb
movq -0x5a8(%rbp), %rdi
movq 0x1f8f7(%rip), %rsi     # 0x24fc0
callq 0x3310
jmp 0x56d0
leaq -0x288(%rbp), %rdi
callq 0x8f50
leaq -0x268(%rbp), %rdi
callq 0x9660
leaq -0x48(%rbp), %rdi
callq 0x31a0
leaq -0x28(%rbp), %rdi
callq 0x31a0
addq $0x5b0, %rsp            # imm = 0x5B0
popq %rbp
retq
leaq -0x288(%rbp), %rdi
callq 0x8f50
leaq -0x268(%rbp), %rdi
callq 0x9660
leaq -0x48(%rbp), %rdi
callq 0x31a0
leaq -0x28(%rbp), %rdi
callq 0x31a0
movq -0x50(%rbp), %rdi
callq 0x34a0
nopw %cs:(%rax,%rax)