// File: SeanChao[P]KV-Store/kvstore.cc
// Function: KVStore::convertMemTable()
void KVStore::convertMemTable() {
    // get pointer to the head of linked list from SkipList. Beware that the
    // last non-nullptr pointer would be the tail, which contains no meaningful
    // data
    std::shared_ptr<typename SkipList<uint64_t, std::string>::Node> p =
        memTable->exportData();
    // while ((p = p->succ) && memTable->valid(p)) std::clog << p->key << "\n";
    std::string lv = resolvePath(0);
    std::string filename = resolvePath(0, 0);
    std::filesystem::create_directories(lv);
    renameLevel(0, 0);
    std::fstream fs(filename, std::ios::out | std::ios::binary);
    // prepares the cache for index data
    std::vector<Index> indexTable;
    uint64_t offset = 0;
    // writes the data segment
    while ((p = p->succ) && memTable->valid(p)) {
        // std::clog << "write key = " << p->key << std::endl;
        // convert to char * on demand
        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
        //   << " tellp: " << fs.tellp() << 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));
    indexTableList.insert(indexTableList.begin(), indexTable);
    fs.close();
    renameLevel(0, 1);
    std::clog << "memTable -> " << filename << std::endl;
    // update state
    fileNum[0]++;
    // compaction if the number of files in level 0 is more than 2
    if (fileNum[0] > 2) compaction();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x400, %rsp            # imm = 0x400
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x3a0(%rbp)
addq $0x38, %rdi
callq 0xb830
movq %rax, %rsi
leaq -0x18(%rbp), %rdi
callq 0xc6f0
movq -0x3a0(%rbp), %rsi
leaq -0x38(%rbp), %rdi
xorl %edx, %edx
callq 0x8b40
jmp 0x7643
movq -0x3a0(%rbp), %rsi
leaq -0x68(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x8330
jmp 0x7659
leaq -0x90(%rbp), %rdi
leaq -0x38(%rbp), %rsi
movl $0x2, %edx
callq 0xc5a0
jmp 0x7670
leaq -0x90(%rbp), %rdi
callq 0x4200
jmp 0x767e
leaq -0x90(%rbp), %rdi
callq 0xc680
movq -0x3a0(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x8cf0
jmp 0x769c
movl $0x10, %edi
movl $0x4, %esi
callq 0xc770
movl %eax, -0x3a4(%rbp)
jmp 0x76b3
movl -0x3a4(%rbp), %edx
leaq -0x2a0(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x44f0
jmp 0x76cb
leaq -0x2b8(%rbp), %rdi
callq 0xc790
movq $0x0, -0x2c0(%rbp)
leaq -0x18(%rbp), %rdi
callq 0xc7b0
movq %rax, %rsi
addq $0x38, %rsi
leaq -0x18(%rbp), %rdi
callq 0xc7d0
movq %rax, %rdi
callq 0xc800
movb %al, %cl
movb $0x0, -0x2d1(%rbp)
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x3a5(%rbp)
jne 0x771b
jmp 0x7779
movq -0x3a0(%rbp), %rdi
addq $0x38, %rdi
callq 0xb830
movq %rax, -0x3b8(%rbp)
leaq -0x2d0(%rbp), %rdi
movq %rdi, -0x3b0(%rbp)
leaq -0x18(%rbp), %rsi
callq 0xc8a0
movq -0x3b8(%rbp), %rdi
movq -0x3b0(%rbp), %rsi
movb $0x1, -0x2d1(%rbp)
callq 0xc820
movb %al, -0x3a6(%rbp)
jmp 0x776b
movb -0x3a6(%rbp), %al
movb %al, -0x3a5(%rbp)
jmp 0x7779
movb -0x3a5(%rbp), %al
movb %al, -0x3b9(%rbp)
testb $0x1, -0x2d1(%rbp)
jne 0x7790
jmp 0x779c
leaq -0x2d0(%rbp), %rdi
callq 0xc8d0
movb -0x3b9(%rbp), %al
testb $0x1, %al
jne 0x77ab
jmp 0x79b4
leaq -0x18(%rbp), %rdi
movq %rdi, -0x3e0(%rbp)
callq 0xc7b0
movq %rax, %rdi
addq $0x8, %rdi
callq 0x4490
movq %rax, -0x2e0(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0x42d0
movq -0x3e0(%rbp), %rdi
movq %rax, -0x2e8(%rbp)
callq 0xc7b0
movq -0x3e0(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x3d8(%rbp)
movq -0x2e8(%rbp), %rax
movq %rax, -0x3d0(%rbp)
movq -0x2e0(%rbp), %rax
movq %rax, -0x3c8(%rbp)
callq 0xc7b0
movq %rax, %rsi
addq $0x8, %rsi
leaq -0x340(%rbp), %rdi
callq 0x4170
jmp 0x7831
movq -0x3c8(%rbp), %rcx
movq -0x3d0(%rbp), %rdx
movq -0x3d8(%rbp), %rsi
leaq -0x320(%rbp), %rdi
leaq -0x340(%rbp), %r8
callq 0xc8f0
jmp 0x785b
leaq -0x340(%rbp), %rdi
callq 0x45d8
movq -0x3a0(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
leaq -0x320(%rbp), %rdx
callq 0x9580
jmp 0x7883
leaq -0x18(%rbp), %rdi
callq 0xc7b0
movq (%rax), %rsi
movq -0x2c0(%rbp), %rdx
leaq -0x350(%rbp), %rdi
callq 0xc980
jmp 0x78a4
leaq -0x2b8(%rbp), %rdi
leaq -0x350(%rbp), %rsi
callq 0xc950
jmp 0x78b9
leaq -0x18(%rbp), %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x8, %rdi
callq 0x4490
addq $0x18, %rax
addq -0x2c0(%rbp), %rax
movq %rax, -0x2c0(%rbp)
leaq -0x320(%rbp), %rdi
callq 0xc9b0
jmp 0x76e2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x7bf0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x7be7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x7bde
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x90(%rbp), %rdi
callq 0xc680
jmp 0x7bde
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
testb $0x1, -0x2d1(%rbp)
jne 0x7958
jmp 0x7964
leaq -0x2d0(%rbp), %rdi
callq 0xc8d0
jmp 0x7bc6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x7bc6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x340(%rbp), %rdi
callq 0x45d8
jmp 0x7bc6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x320(%rbp), %rdi
callq 0xc9b0
jmp 0x7bc6
leaq -0x2b8(%rbp), %rax
movq %rax, -0x358(%rbp)
movq -0x358(%rbp), %rdi
callq 0xc9d0
movq %rax, -0x360(%rbp)
movq -0x358(%rbp), %rdi
callq 0xca00
movq %rax, -0x368(%rbp)
leaq -0x360(%rbp), %rdi
leaq -0x368(%rbp), %rsi
callq 0xca30
testb $0x1, %al
jne 0x7a01
jmp 0x7a5b
leaq -0x360(%rbp), %rdi
callq 0xca70
movups (%rax), %xmm0
movaps %xmm0, -0x380(%rbp)
leaq -0x290(%rbp), %rdi
leaq -0x380(%rbp), %rsi
movl $0x8, %edx
callq 0x4420
jmp 0x7a31
leaq -0x290(%rbp), %rdi
leaq -0x378(%rbp), %rsi
movl $0x8, %edx
callq 0x4420
jmp 0x7a4b
jmp 0x7a4d
leaq -0x360(%rbp), %rdi
callq 0xca90
jmp 0x79e8
leaq -0x290(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
movl $0x8, %edx
callq 0x4420
jmp 0x7a75
movq -0x3a0(%rbp), %rdi
addq $0x40, %rdi
movq %rdi, -0x3f0(%rbp)
callq 0xccb0
movq %rax, -0x390(%rbp)
leaq -0x388(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0xcce0
movq -0x3f0(%rbp), %rdi
movq -0x388(%rbp), %rsi
leaq -0x2b8(%rbp), %rdx
callq 0xcab0
movq %rax, -0x3e8(%rbp)
jmp 0x7ac9
movq -0x3e8(%rbp), %rax
movq %rax, -0x398(%rbp)
leaq -0x2a0(%rbp), %rdi
callq 0x4050
jmp 0x7ae5
movq -0x3a0(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x8cf0
jmp 0x7afa
movq 0x1749f(%rip), %rdi     # 0x1efa0
leaq 0xe859(%rip), %rsi      # 0x16361
callq 0x42f0
movq %rax, -0x3f8(%rbp)
jmp 0x7b16
movq -0x3f8(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x42c0
movq %rax, -0x400(%rbp)
jmp 0x7b2f
movq -0x400(%rbp), %rdi
movq 0x17473(%rip), %rsi     # 0x1efb0
callq 0x4320
jmp 0x7b44
movq -0x3a0(%rbp), %rdi
addq $0x60, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xc0e0
movq -0x3a0(%rbp), %rdi
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
addq $0x60, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xc0e0
cmpl $0x2, (%rax)
jle 0x7b8a
movq -0x3a0(%rbp), %rdi
xorl %esi, %esi
callq 0x9620
jmp 0x7b88
jmp 0x7b8a
leaq -0x2b8(%rbp), %rdi
callq 0xcd20
leaq -0x2a0(%rbp), %rdi
callq 0x4080
leaq -0x68(%rbp), %rdi
callq 0x45d8
leaq -0x38(%rbp), %rdi
callq 0x45d8
leaq -0x18(%rbp), %rdi
callq 0xc8d0
addq $0x400, %rsp            # imm = 0x400
popq %rbp
retq
leaq -0x2b8(%rbp), %rdi
callq 0xcd20
leaq -0x2a0(%rbp), %rdi
callq 0x4080
leaq -0x68(%rbp), %rdi
callq 0x45d8
leaq -0x38(%rbp), %rdi
callq 0x45d8
leaq -0x18(%rbp), %rdi
callq 0xc8d0
movq -0x40(%rbp), %rdi
callq 0x4530
nopw %cs:(%rax,%rax)