// File: SeanChao[P]KV-Store/./skiplist.h
// Function: SkipList<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>::remove(unsigned long, std::shared_ptr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>)
bool SkipList<Key, Value>::remove(Key key, std::shared_ptr<Value> backupVal) {
    std::shared_ptr<Node> ptr = skipSearch(key);
    if (!valid(ptr) || ptr->key != key) return false;
    if (backupVal) *backupVal = ptr->val;
    while (ptr) {
        ptr->pred->succ = ptr->succ;
        ptr->succ->pred = ptr->pred;
        // if this level is empty and it's not bottom then delete it
        if (!ptr->pred->pred && !ptr->succ->succ && ptr->below) {
            if (head->succ == tail && tail->pred == head) {
                head = head->below;
                head->above = nullptr;
                tail = tail->below;
                tail->above = nullptr;
            }
        }
        ptr = ptr->below;
    }
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdx, -0x98(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rsi
movq %rsi, -0x88(%rbp)
movq -0x18(%rbp), %rdx
leaq -0x30(%rbp), %rdi
movq %rdi, -0x90(%rbp)
callq 0x10160
movq -0x90(%rbp), %rsi
leaq -0x40(%rbp), %rdi
movq %rdi, -0x80(%rbp)
callq 0xc8a0
movq -0x88(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0xc820
movb %al, -0x71(%rbp)
jmp 0xc1c6
movb -0x71(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x99(%rbp)
jne 0xc1d8
jmp 0xc1f1
leaq -0x30(%rbp), %rdi
callq 0xc7b0
movq (%rax), %rax
cmpq -0x18(%rbp), %rax
setne %al
movb %al, -0x99(%rbp)
movb -0x99(%rbp), %al
movb %al, -0x9a(%rbp)
leaq -0x40(%rbp), %rdi
callq 0xc8d0
movb -0x9a(%rbp), %al
testb $0x1, %al
jne 0xc212
jmp 0xc23c
movb $0x0, -0x1(%rbp)
movl $0x1, -0x50(%rbp)
jmp 0xc4bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0xc8d0
jmp 0xc4d6
movq -0x98(%rbp), %rdi
callq 0x11650
testb $0x1, %al
jne 0xc24e
jmp 0xc292
leaq -0x30(%rbp), %rdi
callq 0xc7b0
movq -0x98(%rbp), %rdi
addq $0x8, %rax
movq %rax, -0xa8(%rbp)
callq 0xc540
movq -0xa8(%rbp), %rsi
movq %rax, %rdi
callq 0x4040
jmp 0xc27f
jmp 0xc292
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xc4d6
jmp 0xc294
leaq -0x30(%rbp), %rdi
callq 0xc800
testb $0x1, %al
jne 0xc2a6
jmp 0xc4b4
leaq -0x30(%rbp), %rdi
callq 0xc7b0
addq $0x38, %rax
movq %rax, -0xb8(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x28, %rdi
callq 0xc7b0
movq -0xb8(%rbp), %rsi
movq %rax, %rdi
addq $0x38, %rdi
callq 0xc7d0
leaq -0x30(%rbp), %rdi
callq 0xc7b0
addq $0x28, %rax
movq %rax, -0xb0(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x38, %rdi
callq 0xc7b0
movq -0xb0(%rbp), %rsi
movq %rax, %rdi
addq $0x28, %rdi
callq 0xc7d0
leaq -0x30(%rbp), %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x28, %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x28, %rdi
callq 0xc800
testb $0x1, %al
jne 0xc496
leaq -0x30(%rbp), %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x38, %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x38, %rdi
callq 0xc800
testb $0x1, %al
jne 0xc496
leaq -0x30(%rbp), %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x58, %rdi
callq 0xc800
testb $0x1, %al
jne 0xc38e
jmp 0xc496
movq -0x88(%rbp), %rdi
callq 0xc7b0
movq -0x88(%rbp), %rsi
movq %rax, %rdi
addq $0x38, %rdi
addq $0x10, %rsi
callq 0x106a0
testb $0x1, %al
jne 0xc3ba
jmp 0xc494
movq -0x88(%rbp), %rdi
addq $0x10, %rdi
callq 0xc7b0
movq -0x88(%rbp), %rsi
movq %rax, %rdi
addq $0x28, %rdi
callq 0x106a0
testb $0x1, %al
jne 0xc3e6
jmp 0xc494
movq -0x88(%rbp), %rdi
callq 0xc7b0
movq -0x88(%rbp), %rdi
movq %rax, %rsi
addq $0x58, %rsi
callq 0xc7d0
leaq -0x60(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xf2a0
movq -0x88(%rbp), %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x48, %rdi
leaq -0x60(%rbp), %rsi
callq 0xf220
leaq -0x60(%rbp), %rdi
callq 0xc8d0
movq -0x88(%rbp), %rdi
addq $0x10, %rdi
callq 0xc7b0
movq -0x88(%rbp), %rdi
movq %rax, %rsi
addq $0x58, %rsi
addq $0x10, %rdi
callq 0xc7d0
leaq -0x70(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xf2a0
movq -0x88(%rbp), %rdi
addq $0x10, %rdi
callq 0xc7b0
movq %rax, %rdi
addq $0x48, %rdi
leaq -0x70(%rbp), %rsi
callq 0xf220
leaq -0x70(%rbp), %rdi
callq 0xc8d0
jmp 0xc496
leaq -0x30(%rbp), %rdi
callq 0xc7b0
movq %rax, %rsi
addq $0x58, %rsi
leaq -0x30(%rbp), %rdi
callq 0xc7d0
jmp 0xc294
movb $0x1, -0x1(%rbp)
movl $0x1, -0x50(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xc8d0
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xc0, %rsp
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0xc8d0
movq -0x48(%rbp), %rdi
callq 0x4530
nopl (%rax,%rax)