// File: rocket323[P]fishdb/./btree.cpp
// Function: fishdb::BTree::Maintain(std::shared_ptr<fishdb::MemPage>, std::shared_ptr<fishdb::MemPage>, int)
void BTree::Maintain(std::shared_ptr<MemPage> now, std::shared_ptr<MemPage> parent, int child_idx)
{
    size_t left_sep = (child_idx > 0) ? child_idx - 1 : -1;
    size_t right_sep = (child_idx < (int)parent->children.size() - 1) ? child_idx : -1;
    auto left = (child_idx > 0) ? ReadPage(parent->children[child_idx - 1]) : nil;
    auto right = (child_idx < (int)parent->children.size() - 1) ? ReadPage(parent->children[child_idx + 1]) : nil;

    // 1.
    if (left && (int)left->kvs.size() > m_min_key_num)
    {
        now->kvs.insert(now->kvs.begin(), parent->kvs[left_sep]);
        if (!left->is_leaf)
        {
            now->children.insert(now->children.begin(), left->children.back());
            left->children.pop_back();
        }
        parent->kvs[left_sep] = left->kvs.back();
        left->kvs.pop_back();
        return;
    }
    // 2.
    if (right && (int)right->kvs.size() > m_min_key_num)
    {
        now->kvs.push_back(parent->kvs[right_sep]);
        if (!right->is_leaf)
        {
            now->children.push_back(right->children.front());
            right->children.erase(right->children.begin());
        }
        parent->kvs[right_sep] = right->kvs.front();
        right->kvs.erase(right->kvs.begin());
        return;
    }
    // 3a.
    if (left)
    {
        left->kvs.push_back(parent->kvs[left_sep]);
        left->kvs.insert(left->kvs.end(), now->kvs.begin(), now->kvs.end());
        left->children.insert(left->children.end(), now->children.begin(), now->children.end());

        parent->kvs.erase(parent->kvs.begin() + left_sep);
        parent->children.erase(parent->children.begin() + left_sep + 1);
    }
    // 3b.
    else if (right)
    {
        now->kvs.push_back(parent->kvs[right_sep]);
        now->kvs.insert(now->kvs.end(), right->kvs.begin(), right->kvs.end());
        now->children.insert(now->children.end(), right->children.begin(), right->children.end());

        parent->kvs.erase(parent->kvs.begin() + right_sep);
        parent->children.erase(parent->children.begin() + right_sep + 1);
    }
    else
        assert(false);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x340, %rsp            # imm = 0x340
movq %rsi, -0x210(%rbp)
movq %rdx, -0x208(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x200(%rbp)
cmpl $0x0, -0x1c(%rbp)
jle 0x6c57
movl -0x1c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x214(%rbp)
jmp 0x6c64
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x214(%rbp)
jmp 0x6c64
movq -0x208(%rbp), %rdi
movl -0x214(%rbp), %eax
cltq
movq %rax, -0x28(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x218(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x7ec0
movq %rax, %rcx
movl -0x218(%rbp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x6cac
movl -0x1c(%rbp), %eax
movl %eax, -0x21c(%rbp)
jmp 0x6cb9
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x21c(%rbp)
jmp 0x6cb9
movl -0x21c(%rbp), %eax
cltq
movq %rax, -0x30(%rbp)
cmpl $0x0, -0x1c(%rbp)
jle 0x6d01
movq -0x208(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
movl -0x1c(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x41b0
movq -0x200(%rbp), %rsi
movq (%rax), %rdx
leaq -0x40(%rbp), %rdi
callq 0x5390
jmp 0x6d11
leaq -0x40(%rbp), %rdi
leaq 0x14514(%rip), %rsi     # 0x1b220
callq 0x40f0
movq -0x208(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, -0x220(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x7ec0
movq %rax, %rcx
movl -0x220(%rbp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x6d79
movq -0x208(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
movl -0x1c(%rbp), %eax
incl %eax
movslq %eax, %rsi
callq 0x41b0
movq -0x200(%rbp), %rsi
movq (%rax), %rdx
leaq -0x50(%rbp), %rdi
callq 0x5390
jmp 0x6d77
jmp 0x6d89
leaq -0x50(%rbp), %rdi
leaq 0x1449c(%rip), %rsi     # 0x1b220
callq 0x40f0
leaq -0x40(%rbp), %rdi
callq 0x50f0
testb $0x1, %al
jne 0x6d9b
jmp 0x6f8a
leaq -0x40(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4200
movq -0x200(%rbp), %rcx
cmpl 0x48(%rcx), %eax
jle 0x6f8a
movq -0x210(%rbp), %rdi
callq 0x4190
movq -0x210(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x230(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4310
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x7f20
movq -0x208(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
movq -0x28(%rbp), %rsi
callq 0x43f0
movq -0x230(%rbp), %rdi
movq %rax, %rdx
movq -0x68(%rbp), %rsi
callq 0x81e0
movq %rax, -0x228(%rbp)
jmp 0x6e38
movq -0x228(%rbp), %rax
movq %rax, -0x78(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x4190
testb $0x1, 0x79(%rax)
jne 0x6f1d
movq -0x210(%rbp), %rdi
callq 0x4190
movq -0x210(%rbp), %rdi
addq $0x48, %rax
movq %rax, -0x240(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x80b0
movq %rax, -0x88(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x8600
leaq -0x40(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x4260
movq -0x240(%rbp), %rdi
movq %rax, %rdx
movq -0x80(%rbp), %rsi
callq 0x8400
movq %rax, -0x238(%rbp)
jmp 0x6ecd
movq -0x238(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x8770
jmp 0x6f1d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x77f5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x27e0
jmp 0x77f5
leaq -0x40(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x8640
movq -0x208(%rbp), %rdi
movq %rax, -0x248(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
movq -0x28(%rbp), %rsi
callq 0x43f0
movq -0x248(%rbp), %rsi
movq %rax, %rdi
callq 0x8680
jmp 0x6f66
leaq -0x40(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x87a0
movl $0x1, -0x94(%rbp)
jmp 0x77da
leaq -0x50(%rbp), %rdi
callq 0x50f0
testb $0x1, %al
jne 0x6f9c
jmp 0x719b
leaq -0x50(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4200
movq -0x200(%rbp), %rcx
cmpl 0x48(%rcx), %eax
jle 0x719b
movq -0x210(%rbp), %rdi
callq 0x4190
movq -0x208(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x250(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
movq -0x30(%rbp), %rsi
callq 0x43f0
movq -0x250(%rbp), %rdi
movq %rax, %rsi
callq 0x87d0
jmp 0x7005
leaq -0x50(%rbp), %rdi
callq 0x4190
testb $0x1, 0x79(%rax)
jne 0x70cc
movq -0x210(%rbp), %rdi
callq 0x4190
addq $0x48, %rax
movq %rax, -0x258(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x88b0
movq -0x258(%rbp), %rdi
movq %rax, %rsi
callq 0x8840
jmp 0x7055
leaq -0x50(%rbp), %rdi
movq %rdi, -0x270(%rbp)
callq 0x4190
movq -0x270(%rbp), %rdi
addq $0x48, %rax
movq %rax, -0x268(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x80b0
movq %rax, -0xa8(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x8600
movq -0x268(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0x88e0
movq %rax, -0x260(%rbp)
jmp 0x70be
movq -0x260(%rbp), %rax
movq %rax, -0xb0(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x8950
movq -0x208(%rbp), %rdi
movq %rax, -0x278(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
movq -0x30(%rbp), %rsi
callq 0x43f0
movq -0x278(%rbp), %rsi
movq %rax, %rdi
callq 0x8680
jmp 0x7115
leaq -0x50(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0x4190
movq -0x290(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x288(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4310
movq %rax, -0xc0(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x7f20
movq -0x288(%rbp), %rdi
movq -0xb8(%rbp), %rsi
callq 0x86c0
movq %rax, -0x280(%rbp)
jmp 0x717e
movq -0x280(%rbp), %rax
movq %rax, -0xc8(%rbp)
movl $0x1, -0x94(%rbp)
jmp 0x77da
leaq -0x40(%rbp), %rdi
callq 0x50f0
testb $0x1, %al
jne 0x71ad
jmp 0x74a5
leaq -0x40(%rbp), %rdi
callq 0x4190
movq -0x208(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x298(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
movq -0x28(%rbp), %rsi
callq 0x43f0
movq -0x298(%rbp), %rdi
movq %rax, %rsi
callq 0x87d0
jmp 0x71ee
leaq -0x40(%rbp), %rdi
movq %rdi, -0x2b0(%rbp)
callq 0x4190
movq -0x2b0(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x2a8(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4380
movq %rax, -0xd8(%rbp)
leaq -0xd0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x7f20
movq -0x210(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4310
movq -0x210(%rbp), %rdi
movq %rax, -0xe0(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4380
movq -0x2a8(%rbp), %rdi
movq %rax, -0xe8(%rbp)
movq -0xd0(%rbp), %rsi
movq -0xe0(%rbp), %rdx
movq -0xe8(%rbp), %rcx
callq 0x8980
movq %rax, -0x2a0(%rbp)
jmp 0x72a3
movq -0x2a0(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq -0x40(%rbp), %rdi
movq %rdi, -0x2c8(%rbp)
callq 0x4190
movq -0x2c8(%rbp), %rdi
addq $0x48, %rax
movq %rax, -0x2c0(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x5040
movq %rax, -0x100(%rbp)
leaq -0xf8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x8600
movq -0x210(%rbp), %rdi
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x80b0
movq -0x210(%rbp), %rdi
movq %rax, -0x108(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x5040
movq -0x2c0(%rbp), %rdi
movq %rax, -0x110(%rbp)
movq -0xf8(%rbp), %rsi
movq -0x108(%rbp), %rdx
movq -0x110(%rbp), %rcx
callq 0x8a30
movq %rax, -0x2b8(%rbp)
jmp 0x7366
movq -0x208(%rbp), %rdi
movq -0x2b8(%rbp), %rax
movq %rax, -0x118(%rbp)
callq 0x4190
movq -0x208(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x2d8(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4310
movq %rax, -0x130(%rbp)
movq -0x28(%rbp), %rsi
leaq -0x130(%rbp), %rdi
callq 0x8030
movq %rax, -0x128(%rbp)
leaq -0x120(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x7f20
movq -0x2d8(%rbp), %rdi
movq -0x120(%rbp), %rsi
callq 0x86c0
movq %rax, -0x2d0(%rbp)
jmp 0x73f0
movq -0x208(%rbp), %rdi
movq -0x2d0(%rbp), %rax
movq %rax, -0x138(%rbp)
callq 0x4190
movq -0x208(%rbp), %rdi
addq $0x48, %rax
movq %rax, -0x2e8(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x80b0
movq %rax, -0x158(%rbp)
movq -0x28(%rbp), %rsi
leaq -0x158(%rbp), %rdi
callq 0x80e0
movq %rax, -0x150(%rbp)
leaq -0x150(%rbp), %rdi
movl $0x1, %esi
callq 0x80e0
movq %rax, -0x148(%rbp)
leaq -0x140(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x8600
movq -0x2e8(%rbp), %rdi
movq -0x140(%rbp), %rsi
callq 0x88e0
movq %rax, -0x2e0(%rbp)
jmp 0x7492
movq -0x2e0(%rbp), %rax
movq %rax, -0x160(%rbp)
jmp 0x77d0
leaq -0x50(%rbp), %rdi
callq 0x50f0
testb $0x1, %al
jne 0x74b7
jmp 0x77af
movq -0x210(%rbp), %rdi
callq 0x4190
movq -0x208(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x2f0(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
movq -0x30(%rbp), %rsi
callq 0x43f0
movq -0x2f0(%rbp), %rdi
movq %rax, %rsi
callq 0x87d0
jmp 0x74fb
movq -0x210(%rbp), %rdi
callq 0x4190
movq -0x210(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x300(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4380
movq %rax, -0x170(%rbp)
leaq -0x168(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0x7f20
leaq -0x50(%rbp), %rdi
movq %rdi, -0x308(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4310
movq -0x308(%rbp), %rdi
movq %rax, -0x178(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4380
movq -0x300(%rbp), %rdi
movq %rax, -0x180(%rbp)
movq -0x168(%rbp), %rsi
movq -0x178(%rbp), %rdx
movq -0x180(%rbp), %rcx
callq 0x8980
movq %rax, -0x2f8(%rbp)
jmp 0x75b0
movq -0x210(%rbp), %rdi
movq -0x2f8(%rbp), %rax
movq %rax, -0x188(%rbp)
callq 0x4190
movq -0x210(%rbp), %rdi
addq $0x48, %rax
movq %rax, -0x318(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x5040
movq %rax, -0x198(%rbp)
leaq -0x190(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x8600
leaq -0x50(%rbp), %rdi
movq %rdi, -0x320(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x80b0
movq -0x320(%rbp), %rdi
movq %rax, -0x1a0(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x5040
movq -0x318(%rbp), %rdi
movq %rax, -0x1a8(%rbp)
movq -0x190(%rbp), %rsi
movq -0x1a0(%rbp), %rdx
movq -0x1a8(%rbp), %rcx
callq 0x8a30
movq %rax, -0x310(%rbp)
jmp 0x7673
movq -0x208(%rbp), %rdi
movq -0x310(%rbp), %rax
movq %rax, -0x1b0(%rbp)
callq 0x4190
movq -0x208(%rbp), %rdi
addq $0x60, %rax
movq %rax, -0x330(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x60, %rdi
callq 0x4310
movq %rax, -0x1c8(%rbp)
movq -0x30(%rbp), %rsi
leaq -0x1c8(%rbp), %rdi
callq 0x8030
movq %rax, -0x1c0(%rbp)
leaq -0x1b8(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x7f20
movq -0x330(%rbp), %rdi
movq -0x1b8(%rbp), %rsi
callq 0x86c0
movq %rax, -0x328(%rbp)
jmp 0x76fd
movq -0x208(%rbp), %rdi
movq -0x328(%rbp), %rax
movq %rax, -0x1d0(%rbp)
callq 0x4190
movq -0x208(%rbp), %rdi
addq $0x48, %rax
movq %rax, -0x340(%rbp)
callq 0x4190
movq %rax, %rdi
addq $0x48, %rdi
callq 0x80b0
movq %rax, -0x1f0(%rbp)
movq -0x30(%rbp), %rsi
leaq -0x1f0(%rbp), %rdi
callq 0x80e0
movq %rax, -0x1e8(%rbp)
leaq -0x1e8(%rbp), %rdi
movl $0x1, %esi
callq 0x80e0
movq %rax, -0x1e0(%rbp)
leaq -0x1d8(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0x8600
movq -0x340(%rbp), %rdi
movq -0x1d8(%rbp), %rsi
callq 0x88e0
movq %rax, -0x338(%rbp)
jmp 0x779f
movq -0x338(%rbp), %rax
movq %rax, -0x1f8(%rbp)
jmp 0x77ce
leaq 0xaaea(%rip), %rdi      # 0x122a0
leaq 0xa948(%rip), %rsi      # 0x12105
movl $0x102, %edx            # imm = 0x102
leaq 0xaadd(%rip), %rcx      # 0x122a6
callq 0x2150
jmp 0x77d0
movl $0x0, -0x94(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x27e0
leaq -0x40(%rbp), %rdi
callq 0x27e0
addq $0x340, %rsp            # imm = 0x340
popq %rbp
retq
leaq -0x40(%rbp), %rdi
callq 0x27e0
movq -0x58(%rbp), %rdi
callq 0x2370
nopw (%rax,%rax)