// File: xx01cyx[P]LSM-Tree/MemTable.cc
// Function: MemTable::writeToDisk(unsigned long)
SSTPtr MemTable::writeToDisk(TimeStamp timeStamp) {

    // Create the directory.
    string pathname = "./data/level-0/";
    utils::mkdir(pathname.c_str());

    // Open the output file.
    string filename = pathname + "table-" + to_string(timeStamp) + ".sst";
    ofstream out(filename, ios::out | ios::binary);
    if (!out.is_open()) {
        cerr << "Open file failed." << endl;
        exit(-1);
    }

    // Initialize.
    SSTHeader sstHeader;
    BloomFilter bloomFilter;
    vector<DataIndex> dataIndexes = vector<DataIndex>();
    uint32_t dataIndexStart = HEADER_SIZE + BLOOM_FILTER_SIZE;
    uint32_t dataStart = HEADER_SIZE + BLOOM_FILTER_SIZE + DATA_INDEX_SIZE * keyNumber;

    // Set the file position to tha start of data index.
    out.seekp(dataIndexStart, ios::beg);

    // Write data indexes into the file.
    Node* q = getLowestHead();
    Node* p = q;
    uint32_t offset = dataStart;
    while (p->next) {
        LsmKey k = p->next->key;
        LsmValue v = p->next->value;

        out.write((char*)&k, sizeof(k));
        out.write((char*)&offset, sizeof(offset));

        bloomFilter.insert(k);
        DataIndex dataIndex = DataIndex(k, offset);
        dataIndexes.push_back(dataIndex);

        offset += v.size();
        p = p->next;
    }

    // After the loop, p now points to the max key.
    sstHeader = SSTHeader(timeStamp, keyNumber, q->next->key, p->key);

    // Set the file position to the beginning.
    out.seekp(0, ios::beg);

    // Write header and bloom filter into the file.
    out.write((char*)&sstHeader, HEADER_SIZE);
    out.write((char*)(bloomFilter.byteArray), BLOOM_FILTER_SIZE);

    // Set the file position to the start of data.
    out.seekp(dataStart, ios::beg);

    // Write data into the file.
    while (q->next) {
        LsmValue v = q->next->value;
        out.write((char*)&v[0], v.size());
        q = q->next;
    }

    // Close the file.
    out.close();

    // Create an SST in the memory.
    SSTPtr sst = make_shared<SSTable>(0, sstHeader, bloomFilter, dataIndexes);

    // Rename the file.
    string newFilename = sst->getFilename();
    rename(filename.c_str(), newFilename.c_str());

    return sst;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x420, %rsp            # imm = 0x420
movq %rdi, -0x3f0(%rbp)
movq %rdi, %rax
movq %rax, -0x3e8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x3e0(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0x3d8(%rbp)
callq 0x4570
movq -0x3d8(%rbp), %rdx
leaq 0x16d83(%rip), %rsi     # 0x232a4
leaq -0x38(%rbp), %rdi
callq 0x4b40
jmp 0xc52c
leaq -0x39(%rbp), %rdi
callq 0x4320
leaq -0x38(%rbp), %rdi
callq 0x4100
movq %rax, %rdi
callq 0xcba0
jmp 0xc548
leaq 0x16c6e(%rip), %rdx     # 0x231bd
leaq -0xb0(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0xd110
jmp 0xc561
movq -0x18(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0x9ed0
jmp 0xc573
leaq -0x90(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
leaq -0xd0(%rbp), %rdx
callq 0x9db0
jmp 0xc58f
leaq 0x16c2e(%rip), %rdx     # 0x231c4
leaq -0x70(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x9d60
jmp 0xc5a8
leaq -0x90(%rbp), %rdi
callq 0x4608
leaq -0xd0(%rbp), %rdi
callq 0x4608
leaq -0xb0(%rbp), %rdi
callq 0x4608
movl $0x10, %edi
movl $0x4, %esi
callq 0x9bb0
movl %eax, -0x3f4(%rbp)
jmp 0xc5e3
movl -0x3f4(%rbp), %edx
leaq -0x2d0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x45c0
jmp 0xc5fb
leaq -0x2d0(%rbp), %rdi
callq 0x4210
movb %al, -0x3f5(%rbp)
jmp 0xc60f
movb -0x3f5(%rbp), %al
testb $0x1, %al
jne 0xc6f8
jmp 0xc61f
movq 0x259ca(%rip), %rdi     # 0x31ff0
leaq 0x16c87(%rip), %rsi     # 0x232b4
callq 0x42c0
movq %rax, -0x400(%rbp)
jmp 0xc63b
movq -0x400(%rbp), %rdi
movq 0x25967(%rip), %rsi     # 0x31fb0
callq 0x4300
jmp 0xc650
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x4360
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x39(%rbp), %rdi
callq 0x4320
jmp 0xcb8c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xcb83
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xc6c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xc6b9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x4608
leaq -0xd0(%rbp), %rdi
callq 0x4608
leaq -0xb0(%rbp), %rdi
callq 0x4608
jmp 0xcb83
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xcb7a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xcb6e
leaq -0x2f0(%rbp), %rdi
callq 0xd190
jmp 0xc706
leaq -0x2f8(%rbp), %rdi
callq 0x80f0
jmp 0xc714
xorps %xmm0, %xmm0
movaps %xmm0, -0x310(%rbp)
movq $0x0, -0x300(%rbp)
leaq -0x310(%rbp), %rdi
callq 0xd1a0
movq -0x3e0(%rbp), %rax
movl $0x2820, -0x314(%rbp)   # imm = 0x2820
movl 0x8(%rax), %ecx
movl %ecx, %eax
leal (%rax,%rax,2), %ecx
movl %ecx, %eax
leal 0x2820(,%rax,4), %eax
movl %eax, -0x318(%rbp)
movl -0x314(%rbp), %eax
movl %eax, %esi
leaq -0x2d0(%rbp), %rdi
xorl %edx, %edx
callq 0x42d0
jmp 0xc775
movq -0x3e0(%rbp), %rdi
callq 0xce60
movq %rax, -0x408(%rbp)
jmp 0xc78a
movq -0x408(%rbp), %rax
movq %rax, -0x320(%rbp)
movq -0x320(%rbp), %rax
movq %rax, -0x328(%rbp)
movl -0x318(%rbp), %eax
movl %eax, -0x32c(%rbp)
movq -0x328(%rbp), %rax
cmpq $0x0, 0x28(%rax)
je 0xc8de
movq -0x328(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rax
movq %rax, -0x338(%rbp)
movq -0x328(%rbp), %rax
movq 0x28(%rax), %rsi
addq $0x8, %rsi
leaq -0x358(%rbp), %rdi
callq 0x4120
jmp 0xc7f6
leaq -0x2d0(%rbp), %rdi
leaq -0x338(%rbp), %rsi
movl $0x8, %edx
callq 0x43d0
jmp 0xc810
leaq -0x2d0(%rbp), %rdi
leaq -0x32c(%rbp), %rsi
movl $0x4, %edx
callq 0x43d0
jmp 0xc82a
movq -0x338(%rbp), %rsi
leaq -0x2f8(%rbp), %rdi
callq 0x81a0
jmp 0xc83f
movq -0x338(%rbp), %rsi
movl -0x32c(%rbp), %edx
leaq -0x368(%rbp), %rdi
callq 0xd1c0
jmp 0xc85a
leaq -0x310(%rbp), %rdi
leaq -0x368(%rbp), %rsi
callq 0xd1f0
jmp 0xc86f
leaq -0x358(%rbp), %rdi
callq 0x41e0
movq %rax, %rcx
movl -0x32c(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x32c(%rbp)
movq -0x328(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x328(%rbp)
leaq -0x358(%rbp), %rdi
callq 0x4608
jmp 0xc7b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xcb56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x358(%rbp), %rdi
callq 0x4608
jmp 0xcb56
movq -0x3e0(%rbp), %rax
movq -0x18(%rbp), %rsi
movq 0x8(%rax), %rdx
movq -0x320(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rcx
movq -0x328(%rbp), %rax
movq (%rax), %r8
leaq -0x388(%rbp), %rdi
callq 0xd260
jmp 0xc913
movups -0x388(%rbp), %xmm0
movups -0x378(%rbp), %xmm1
movaps %xmm1, -0x2e0(%rbp)
movaps %xmm0, -0x2f0(%rbp)
xorl %edx, %edx
movl %edx, %esi
leaq -0x2d0(%rbp), %rdi
callq 0x42d0
jmp 0xc941
leaq -0x2d0(%rbp), %rdi
leaq -0x2f0(%rbp), %rsi
movl $0x20, %edx
callq 0x43d0
jmp 0xc95b
movq -0x2f8(%rbp), %rsi
leaq -0x2d0(%rbp), %rdi
movl $0x2800, %edx           # imm = 0x2800
callq 0x43d0
jmp 0xc975
movl -0x318(%rbp), %eax
movl %eax, %esi
leaq -0x2d0(%rbp), %rdi
xorl %edx, %edx
callq 0x42d0
jmp 0xc98d
jmp 0xc98f
movq -0x320(%rbp), %rax
cmpq $0x0, 0x28(%rax)
je 0xca3b
movq -0x320(%rbp), %rax
movq 0x28(%rax), %rsi
addq $0x8, %rsi
leaq -0x3a8(%rbp), %rdi
callq 0x4120
jmp 0xc9be
xorl %eax, %eax
movl %eax, %esi
leaq -0x3a8(%rbp), %rdi
callq 0x45f0
movq %rax, -0x410(%rbp)
jmp 0xc9d7
leaq -0x3a8(%rbp), %rdi
callq 0x41e0
movq -0x410(%rbp), %rsi
movq %rax, %rdx
leaq -0x2d0(%rbp), %rdi
callq 0x43d0
jmp 0xc9fb
movq -0x320(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x320(%rbp)
leaq -0x3a8(%rbp), %rdi
callq 0x4608
jmp 0xc98f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x3a8(%rbp), %rdi
callq 0x4608
jmp 0xcb56
leaq -0x2d0(%rbp), %rdi
callq 0x4440
jmp 0xca49
movq -0x3f0(%rbp), %rdi
movb $0x0, -0x3a9(%rbp)
movl $0x0, -0x3b0(%rbp)
leaq -0x3b0(%rbp), %rsi
leaq -0x2f0(%rbp), %rdx
leaq -0x2f8(%rbp), %rcx
leaq -0x310(%rbp), %r8
callq 0xd2a0
jmp 0xca84
movq -0x3f0(%rbp), %rdi
callq 0xd330
movq %rax, %rsi
leaq -0x3d0(%rbp), %rdi
callq 0x9070
jmp 0xcaa1
leaq -0x70(%rbp), %rdi
callq 0x4100
movq %rax, -0x418(%rbp)
leaq -0x3d0(%rbp), %rdi
callq 0x4100
movq -0x418(%rbp), %rdi
movq %rax, %rsi
callq 0x41b0
movb $0x1, -0x3a9(%rbp)
leaq -0x3d0(%rbp), %rdi
callq 0x4608
testb $0x1, -0x3a9(%rbp)
jne 0xcb10
jmp 0xcb04
movq -0x3f0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0xd350
jmp 0xcb56
movq -0x3f0(%rbp), %rdi
callq 0xd350
leaq -0x310(%rbp), %rdi
callq 0x9b30
leaq -0x2f8(%rbp), %rdi
callq 0x8190
leaq -0x2d0(%rbp), %rdi
callq 0x4470
leaq -0x70(%rbp), %rdi
callq 0x4608
leaq -0x38(%rbp), %rdi
callq 0x4608
movq -0x3e8(%rbp), %rax
addq $0x420, %rsp            # imm = 0x420
popq %rbp
retq
leaq -0x310(%rbp), %rdi
callq 0x9b30
leaq -0x2f8(%rbp), %rdi
callq 0x8190
leaq -0x2d0(%rbp), %rdi
callq 0x4470
leaq -0x70(%rbp), %rdi
callq 0x4608
leaq -0x38(%rbp), %rdi
callq 0x4608
movq -0x48(%rbp), %rdi
callq 0x4560
nopw %cs:(%rax,%rax)