// File: /workspace/github_cpp_makefile_star2_O3/SeanChao[P]KV-Store/./skiplist.h
// Function: SkipList<unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>::skipSearch(unsigned long) const
std::shared_ptr<typename SkipList<Key, Value>::Node>
SkipList<Key, Value>::skipSearch(Key key) const {
    std::shared_ptr<Node> temp = head->succ;
    std::shared_ptr<Node> levelHead = head;  // marks the head of current level
    std::vector<Key> path;
    while (temp) {
        while ((temp->succ && temp->key <= key) || temp == levelHead) {
            temp = temp->succ;
            path.push_back(temp->key);
        }
        if (!temp->pred) {
            std::cerr << *this << '\n';
            std::cerr << "ERR with key " << key << '\n';
            std::cerr << "level head @" << levelHead << '\n';
            for (auto n = path.begin(); n != path.end(); n++) {
                std::cout << *n << '\t';
            }
            std::cout << '\n';
        }
        temp = temp->pred;

        path.push_back(temp->key);
        // find a match
        // temp->pred is to prevent visiting head's
        if (temp && temp->pred && temp->key == key && valid(temp)) {
            return temp;
        }
        // return if no lower level exists
        if (!levelHead->below) return temp;
        // go to lower level or the head of lower level
        if (temp->below) {
            temp = temp->below;
            path.push_back(temp->key);
        } else
            temp = levelHead->below;
        levelHead = levelHead->below;
        // if (!temp->below) return temp;
        // temp = temp->below;
    }
    return nullptr;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdx, %r14
movq %rsi, 0x50(%rsp)
movq (%rsi), %rax
movq 0x38(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x40(%rax), %rcx
movq %rcx, 0x18(%rsp)
testq %rcx, %rcx
movq %rdi, 0x48(%rsp)
je 0x9988
movq 0x5656(%rip), %rdx      # 0xefc8
cmpb $0x0, (%rdx)
je 0x997c
incl 0x8(%rcx)
jmp 0x9988
lock
incl 0x8(%rcx)
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x40(%rsp)
testq %rax, %rax
je 0x99b5
movq 0x5621(%rip), %rcx      # 0xefc8
cmpb $0x0, (%rcx)
je 0x99b1
incl 0x8(%rax)
jmp 0x99b5
lock
incl 0x8(%rax)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
movq 0x10(%rsp), %rdx
testq %rdx, %rdx
je 0x9c8a
leaq 0x18(%rsp), %r12
movq 0x5610(%rip), %rbx      # 0xeff0
leaq 0xf(%rsp), %rbp
movq 0x55e4(%rip), %r13      # 0xefd0
movq 0x38(%rdx), %rax
testq %rax, %rax
je 0x99fe
cmpq %r14, (%rdx)
jbe 0x9ad4
cmpq 0x38(%rsp), %rdx
je 0x9ad4
movq 0x28(%rdx), %rax
testq %rax, %rax
jne 0x9b2f
movq %rbx, %rdi
movq 0x50(%rsp), %rsi
callq 0x9d63
movb $0xa, 0xf(%rsp)
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x32b0
movl $0xd, %edx
movq %rbx, %rdi
leaq 0x1983(%rip), %rsi      # 0xb3ca
callq 0x32b0
movq %rbx, %rdi
movq %r14, %rsi
callq 0x31a0
movb $0xa, 0xf(%rsp)
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x32b0
movl $0xc, %edx
movq %rbx, %rdi
leaq 0x195d(%rip), %rsi      # 0xb3d8
callq 0x32b0
movq 0x38(%rsp), %rsi
movq %rbx, %rdi
callq 0x31d0
movb $0xa, 0xf(%rsp)
movl $0x1, %edx
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x32b0
movq 0x20(%rsp), %r15
cmpq 0x28(%rsp), %r15
je 0x9b11
movq (%r15), %rsi
movq %r13, %rdi
callq 0x31a0
movb $0x9, 0xf(%rsp)
movl $0x1, %edx
movq %rax, %rdi
movq %rbp, %rsi
callq 0x32b0
addq $0x8, %r15
jmp 0x9aa7
movq %rax, 0x10(%rsp)
addq $0x40, %rdx
movq %r12, %rdi
movq %rdx, %rsi
callq 0x94a6
movq 0x10(%rsp), %rdx
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x9ba0
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x99ec
movb $0xa, 0xf(%rsp)
movl $0x1, %edx
movq %r13, %rdi
movq %rbp, %rsi
callq 0x32b0
movq 0x10(%rsp), %rdx
movq 0x28(%rdx), %rax
movq %rax, 0x10(%rsp)
addq $0x30, %rdx
movq %r12, %rdi
movq %rdx, %rsi
callq 0x94a6
movq 0x10(%rsp), %rdx
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x9b65
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x9b79
leaq 0x20(%rsp), %rdi
callq 0x9f62
movq 0x10(%rsp), %rdx
testq %rdx, %rdx
je 0x9be1
cmpq $0x0, 0x28(%rdx)
je 0x9be1
cmpq %r14, (%rdx)
jne 0x9be1
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x9bb4
movq 0x5432(%rip), %rax      # 0xefc8
cmpb $0x0, (%rax)
je 0x9bc0
incl 0x8(%rdi)
jmp 0x9bcf
leaq 0x20(%rsp), %rdi
callq 0x9f62
movq 0x10(%rsp), %rdx
jmp 0x99ec
cmpq $0x0, 0x38(%rdx)
je 0x9be1
jmp 0x9d03
lock
incl 0x8(%rdi)
cmpq $0x0, 0x28(%rdx)
je 0x9c80
movq 0x38(%rdx), %r15
callq 0x9436
testq %r15, %r15
jne 0x9cfb
movq 0x38(%rsp), %rsi
movq 0x58(%rsi), %rcx
movq 0x10(%rsp), %rax
testq %rcx, %rcx
je 0x9c97
movq 0x58(%rax), %rdx
testq %rdx, %rdx
je 0x9c37
movq %rdx, 0x10(%rsp)
addq $0x60, %rax
movq %r12, %rdi
movq %rax, %rsi
callq 0x94a6
movq 0x10(%rsp), %rdx
movq 0x28(%rsp), %rsi
cmpq 0x30(%rsp), %rsi
je 0x9c4a
movq (%rdx), %rax
movq %rax, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x28(%rsp)
jmp 0x9c54
movq %rcx, 0x10(%rsp)
addq $0x60, %rsi
movq %r12, %rdi
callq 0x94a6
jmp 0x9c54
leaq 0x20(%rsp), %rdi
callq 0x9f62
movq 0x38(%rsp), %rsi
movq 0x58(%rsi), %rax
movq %rax, 0x38(%rsp)
addq $0x60, %rsi
leaq 0x40(%rsp), %rdi
callq 0x94a6
movq 0x10(%rsp), %rdx
testq %rdx, %rdx
jne 0x99ec
jmp 0x9c8a
callq 0x9436
jmp 0x9be1
movq 0x48(%rsp), %rbx
xorps %xmm0, %xmm0
movups %xmm0, (%rbx)
jmp 0x9cb4
movq 0x48(%rsp), %rbx
movq %rax, (%rbx)
movq 0x18(%rsp), %rax
xorl %ecx, %ecx
movq %rcx, 0x18(%rsp)
movq %rax, 0x8(%rbx)
movq %rcx, 0x10(%rsp)
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x9ccb
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x3280
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x9cda
callq 0x9436
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x9ce9
callq 0x9436
movq %rbx, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movdqa 0x10(%rsp), %xmm0
jmp 0x9d08
movq %rdx, %xmm0
xorl %eax, %eax
movq %rax, 0x18(%rsp)
movq 0x48(%rsp), %rbx
movdqu %xmm0, (%rbx)
movq %rax, 0x10(%rsp)
jmp 0x9cb4
jmp 0x9d23
jmp 0x9d23
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x9d3d
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x3280
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x9d4c
callq 0x9436
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x9d5b
callq 0x9436
movq %rbx, %rdi
callq 0x33f0