// File: chahk0129[P]hash_bench/./index/linear_probing.h
// Function: LinearProbingHash<char [32]>::Insert(char (&) [32], long)
void LinearProbingHash<Key_t>::Insert(Key_t& key, Value_t value){
    uint64_t key_hash;
    if constexpr(sizeof(Key_t) > 8)
	key_hash = h(key, sizeof(Key_t));
    else
	key_hash = h(&key, sizeof(Key_t));

RETRY:
    while(resizing_lock){
	asm("nop");
    }

    auto loc = key_hash;
    if(size < capacity*kResizingThreshold){
	int i = 0;
	while(i < capacity){
	    auto slot = (loc + i) % capacity;
	    unique_lock<shared_mutex> lock(mutex[slot/locksize]);
	    do{
		if constexpr(sizeof(Key_t) > 8){
		    if(memcmp(dict[slot].key, INVALID<Key_t>, sizeof(Key_t)) == 0){
			memcpy(dict[slot].key, key, sizeof(Key_t));
			memcpy(&dict[slot].value, &value, sizeof(Value_t));
			auto _size = size;
			while(!CAS(&size, &_size, _size+1)){
			    _size = size;
			}
			return;
		    }
		}
		else{
		    if(memcmp(&dict[slot].key, &INVALID<Key_t>, sizeof(Key_t)) == 0){
			memcpy(&dict[slot].key, &key, sizeof(Key_t));
			memcpy(&dict[slot].value, &value, sizeof(Value_t));
			auto _size = size;
			while(!CAS(&size, &_size, _size+1)){
			    _size = size;
			}
			return;
		    }
		}
		i++;
		slot = (loc + i) % capacity;
		if(!(i < capacity)) break;
	    }while(slot % locksize != 0);
	}
    }else{
	auto unlocked = 0;
	if(CAS(&resizing_lock, &unlocked, 1)){
#ifdef BREAKDOWN
	    clock_gettime(CLOCK_MONOTONIC, &t_start);
#endif
	    resize(capacity * kResizingFactor);
	    resizing_lock = 0;
#ifdef BREAKDOWN
	    clock_gettime(CLOCK_MONOTONIC, &t_end);
	    split_time += t_end.tv_nsec - t_start.tv_nsec + (t_end.tv_sec - t_start.tv_sec)*1000000000;
#endif
	}
    }
    goto RETRY;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rdi
movl $0x20, %esi
movl $0xc70697, %edx         # imm = 0xC70697
callq 0x1dd60
movq %rax, -0x20(%rbp)
jmp 0x1d488
movq -0x78(%rbp), %rax
cmpl $0x0, 0x38(%rax)
je 0x1d495
nop
jmp 0x1d488
movq -0x78(%rbp), %rax
movq -0x20(%rbp), %rcx
movq %rcx, -0x28(%rbp)
movq 0x10(%rax), %rcx
movq %rcx, -0x88(%rbp)
movq 0x30(%rax), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x80(%rbp)
testq %rax, %rax
movss %xmm0, -0x7c(%rbp)
js 0x1d4e5
movss -0x80(%rbp), %xmm0
movss %xmm0, -0x7c(%rbp)
movq -0x88(%rbp), %rax
movss -0x7c(%rbp), %xmm0
movss %xmm0, -0x94(%rbp)
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x90(%rbp)
testq %rax, %rax
movss %xmm0, -0x8c(%rbp)
js 0x1d53a
movss -0x90(%rbp), %xmm0
movss %xmm0, -0x8c(%rbp)
movss -0x94(%rbp), %xmm1
movq -0x78(%rbp), %rax
movss -0x8c(%rbp), %xmm0
mulss 0xc(%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x1d706
movl $0x0, -0x2c(%rbp)
movq -0x78(%rbp), %rcx
movslq -0x2c(%rbp), %rax
cmpq 0x10(%rcx), %rax
jae 0x1d701
movq -0x78(%rbp), %rcx
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rdx
addq %rdx, %rax
xorl %edx, %edx
divq 0x10(%rcx)
movq %rdx, -0x38(%rbp)
movq 0x40(%rcx), %rsi
movq -0x38(%rbp), %rax
movslq 0x4c(%rcx), %rcx
xorl %edx, %edx
divq %rcx
imulq $0x38, %rax, %rax
addq %rax, %rsi
leaq -0x48(%rbp), %rdi
callq 0x1dd90
movq -0x78(%rbp), %rax
movq 0x18(%rax), %rdi
imulq $0x28, -0x38(%rbp), %rax
addq %rax, %rdi
leaq 0x3d6da(%rip), %rsi     # 0x5aca0
movl $0x20, %edx
callq 0x6190
cmpl $0x0, %eax
jne 0x1d693
movq -0x78(%rbp), %rax
movq 0x18(%rax), %rcx
imulq $0x28, -0x38(%rbp), %rdx
addq %rdx, %rcx
movq -0x10(%rbp), %rdx
movq (%rdx), %rsi
movq %rsi, (%rcx)
movq 0x8(%rdx), %rsi
movq %rsi, 0x8(%rcx)
movq 0x10(%rdx), %rsi
movq %rsi, 0x10(%rcx)
movq 0x18(%rdx), %rdx
movq %rdx, 0x18(%rcx)
movq 0x18(%rax), %rcx
imulq $0x28, -0x38(%rbp), %rdx
addq %rdx, %rcx
movq -0x18(%rbp), %rdx
movq %rdx, 0x20(%rcx)
movq 0x30(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x78(%rbp), %rcx
movq -0x50(%rbp), %rax
incq %rax
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rax
movq -0x58(%rbp), %rdx
lock
cmpxchgq %rdx, 0x30(%rcx)
movq %rax, %rcx
sete %al
movb %al, -0xa1(%rbp)
movq %rcx, -0xa0(%rbp)
testb $0x1, %al
jne 0x1d666
movq -0xa0(%rbp), %rax
movq %rax, -0x50(%rbp)
movb -0xa1(%rbp), %al
andb $0x1, %al
movb %al, -0x59(%rbp)
movb -0x59(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x1d67c
jmp 0x1d68a
movq -0x78(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x50(%rbp)
jmp 0x1d627
movl $0x1, -0x60(%rbp)
jmp 0x1d6e5
movq -0x78(%rbp), %rcx
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rdx
addq %rdx, %rax
xorl %edx, %edx
divq 0x10(%rcx)
movq %rdx, -0x38(%rbp)
movslq -0x2c(%rbp), %rax
cmpq 0x10(%rcx), %rax
jb 0x1d6c1
jmp 0x1d6de
jmp 0x1d6c3
movq -0x78(%rbp), %rcx
movq -0x38(%rbp), %rax
movslq 0x4c(%rcx), %rcx
xorl %edx, %edx
divq %rcx
cmpq $0x0, %rdx
jne 0x1d5af
movl $0x0, -0x60(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x1ddd0
movl -0x60(%rbp), %eax
testl %eax, %eax
je 0x1d6fc
jmp 0x1d6f7
jmp 0x1d847
jmp 0x1d563
jmp 0x1d842
movq -0x78(%rbp), %rcx
movl $0x0, -0x64(%rbp)
movl $0x1, -0x68(%rbp)
movl -0x64(%rbp), %eax
movl -0x68(%rbp), %edx
lock
cmpxchgl %edx, 0x38(%rcx)
movl %eax, %ecx
sete %al
movb %al, -0xa9(%rbp)
movl %ecx, -0xa8(%rbp)
testb $0x1, %al
jne 0x1d741
movl -0xa8(%rbp), %eax
movl %eax, -0x64(%rbp)
movb -0xa9(%rbp), %al
andb $0x1, %al
movb %al, -0x69(%rbp)
testb $0x1, -0x69(%rbp)
je 0x1d840
leaq 0x3d513(%rip), %rsi     # 0x5ac70
movl $0x1, %edi
callq 0x63d0
movq -0x78(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0xb4(%rbp)
testq %rax, %rax
movss %xmm0, -0xb0(%rbp)
js 0x1d7b0
movss -0xb4(%rbp), %xmm0
movss %xmm0, -0xb0(%rbp)
movq -0x78(%rbp), %rdi
movss -0xb0(%rbp), %xmm0
movss 0x8(%rdi), %xmm1
mulss %xmm1, %xmm0
movaps %xmm0, %xmm1
cvttss2si %xmm1, %rsi
movq %rsi, %rcx
sarq $0x3f, %rcx
movss 0x24880(%rip), %xmm1    # 0x4205c
subss %xmm1, %xmm0
cvttss2si %xmm0, %rax
andq %rcx, %rax
orq %rax, %rsi
callq 0x1de10
movq -0x78(%rbp), %rax
movl $0x0, 0x38(%rax)
movl $0x1, %edi
leaq 0x3d479(%rip), %rsi     # 0x5ac80
callq 0x63d0
movq 0x3d475(%rip), %rax     # 0x5ac88
subq 0x3d45e(%rip), %rax     # 0x5ac78
movq 0x3d45f(%rip), %rcx     # 0x5ac80
subq 0x3d448(%rip), %rcx     # 0x5ac70
imulq $0x3b9aca00, %rcx, %rcx # imm = 0x3B9ACA00
addq %rcx, %rax
addq 0x3d427(%rip), %rax     # 0x5ac60
movq %rax, 0x3d420(%rip)     # 0x5ac60
jmp 0x1d842
jmp 0x1d486
addq $0xc0, %rsp
popq %rbp
retq