// File: /workspace/github_cpp_makefile_star2_O1/SeanChao[P]KV-Store/kvstore.cc
// Function: KVStore::compaction(int)
void KVStore::compaction(int level) {
    std::clog << "run compaction on level " << level << std::endl;
    // range statistics
    int nextLv = level + 1;
    int nextLvPos = -1;        // index of insertion point of indexTable in next
                               // level, -1 indicates no assignment yet
    std::vector<Location> id;  // location of tables to be merged
    uint64_t min = UINT64_MAX;
    uint64_t max = 0;
    if (level == 0) {
        uint64_t t0Min = indexTableList[0].front().key;
        uint64_t t1Min = indexTableList[1].front().key;
        uint64_t t0Max = indexTableList[0].back().key;
        uint64_t t1Max = indexTableList[1].back().key;
        uint64_t t2Min = indexTableList[2].front().key;
        uint64_t t2Max = indexTableList[2].back().key;
        min = std::min({t0Min, t1Min, t2Min});
        max = std::max({t0Max, t1Max, t2Max});
        // std::clog << "[lv0]compaction range " << min << " " << max <<
        // std::endl;
        id.push_back(Location(0, 2));
        id.push_back(Location(0, 1));
        id.push_back(Location(0, 0));
    } else {
        // selects exceeding files and merges them into next level
        int more = fileNum[level] - levelSizeLim(level);
        // counts the range of keys in the last file of current level
        for (int i = 0; i < more; i++) {
            int tabId = getIndex(level, levelSizeLim(level) + i);
            uint64_t tMin = indexTableList[tabId].front().key;
            uint64_t tMax = indexTableList[tabId].back().key;
            if (tMin < min) min = tMin;
            max = tMax > max ? tMax : max;
            id.push_back(Location(level, levelSizeLim(level) + i));
        }
    }
    // looks for key range overlapped files
    int delFiles = 0;
    for (int i = 0; fileNum.size() > (size_t)nextLv && i < fileNum[nextLv];
         i++) {
        int tabId = getIndex(nextLv, i);
        uint64_t tMin = indexTableList[tabId].front().key;
        uint64_t tMax = indexTableList[tabId].back().key;
        if (!(tMax < min || max < tMin)) {
            id.push_back(Location(nextLv, i));
            delFiles++;
            // if (nextLvPos == -1) nextLvPos = i;
        }
        if (tMax < min) nextLvPos = i + 1;
    }
    // merge
    std::vector<Pair> all;
    for (size_t i = 0; i < id.size(); i++) {
        // reads ssTable and build pair vector
        std::vector<Pair> t = readSsTable(id[i].level, id[i].id);
        all = merge(all, t);
    }
    // std::clog << "Merged all data: " << std::endl;
    // for (auto &i : all)
    // std::clog << "\t" << i.key << ":\t" << std::string(i.val, 0, 50)
    // << std::endl;
    // update state: removes indexTable from memory, updates fileNum
    for (int i = (int)id.size() - 1; i >= 0; i--) {
        indexTableList.erase(indexTableList.begin() + getIndex(id[i]));
        fileNum[id[i].level]--;
        if (!std::filesystem::remove(resolvePath(id[i])))
            std::clog << "error deleting " << resolvePath(id[i]) << std::endl;
    }
    // slice merged data and write to disk
    // program state is updated in call to writeSsTable
    uint64_t size = 0;
    std::vector<Pair> tmp;
    if (nextLvPos == -1) nextLvPos = 0;
    // renames all file in nextLv to avoid rename hazard
    renameLevel(nextLv, 0);
    for (auto &i : all) {
        size += i.val.length() + DATA_CONST_SIZE;
        tmp.push_back(i);
        if (size >= MEM_TABLE_SIZE_MAX || i.key == all.back().key) {
            writeSsTable(tmp, Location(nextLv, nextLvPos++), true);
            size = 0;
            tmp.clear();
        }
    }
    renameLevel(nextLv, 1);
    // call compaction on next level if necessary
    if (fileNum[nextLv] > levelSizeLim(nextLv)) compaction(nextLv);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movl %esi, %ebp
movq %rdi, %rbx
movq 0x7fd3(%rip), %r14      # 0xefa8
leaq 0x4388(%rip), %rsi      # 0xb364
movl $0x18, %edx
movq %r14, %rdi
callq 0x32b0
movq %r14, %rdi
movl %ebp, %esi
callq 0x33d0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3250
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x31b0
leal 0x1(%rbp), %ecx
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
testl %ebp, %ebp
movl %ecx, 0xc(%rsp)
movq %rbp, 0x88(%rsp)
je 0x7114
movslq %ebp, %rdx
movl $0x1, %esi
shll %cl, %esi
movq 0x60(%rbx), %rax
movq %rdx, 0x60(%rsp)
movl (%rax,%rdx,4), %ecx
xorl %r15d, %r15d
movq %rsi, 0x38(%rsp)
subl %esi, %ecx
movl %ecx, 0x68(%rsp)
movq $-0x1, %r12
jle 0x71fc
xorl %r13d, %r13d
movq 0x60(%rbx), %rax
movq 0x68(%rbx), %rdx
movq %rdx, %rcx
subq %rax, %rcx
sarq $0x2, %rcx
movq 0x60(%rsp), %rsi
cmpq %rcx, %rsi
cmovbq %rsi, %rcx
cmpq %rax, %rdx
je 0x70ad
xorl %esi, %esi
xorl %edx, %edx
addl (%rax,%rsi,4), %edx
incq %rsi
cmpq %rsi, %rcx
jne 0x70a0
jmp 0x70af
xorl %edx, %edx
movq 0x38(%rsp), %rax
addl %r15d, %eax
addl %eax, %edx
movslq %edx, %rcx
movq 0x40(%rbx), %rdx
leaq (%rcx,%rcx,2), %rcx
movq (%rdx,%rcx,8), %rsi
movq 0x8(%rdx,%rcx,8), %rcx
movq (%rsi), %rbp
movq -0x10(%rcx), %r14
movq 0x88(%rsp), %rcx
movl %ecx, 0x10(%rsp)
movl %eax, 0x14(%rsp)
leaq 0x40(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0xa870
cmpq %r12, %rbp
cmovbq %rbp, %r12
cmpq %r13, %r14
cmovaq %r14, %r13
incl %r15d
cmpl 0x68(%rsp), %r15d
jne 0x7079
jmp 0x71ff
movq 0x40(%rbx), %rdx
movq (%rdx), %rax
movq 0x8(%rdx), %rcx
movq (%rax), %rdi
movq 0x18(%rdx), %rax
movq (%rax), %r8
movq -0x10(%rcx), %rax
movq 0x20(%rdx), %rcx
movq -0x10(%rcx), %rcx
movq 0x30(%rdx), %rsi
movq (%rsi), %r9
movq 0x38(%rdx), %rdx
movq -0x10(%rdx), %rdx
leaq 0x10(%rsp), %rsi
movq %rdi, (%rsi)
movq %r8, 0x8(%rsi)
movq %r9, 0x10(%rsi)
movl $0x8, %edi
movq 0x10(%rsp,%rdi), %r8
cmpq (%rsi), %r8
jae 0x716b
leaq (%rsp,%rdi), %rsi
addq $0x10, %rsi
addq $0x8, %rdi
cmpq $0x18, %rdi
jne 0x7159
movq (%rsi), %r12
leaq 0x10(%rsp), %rsi
movq %rax, (%rsi)
movq %rcx, 0x8(%rsi)
movq %rdx, 0x10(%rsi)
movl $0x8, %eax
movq (%rsi), %rcx
cmpq 0x10(%rsp,%rax), %rcx
jae 0x719f
leaq (%rsp,%rax), %rsi
addq $0x10, %rsi
addq $0x8, %rax
cmpq $0x18, %rax
jne 0x718d
movq (%rsi), %r13
movabsq $0x200000000, %rax      # imm = 0x200000000
leaq 0x10(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x40(%rsp), %rdi
callq 0xa870
movabsq $0x100000000, %rax      # imm = 0x100000000
leaq 0x10(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x40(%rsp), %rdi
callq 0xa870
leaq 0x10(%rsp), %rsi
movq $0x0, (%rsi)
leaq 0x40(%rsp), %rdi
callq 0xa870
jmp 0x71ff
xorl %r13d, %r13d
movslq 0xc(%rsp), %rdx
movq 0x60(%rbx), %rax
movq 0x68(%rbx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movq %rsi, 0x38(%rsp)
cmpq %rdx, %rcx
movq %rdx, 0x68(%rsp)
jbe 0x72db
xorl %ebp, %ebp
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movq %rcx, 0x38(%rsp)
leaq 0x10(%rsp), %r15
cmpl (%rax,%rdx,4), %ebp
jge 0x72db
movq 0x68(%rbx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %rcx, %rdx
cmovbq %rdx, %rcx
testq %rcx, %rcx
je 0x726d
xorl %esi, %esi
xorl %edx, %edx
addl (%rax,%rsi,4), %edx
incq %rsi
cmpq %rsi, %rcx
jne 0x7260
jmp 0x726f
xorl %edx, %edx
addl %ebp, %edx
movslq %edx, %rcx
movq 0x40(%rbx), %rax
leaq (%rcx,%rcx,2), %rcx
movq 0x8(%rax,%rcx,8), %rdx
movq -0x10(%rdx), %r14
cmpq %r12, %r14
jb 0x72ac
movq (%rax,%rcx,8), %rax
cmpq (%rax), %r13
jb 0x72ac
movl 0xc(%rsp), %eax
movl %eax, 0x10(%rsp)
movl %ebp, 0x14(%rsp)
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0xa870
incl %ebp
cmpq %r12, %r14
movq 0x38(%rsp), %rax
cmovbl %ebp, %eax
movq %rax, 0x38(%rsp)
movq 0x60(%rbx), %rax
movq 0x68(%rbx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
movq 0x68(%rsp), %rdx
cmpq %rdx, %rcx
ja 0x723c
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %r12
xorps %xmm0, %xmm0
movaps %xmm0, 0x70(%rsp)
movq $0x0, 0x80(%rsp)
subq %rax, %r12
je 0x73fa
xorl %ebp, %ebp
leaq 0x90(%rsp), %r14
leaq 0x100(%rsp), %r15
leaq 0xe8(%rsp), %r13
movl (%rax,%rbp,8), %edx
movl 0x4(%rax,%rbp,8), %ecx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x79be
movq %r15, %rdi
leaq 0x70(%rsp), %rsi
callq 0x92ea
leaq 0xb8(%rsp), %r12
movq %r13, %rdi
movq %r14, %rsi
callq 0x92ea
movq %r12, %rdi
movq %r15, %rdx
movq %r13, %rcx
callq 0x8298
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movaps 0x70(%rsp), %xmm0
movq 0x80(%rsp), %rax
movups 0xb8(%rsp), %xmm1
movaps %xmm1, 0x70(%rsp)
movq 0xc8(%rsp), %rcx
movq %rcx, 0x80(%rsp)
movaps 0x10(%rsp), %xmm1
movaps %xmm0, 0x10(%rsp)
movq %rax, 0x20(%rsp)
movups %xmm1, 0xb8(%rsp)
movq $0x0, 0xc8(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x913a
movq %r12, %rdi
callq 0x913a
movq %r13, %rdi
callq 0x913a
movq %r15, %rdi
callq 0x913a
movq %r14, %rdi
callq 0x913a
incq %rbp
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %r12
subq %rax, %r12
sarq $0x3, %r12
cmpq %r12, %rbp
jb 0x731c
jmp 0x73fe
sarq $0x3, %r12
testl %r12d, %r12d
jle 0x7591
leaq 0x40(%rbx), %rax
movq %rax, 0x60(%rsp)
andl $0x7fffffff, %r12d      # imm = 0x7FFFFFFF
leaq 0x90(%rsp), %rbp
leaq 0x10(%rsp), %r13
movq 0x60(%rbx), %rcx
movq 0x40(%rsp), %rax
movslq -0x8(%rax,%r12,8), %rsi
movq 0x68(%rbx), %rdx
subq %rcx, %rdx
sarq $0x2, %rdx
cmpq %rdx, %rsi
cmovbq %rsi, %rdx
testq %rdx, %rdx
je 0x745a
xorl %edi, %edi
xorl %esi, %esi
addl (%rcx,%rdi,4), %esi
incq %rdi
cmpq %rdi, %rdx
jne 0x744d
jmp 0x745c
xorl %esi, %esi
movq 0x40(%rbx), %rcx
movslq -0x4(%rax,%r12,8), %rax
movslq %esi, %rdx
addq %rax, %rdx
leaq (%rdx,%rdx,2), %rax
leaq (%rcx,%rax,8), %rsi
movq 0x60(%rsp), %rdi
callq 0xaa7e
leaq -0x1(%r12), %r15
movq 0x40(%rsp), %rax
movslq (%rax,%r15,8), %rcx
movq 0x60(%rbx), %rdx
decl (%rdx,%rcx,4)
movl (%rax,%r15,8), %edx
movl 0x4(%rax,%r15,8), %ecx
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x5ea6
movq %r13, %rdi
movq %rbp, %rsi
movl $0x2, %edx
callq 0x920e
movq %r13, %rdi
callq 0x3200
movl %eax, %r14d
movq %r13, %rdi
callq 0x8fba
movq 0x90(%rsp), %rdi
leaq 0xa0(%rsp), %rax
cmpq %rax, %rdi
je 0x74ee
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x3280
testb %r14b, %r14b
jne 0x7584
movl $0xf, %edx
movq 0x7aa5(%rip), %rdi      # 0xefa8
leaq 0x3e73(%rip), %rsi      # 0xb37d
callq 0x32b0
movq 0x40(%rsp), %rax
movl (%rax,%r15,8), %edx
movl 0x4(%rax,%r15,8), %ecx
movq %r13, %rdi
movq %rbx, %rsi
callq 0x5ea6
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x7a6f(%rip), %rdi      # 0xefa8
callq 0x32b0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3250
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x31b0
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x7584
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x3280
cmpq $0x1, %r12
movq %r15, %r12
jg 0x7424
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
movq %rbx, %rdi
movl 0xc(%rsp), %esi
xorl %edx, %edx
callq 0x688e
movq 0x70(%rsp), %r14
movq 0x78(%rsp), %r12
cmpq %r12, %r14
movq 0x38(%rsp), %r13
je 0x76b8
xorl %ebp, %ebp
cmpl $-0x1, %r13d
cmovel %ebp, %r13d
movl 0xc(%rsp), %eax
movq %rax, 0x60(%rsp)
movq %rbx, 0xb0(%rsp)
movq 0x18(%r14), %r15
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x9386
addq %r15, %rbp
addq $0x28, %rbp
cmpq $0x1fffff, %rbp         # imm = 0x1FFFFF
ja 0x7616
movq (%r14), %rax
movq 0x78(%rsp), %rcx
cmpq -0x30(%rcx), %rax
jne 0x76ab
leaq 0xd0(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x92ea
movq %r13, %rdx
shlq $0x20, %rdx
addq 0x60(%rsp), %rdx
movq %rbx, %rdi
leaq 0xd0(%rsp), %r15
movq %r15, %rsi
xorl %ecx, %ecx
callq 0x7d08
incl %r13d
movq %r15, %rdi
callq 0x913a
movq 0x10(%rsp), %rbp
movq 0x18(%rsp), %r15
cmpq %rbp, %r15
je 0x76a9
movq %r12, %rbx
movq %r13, %r12
leaq 0x20(%rbp), %r13
movq -0x10(%r13), %rdi
cmpq %rdi, %r13
je 0x7682
movq (%r13), %rsi
incq %rsi
callq 0x3280
leaq 0x30(%r13), %rax
addq $0x10, %r13
cmpq %r15, %r13
movq %rax, %r13
jne 0x766d
movq %rbp, 0x18(%rsp)
xorl %ebp, %ebp
movq %r12, %r13
movq %rbx, %r12
movq 0xb0(%rsp), %rbx
jmp 0x76ab
xorl %ebp, %ebp
addq $0x30, %r14
cmpq %r12, %r14
jne 0x75e3
movl $0x1, %ebp
movq %rbx, %rdi
movl 0xc(%rsp), %r14d
movl %r14d, %esi
movl $0x1, %edx
callq 0x688e
movq 0x88(%rsp), %rcx
addb $0x2, %cl
shll %cl, %ebp
movq 0x60(%rbx), %rax
movq 0x68(%rsp), %rcx
cmpl %ebp, (%rax,%rcx,4)
jle 0x76f8
movq %rbx, %rdi
movl %r14d, %esi
callq 0x6fb8
leaq 0x10(%rsp), %rdi
callq 0x913a
leaq 0x70(%rsp), %rdi
callq 0x913a
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x7723
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x3280
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x7746
jmp 0x7746
jmp 0x7746
jmp 0x77cb
jmp 0x7746
jmp 0x7795
jmp 0x7795
movq %rax, %rbx
jmp 0x7803
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0x913a
jmp 0x77ce
jmp 0x7795
jmp 0x7795
movq %rax, %rbx
jmp 0x7776
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x8fba
movq 0x90(%rsp), %rdi
leaq 0xa0(%rsp), %rax
cmpq %rax, %rdi
je 0x77f9
movq 0xa0(%rsp), %rsi
jmp 0x77f1
movq %rax, %rbx
jmp 0x77f9
movq %rax, %rbx
jmp 0x77c1
movq %rax, %rbx
jmp 0x77b4
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x913a
leaq 0x100(%rsp), %rdi
callq 0x913a
leaq 0x90(%rsp), %rdi
jmp 0x77d3
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x913a
jmp 0x77f9
movq %rax, %rbx
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x77f9
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x3280
leaq 0x70(%rsp), %rdi
callq 0x913a
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x781a
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x3280
movq %rbx, %rdi
callq 0x33f0