// File: xx01cyx[P]LSM-Tree/kvstore.cc
// Function: KVStore::generateNewSST(std::vector<unsigned long, std::allocator<unsigned long>> const&, std::unordered_map<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>> const&, unsigned long, unsigned long)
SSTPtr KVStore::generateNewSST(const vector<LsmKey> &keys, const KVPair& data,
                               size_t level, TimeStamp maxTimeStamp) {

    // Create the directory.
    string pathname = "./data/level-" + to_string(level) + "/";
    utils::mkdir(pathname.c_str());

    // Open the output file.
    string filename = pathname + "table-" + to_string(maxTimeStamp)
                      + "-" + to_string(keys.front())
                      + "-" + to_string(keys.back())
                      + ".sst";
    ofstream out(filename, ios::out | ios::binary);
    if (!out.is_open()) {
        cerr << "Open file failed." << endl;
        exit(-1);
    }

    // Initialize.
    size_t keyNumber = keys.size();
    SSTHeader sstHeader = SSTHeader(maxTimeStamp, keyNumber, keys.front(), keys.back());
    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;

    // Write header into the file.
    out.write((char*)&sstHeader, HEADER_SIZE);

    // Set the file position to tha start of data index.
    out.seekp(dataIndexStart, ios::beg);

    // Write data indexes into the file.
    uint32_t offset = dataStart;
    for (const auto& key : keys) {
        out.write((char*)&key, sizeof(key));
        out.write((char*)&offset, sizeof(offset));

        bloomFilter.insert(key);
        DataIndex dataIndex = DataIndex(key, offset);
        dataIndexes.push_back(dataIndex);

        offset += data.at(key).size();
    }

    // Write data into the file.
    for (const auto& key: keys) {
        LsmValue value = data.at(key);
        out.write((char*)&value[0], value.size());
    }

    // Write bloom filter into the file.
    out.seekp(HEADER_SIZE, ios::beg);
    out.write((char*)(bloomFilter.byteArray), BLOOM_FILTER_SIZE);

    // Close the file.
    out.close();

    // Return an SST.
    SSTPtr sst = make_shared<SSTable>(level, sstHeader, bloomFilter, dataIndexes);
    return sst;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x500, %rsp            # imm = 0x500
movq %rdi, -0x4c0(%rbp)
movq %rdi, %rax
movq %rax, -0x4b8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x88(%rbp), %rdi
movq %rdi, -0x4b0(%rbp)
callq 0x9ed0
movq -0x4b0(%rbp), %rdx
leaq 0xf7d9(%rip), %rsi      # 0x231ae
leaq -0x68(%rbp), %rdi
callq 0x9e80
jmp 0x139e0
leaq 0xf8cb(%rip), %rdx      # 0x232b2
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x9d60
jmp 0x139f6
leaq -0x68(%rbp), %rdi
callq 0x4608
leaq -0x88(%rbp), %rdi
callq 0x4608
leaq -0x48(%rbp), %rdi
callq 0x4100
movq %rax, %rdi
callq 0xff90
jmp 0x13a1e
leaq 0xf798(%rip), %rdx      # 0x231bd
leaq -0x178(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0xd110
jmp 0x13a37
movq -0x28(%rbp), %rsi
leaq -0x198(%rbp), %rdi
callq 0x9ed0
jmp 0x13a49
leaq -0x158(%rbp), %rdi
leaq -0x178(%rbp), %rsi
leaq -0x198(%rbp), %rdx
callq 0x9db0
jmp 0x13a65
leaq 0xf756(%rip), %rdx      # 0x231c2
leaq -0x138(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0x9d60
jmp 0x13a81
movq -0x10(%rbp), %rdi
callq 0x17000
movq (%rax), %rsi
leaq -0x1b8(%rbp), %rdi
callq 0x9ed0
jmp 0x13a9b
leaq -0x118(%rbp), %rdi
leaq -0x138(%rbp), %rsi
leaq -0x1b8(%rbp), %rdx
callq 0x9db0
jmp 0x13ab7
leaq 0xf704(%rip), %rdx      # 0x231c2
leaq -0xf8(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x9d60
jmp 0x13ad3
movq -0x10(%rbp), %rdi
callq 0x17030
movq (%rax), %rsi
leaq -0x1d8(%rbp), %rdi
callq 0x9ed0
jmp 0x13aed
leaq -0xd8(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
leaq -0x1d8(%rbp), %rdx
callq 0x9db0
jmp 0x13b09
leaq 0xf6b4(%rip), %rdx      # 0x231c4
leaq -0xb8(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x9d60
jmp 0x13b25
leaq -0xd8(%rbp), %rdi
callq 0x4608
leaq -0x1d8(%rbp), %rdi
callq 0x4608
leaq -0xf8(%rbp), %rdi
callq 0x4608
leaq -0x118(%rbp), %rdi
callq 0x4608
leaq -0x1b8(%rbp), %rdi
callq 0x4608
leaq -0x138(%rbp), %rdi
callq 0x4608
leaq -0x158(%rbp), %rdi
callq 0x4608
leaq -0x198(%rbp), %rdi
callq 0x4608
leaq -0x178(%rbp), %rdi
callq 0x4608
movl $0x10, %edi
movl $0x4, %esi
callq 0x9bb0
movl %eax, -0x4c4(%rbp)
jmp 0x13ba8
movl -0x4c4(%rbp), %edx
leaq -0x3d8(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x45c0
jmp 0x13bc3
leaq -0x3d8(%rbp), %rdi
callq 0x4210
movb %al, -0x4c5(%rbp)
jmp 0x13bd7
movb -0x4c5(%rbp), %al
testb $0x1, %al
jne 0x13dd6
jmp 0x13be7
movq 0x1e402(%rip), %rdi     # 0x31ff0
leaq 0xf6bf(%rip), %rsi      # 0x232b4
callq 0x42c0
movq %rax, -0x4d0(%rbp)
jmp 0x13c03
movq -0x4d0(%rbp), %rdi
movq 0x1e39f(%rip), %rsi     # 0x31fb0
callq 0x4300
jmp 0x13c18
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x4360
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13c51
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x4608
leaq -0x88(%rbp), %rdi
callq 0x4608
jmp 0x14224
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x1421b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13d97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13d8b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13d7f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13d73
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13d67
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13d5b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13d4f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x13d43
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x4608
leaq -0x1d8(%rbp), %rdi
callq 0x4608
leaq -0xf8(%rbp), %rdi
callq 0x4608
leaq -0x118(%rbp), %rdi
callq 0x4608
leaq -0x1b8(%rbp), %rdi
callq 0x4608
leaq -0x138(%rbp), %rdi
callq 0x4608
leaq -0x158(%rbp), %rdi
callq 0x4608
leaq -0x198(%rbp), %rdi
callq 0x4608
leaq -0x178(%rbp), %rdi
callq 0x4608
jmp 0x1421b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x1420f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x14203
movq -0x10(%rbp), %rdi
callq 0x6920
movq %rax, -0x3e0(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x4e8(%rbp)
movq -0x3e0(%rbp), %rax
movq %rax, -0x4e0(%rbp)
movq -0x10(%rbp), %rdi
callq 0x17000
movq (%rax), %rax
movq %rax, -0x4d8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x17030
movq -0x4e8(%rbp), %rsi
movq -0x4e0(%rbp), %rdx
movq -0x4d8(%rbp), %rcx
movq (%rax), %r8
leaq -0x400(%rbp), %rdi
callq 0xd260
jmp 0x13e41
leaq -0x408(%rbp), %rdi
callq 0x80f0
jmp 0x13e4f
xorps %xmm0, %xmm0
movaps %xmm0, -0x420(%rbp)
movq $0x0, -0x410(%rbp)
leaq -0x420(%rbp), %rdi
callq 0xd1a0
movl $0x2820, -0x424(%rbp)   # imm = 0x2820
movl -0x3e0(%rbp), %ecx
movl %ecx, %eax
leal (%rax,%rax,2), %ecx
movl %ecx, %eax
leal 0x2820(,%rax,4), %eax
movl %eax, -0x428(%rbp)
leaq -0x3d8(%rbp), %rdi
leaq -0x400(%rbp), %rsi
movl $0x20, %edx
callq 0x43d0
jmp 0x13eae
movl -0x424(%rbp), %eax
movl %eax, %esi
leaq -0x3d8(%rbp), %rdi
xorl %edx, %edx
callq 0x42d0
jmp 0x13ec6
movl -0x428(%rbp), %eax
movl %eax, -0x42c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x438(%rbp)
movq -0x438(%rbp), %rdi
callq 0x17070
movq %rax, -0x440(%rbp)
movq -0x438(%rbp), %rdi
callq 0x170a0
movq %rax, -0x448(%rbp)
leaq -0x440(%rbp), %rdi
leaq -0x448(%rbp), %rsi
callq 0x170d0
testb $0x1, %al
jne 0x13f1f
jmp 0x14010
leaq -0x440(%rbp), %rdi
callq 0x17110
movq %rax, -0x450(%rbp)
movq -0x450(%rbp), %rsi
leaq -0x3d8(%rbp), %rdi
movl $0x8, %edx
callq 0x43d0
jmp 0x13f4c
leaq -0x3d8(%rbp), %rdi
leaq -0x42c(%rbp), %rsi
movl $0x4, %edx
callq 0x43d0
jmp 0x13f66
movq -0x450(%rbp), %rax
movq (%rax), %rsi
leaq -0x408(%rbp), %rdi
callq 0x81a0
jmp 0x13f7e
movq -0x450(%rbp), %rax
movq (%rax), %rsi
movl -0x42c(%rbp), %edx
leaq -0x460(%rbp), %rdi
callq 0xd1c0
jmp 0x13f9c
leaq -0x420(%rbp), %rdi
leaq -0x460(%rbp), %rsi
callq 0xd1f0
jmp 0x13fb1
movq -0x18(%rbp), %rdi
movq -0x450(%rbp), %rsi
callq 0x16c40
movq %rax, -0x4f0(%rbp)
jmp 0x13fca
movq -0x4f0(%rbp), %rdi
callq 0x41e0
movq %rax, %rcx
movl -0x42c(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x42c(%rbp)
leaq -0x440(%rbp), %rdi
callq 0x17130
jmp 0x13f03
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x141eb
movq -0x10(%rbp), %rax
movq %rax, -0x468(%rbp)
movq -0x468(%rbp), %rdi
callq 0x17070
movq %rax, -0x470(%rbp)
movq -0x468(%rbp), %rdi
callq 0x170a0
movq %rax, -0x478(%rbp)
leaq -0x470(%rbp), %rdi
leaq -0x478(%rbp), %rsi
callq 0x170d0
testb $0x1, %al
jne 0x1405d
jmp 0x1411b
leaq -0x470(%rbp), %rdi
callq 0x17110
movq %rax, -0x480(%rbp)
movq -0x18(%rbp), %rdi
movq -0x480(%rbp), %rsi
callq 0x16c40
movq %rax, -0x4f8(%rbp)
jmp 0x14089
movq -0x4f8(%rbp), %rsi
leaq -0x4a0(%rbp), %rdi
callq 0x4120
jmp 0x1409e
xorl %eax, %eax
movl %eax, %esi
leaq -0x4a0(%rbp), %rdi
callq 0x45f0
movq %rax, -0x500(%rbp)
jmp 0x140b7
leaq -0x4a0(%rbp), %rdi
callq 0x41e0
movq -0x500(%rbp), %rsi
movq %rax, %rdx
leaq -0x3d8(%rbp), %rdi
callq 0x43d0
jmp 0x140db
leaq -0x4a0(%rbp), %rdi
callq 0x4608
leaq -0x470(%rbp), %rdi
callq 0x17130
jmp 0x14041
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x4a0(%rbp), %rdi
callq 0x4608
jmp 0x141eb
leaq -0x3d8(%rbp), %rdi
movl $0x20, %esi
xorl %edx, %edx
callq 0x42d0
jmp 0x14130
movq -0x408(%rbp), %rsi
leaq -0x3d8(%rbp), %rdi
movl $0x2800, %edx           # imm = 0x2800
callq 0x43d0
jmp 0x1414a
leaq -0x3d8(%rbp), %rdi
callq 0x4440
jmp 0x14158
movq -0x4c0(%rbp), %rdi
movb $0x0, -0x4a1(%rbp)
leaq -0x20(%rbp), %rsi
leaq -0x400(%rbp), %rdx
leaq -0x408(%rbp), %rcx
leaq -0x420(%rbp), %r8
callq 0x16490
jmp 0x14186
movb $0x1, -0x4a1(%rbp)
testb $0x1, -0x4a1(%rbp)
jne 0x141a2
movq -0x4c0(%rbp), %rdi
callq 0xd350
leaq -0x420(%rbp), %rdi
callq 0x9b30
leaq -0x408(%rbp), %rdi
callq 0x8190
leaq -0x3d8(%rbp), %rdi
callq 0x4470
leaq -0xb8(%rbp), %rdi
callq 0x4608
leaq -0x48(%rbp), %rdi
callq 0x4608
movq -0x4b8(%rbp), %rax
addq $0x500, %rsp            # imm = 0x500
popq %rbp
retq
leaq -0x420(%rbp), %rdi
callq 0x9b30
leaq -0x408(%rbp), %rdi
callq 0x8190
leaq -0x3d8(%rbp), %rdi
callq 0x4470
leaq -0xb8(%rbp), %rdi
callq 0x4608
leaq -0x48(%rbp), %rdi
callq 0x4608
movq -0x90(%rbp), %rdi
callq 0x4560