// File: SeanChao[P]KV-Store/kvstore.cc
// Function: KVStore::writeSsTable(std::vector<Pair, std::allocator<Pair>>, Location, bool)
void KVStore::writeSsTable(std::vector<Pair> table, Location loc, bool tmp) {
    std::string path = resolvePath(loc.level, loc.id);
    std::string folder = resolvePath(loc.level);
    if (!std::filesystem::exists(folder))
        std::filesystem::create_directories(folder);
    std::fstream fs(path, std::ios::out | std::ios::binary);
    if (!fs.is_open()) {
        // std::clog << "[writeSsTable] Failed to open sstable file " << path
        // << std::endl;
        return;
    }
    // prepares the cache for index data
    std::vector<Index> indexTable;
    uint64_t offset = 0;
    // writes the data segment
    for (auto &p : table) {
        uint64_t strLen = p.val.length();
        time_t writeTime = time(nullptr);
        Entry e(p.key, writeTime, strLen, p.val);
        writeEntry(fs, e);
        // caches index data
        indexTable.push_back(Index(p.key, offset));
        offset +=
            sizeof(p.key) + sizeof(writeTime) + sizeof(strLen) + p.val.length();
    }
    // writes index data to file
    for (auto i : indexTable) {
        // std::clog << "write key = " << i.key << " offset = " << i.offset
        // << std::endl;
        fs.write(reinterpret_cast<char *>(&i.key), sizeof(i.key));
        fs.write(reinterpret_cast<char *>(&i.offset), sizeof(i.offset));
    }
    // writes meta data
    // index of indexTable
    // std::clog << "Meta: offset = " << std::hex << "0x" << offset << std::dec
    // << std::endl;
    fs.write(reinterpret_cast<char *>(&offset), sizeof(offset));
    fs.close();
    // update state
    indexTableList.insert(indexTableList.begin() + getIndex(loc), indexTable);
    if ((int)fileNum.size() <= loc.level) fileNum.push_back(0);
    if (loc.level >= 0) fileNum[loc.level]++;
    std::clog << "write ss table done -> " << path << std::endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x450, %rsp            # imm = 0x450
movq %rsi, -0x3f8(%rbp)
movb %cl, %al
movq %rdx, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
movq -0x10(%rbp), %rsi
movq %rsi, -0x3f0(%rbp)
movl -0x8(%rbp), %edx
movl -0x4(%rbp), %ecx
leaq -0x40(%rbp), %rdi
callq 0x8330
movq -0x3f0(%rbp), %rsi
movl -0x8(%rbp), %edx
leaq -0x60(%rbp), %rdi
callq 0x8b40
jmp 0xa9f4
leaq -0x98(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movl $0x2, %edx
callq 0xc5a0
jmp 0xaa0b
leaq -0x98(%rbp), %rdi
callq 0xc570
movb %al, -0x3f9(%rbp)
jmp 0xaa1f
movb -0x3f9(%rbp), %al
xorb $-0x1, %al
movb %al, -0x3fa(%rbp)
leaq -0x98(%rbp), %rdi
callq 0xc680
movb -0x3fa(%rbp), %al
testb $0x1, %al
jne 0xaa48
jmp 0xaad7
leaq -0xc0(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movl $0x2, %edx
callq 0xc5a0
jmp 0xaa5f
leaq -0xc0(%rbp), %rdi
callq 0x4200
jmp 0xaa6d
leaq -0xc0(%rbp), %rdi
callq 0xc680
jmp 0xaad7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0xaf9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0xaf95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0xc680
jmp 0xaf95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0xc680
jmp 0xaf95
movl $0x10, %edi
movl $0x4, %esi
callq 0xc770
movl %eax, -0x400(%rbp)
jmp 0xaaee
movl -0x400(%rbp), %edx
leaq -0x2d0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x44f0
jmp 0xab06
leaq -0x2d0(%rbp), %rdi
callq 0x4500
movb %al, -0x401(%rbp)
jmp 0xab1a
movb -0x401(%rbp), %al
testb $0x1, %al
jne 0xab46
jmp 0xab26
movl $0x1, -0x2d4(%rbp)
jmp 0xaf56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0xaf89
leaq -0x2f0(%rbp), %rdi
callq 0xc790
movq -0x3f8(%rbp), %rax
movq $0x0, -0x2f8(%rbp)
movq %rax, -0x300(%rbp)
movq -0x300(%rbp), %rdi
callq 0xd4a0
movq %rax, -0x308(%rbp)
movq -0x300(%rbp), %rdi
callq 0xd4d0
movq %rax, -0x310(%rbp)
leaq -0x308(%rbp), %rdi
leaq -0x310(%rbp), %rsi
callq 0xd500
testb $0x1, %al
jne 0xabad
jmp 0xad36
leaq -0x308(%rbp), %rdi
callq 0xd540
movq %rax, -0x318(%rbp)
movq -0x318(%rbp), %rdi
addq $0x10, %rdi
callq 0x4490
movq %rax, -0x320(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0x42d0
movq %rax, -0x328(%rbp)
movq -0x318(%rbp), %rsi
movq (%rsi), %rax
movq %rax, -0x420(%rbp)
movq -0x328(%rbp), %rax
movq %rax, -0x418(%rbp)
movq -0x320(%rbp), %rax
movq %rax, -0x410(%rbp)
addq $0x10, %rsi
leaq -0x380(%rbp), %rdi
callq 0x4170
jmp 0xac26
movq -0x410(%rbp), %rcx
movq -0x418(%rbp), %rdx
movq -0x420(%rbp), %rsi
leaq -0x360(%rbp), %rdi
leaq -0x380(%rbp), %r8
callq 0xc8f0
jmp 0xac50
leaq -0x380(%rbp), %rdi
callq 0x45d8
movq -0x3f0(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
leaq -0x360(%rbp), %rdx
callq 0x9580
jmp 0xac78
movq -0x318(%rbp), %rax
movq (%rax), %rsi
movq -0x2f8(%rbp), %rdx
leaq -0x390(%rbp), %rdi
callq 0xc980
jmp 0xac97
leaq -0x2f0(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0xc950
jmp 0xacac
movq -0x318(%rbp), %rdi
addq $0x10, %rdi
callq 0x4490
addq $0x18, %rax
addq -0x2f8(%rbp), %rax
movq %rax, -0x2f8(%rbp)
leaq -0x360(%rbp), %rdi
callq 0xc9b0
leaq -0x308(%rbp), %rdi
callq 0xd560
jmp 0xab91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0xaf7d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x380(%rbp), %rdi
callq 0x45d8
jmp 0xaf7d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x360(%rbp), %rdi
callq 0xc9b0
jmp 0xaf7d
leaq -0x2f0(%rbp), %rax
movq %rax, -0x398(%rbp)
movq -0x398(%rbp), %rdi
callq 0xc9d0
movq %rax, -0x3a0(%rbp)
movq -0x398(%rbp), %rdi
callq 0xca00
movq %rax, -0x3a8(%rbp)
leaq -0x3a0(%rbp), %rdi
leaq -0x3a8(%rbp), %rsi
callq 0xca30
testb $0x1, %al
jne 0xad83
jmp 0xaddd
leaq -0x3a0(%rbp), %rdi
callq 0xca70
movups (%rax), %xmm0
movaps %xmm0, -0x3c0(%rbp)
leaq -0x2c0(%rbp), %rdi
leaq -0x3c0(%rbp), %rsi
movl $0x8, %edx
callq 0x4420
jmp 0xadb3
leaq -0x2c0(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
movl $0x8, %edx
callq 0x4420
jmp 0xadcd
jmp 0xadcf
leaq -0x3a0(%rbp), %rdi
callq 0xca90
jmp 0xad6a
leaq -0x2c0(%rbp), %rdi
leaq -0x2f8(%rbp), %rsi
movl $0x8, %edx
callq 0x4420
jmp 0xadf7
leaq -0x2d0(%rbp), %rdi
callq 0x4050
jmp 0xae05
movq -0x3f0(%rbp), %rdi
addq $0x40, %rdi
movq %rdi, -0x430(%rbp)
callq 0xccb0
movq -0x3f0(%rbp), %rdi
movq %rax, -0x3d8(%rbp)
leaq -0x8(%rbp), %rsi
callq 0xafb0
movl %eax, -0x424(%rbp)
jmp 0xae3b
movl -0x424(%rbp), %eax
movslq %eax, %rsi
leaq -0x3d8(%rbp), %rdi
callq 0xd580
movq %rax, -0x3d0(%rbp)
leaq -0x3c8(%rbp), %rdi
leaq -0x3d0(%rbp), %rsi
callq 0xcce0
movq -0x430(%rbp), %rdi
movq -0x3c8(%rbp), %rsi
leaq -0x2f0(%rbp), %rdx
callq 0xcab0
movq %rax, -0x438(%rbp)
jmp 0xae8d
movq -0x3f0(%rbp), %rdi
movq -0x438(%rbp), %rax
movq %rax, -0x3e0(%rbp)
addq $0x60, %rdi
callq 0xcd80
cmpl -0x8(%rbp), %eax
jg 0xaed5
movq -0x3f0(%rbp), %rdi
addq $0x60, %rdi
movl $0x0, -0x3e4(%rbp)
leaq -0x3e4(%rbp), %rsi
callq 0xb720
jmp 0xaed3
jmp 0xaed5
cmpl $0x0, -0x8(%rbp)
jl 0xaef6
movq -0x3f0(%rbp), %rdi
addq $0x60, %rdi
movslq -0x8(%rbp), %rsi
callq 0xc0e0
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq 0x140a3(%rip), %rdi     # 0x1efa0
leaq 0xb47e(%rip), %rsi      # 0x16382
callq 0x42f0
movq %rax, -0x440(%rbp)
jmp 0xaf12
movq -0x440(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x42c0
movq %rax, -0x448(%rbp)
jmp 0xaf2b
movq -0x448(%rbp), %rdi
movq 0x14077(%rip), %rsi     # 0x1efb0
callq 0x4320
jmp 0xaf40
leaq -0x2f0(%rbp), %rdi
callq 0xcd20
movl $0x0, -0x2d4(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x4080
leaq -0x60(%rbp), %rdi
callq 0x45d8
leaq -0x40(%rbp), %rdi
callq 0x45d8
addq $0x450, %rsp            # imm = 0x450
popq %rbp
retq
leaq -0x2f0(%rbp), %rdi
callq 0xcd20
leaq -0x2d0(%rbp), %rdi
callq 0x4080
leaq -0x60(%rbp), %rdi
callq 0x45d8
leaq -0x40(%rbp), %rdi
callq 0x45d8
movq -0x68(%rbp), %rdi
callq 0x4530