// File: night-shift[P]Srl/include/Srl/Hash.hpp
// Function: std::pair<bool, Srl::String*> Srl::Lib::HTable<Srl::String, Srl::String, Srl::Lib::HashSrl<Srl::String, void>>::insert_hash<Srl::String&, Srl::String&>(unsigned long, bool, Srl::String&, Srl::String&)
std::pair<bool, V*> HTable<K, V, H>::insert_hash(uint64_t hash, bool update_on_dup,
                                                     KV&& key, Args&&... args)
    {
        if(this->limit < 1 || this->elements >= this->limit) {
            this->redistribute();
        }

        auto bucket  = get_bucket(hash);
        Entry* entry = table[bucket];
        Entry* prev  = nullptr;

        while(entry) {

            if(entry->hash == hash && entry->key == key) {

                if(update_on_dup) {

                    this->destroy_item(entry->val);
                    new (&entry->val) V(std::forward<Args>(args)...);
                }

                return { true, &entry->val };
            }

            prev  = entry;
            entry = entry->next;
        }

        Entry* mem = nullptr;

        if(this->mem_cache.size() > 0) {
            mem = this->mem_cache.back();
            this->mem_cache.pop_back();

        } else {
            mem = this->heap.template get_mem<Entry>(1);
        }

        auto* new_entry = new (mem) Entry (
            hash, std::forward<KV>(key), std::forward<Args>(args)...
        );

        if(prev) {
            prev->next = new_entry;
        } else {
            table[bucket] = new_entry;
        }

        this->elements++;

        return { false, &(new_entry->val) };
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movb %dl, %al
movq %rdi, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
movq %rcx, -0x30(%rbp)
movq %r8, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x88(%rbp)
cmpq $0x1, 0x10(%rax)
jb 0x403b5
movq -0x88(%rbp), %rcx
movq 0x18(%rcx), %rax
cmpq 0x10(%rcx), %rax
jb 0x403c1
movq -0x88(%rbp), %rdi
callq 0x35b20
movq -0x88(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x34490
movq %rax, %rcx
movq -0x88(%rbp), %rax
movq %rcx, -0x40(%rbp)
movq 0x20(%rax), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x40496
movq -0x48(%rbp), %rax
movq (%rax), %rax
cmpq -0x20(%rbp), %rax
jne 0x4047d
movq -0x48(%rbp), %rdi
addq $0x10, %rdi
movq -0x30(%rbp), %rsi
callq 0x33e90
testb $0x1, %al
jne 0x40426
jmp 0x4047d
testb $0x1, -0x21(%rbp)
je 0x40457
movq -0x88(%rbp), %rdi
movq -0x48(%rbp), %rsi
addq $0x20, %rsi
callq 0x36e30
movq -0x48(%rbp), %rax
movq -0x38(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x20(%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x28(%rax)
movb $0x1, -0x51(%rbp)
movq -0x48(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x60(%rbp)
leaq -0x10(%rbp), %rdi
leaq -0x51(%rbp), %rsi
leaq -0x60(%rbp), %rdx
callq 0x34f10
jmp 0x4057d
movq -0x48(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x403f7
movq -0x88(%rbp), %rdi
movq $0x0, -0x68(%rbp)
addq $0x28, %rdi
callq 0x36e00
cmpq $0x0, %rax
jbe 0x404dd
movq -0x88(%rbp), %rdi
addq $0x28, %rdi
callq 0x36470
movq -0x88(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x68(%rbp)
addq $0x28, %rdi
callq 0x36510
jmp 0x404f6
movq -0x88(%rbp), %rdi
addq $0x48, %rdi
movl $0x1, %esi
callq 0x33680
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
movq %rdi, -0x90(%rbp)
movq -0x20(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
callq 0x33fd0
movq -0x90(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x40532
movq -0x70(%rbp), %rcx
movq -0x50(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x40549
movq -0x88(%rbp), %rax
movq -0x70(%rbp), %rdx
movq 0x20(%rax), %rax
movq -0x40(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x88(%rbp), %rax
movq 0x18(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x18(%rax)
movb $0x0, -0x71(%rbp)
movq -0x70(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x80(%rbp)
leaq -0x10(%rbp), %rdi
leaq -0x71(%rbp), %rsi
leaq -0x80(%rbp), %rdx
callq 0x34f10
movb -0x10(%rbp), %al
movq -0x8(%rbp), %rdx
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax)