// File: /workspace/github_cpp_makefile_star2_O1/chahk0129[P]hash_bench/./index/extendible_hash.h
// Function: ExtendibleHash<char [32]>::Delete(char (&) [32])
bool ExtendibleHash<Key_t>::Delete(Key_t& key) {
	size_t f_hash;
    if constexpr(sizeof(Key_t) > 8)
	f_hash = hash_funcs[0](key, sizeof(Key_t), f_seed);
    else
	f_hash = hash_funcs[0](&key, sizeof(Key_t), f_seed);
    auto f_idx = (f_hash & kMask) * kNumPairPerCacheLine;

RETRY:
    while(dir->sema < 0){
	asm("nop");
    }

    auto x = (f_hash >> (8*sizeof(f_hash) - dir->depth)); 
    auto target = dir->_[x];

    if(!target){
	std::this_thread::yield();
	goto RETRY;
    }

    /* acquire segment shared lock */
    if(!target->mutex.try_lock()){
	std::this_thread::yield();
	goto RETRY;
    }

    auto target_check = (f_hash >> (8*sizeof(f_hash) - dir->depth));
    if(target != dir->_[target_check]){
	target->mutex.unlock();
	std::this_thread::yield();
	goto RETRY;
    }

    for (unsigned i = 0; i < kNumPairPerCacheLine * kNumCacheLine; ++i) {
	auto loc = (f_idx+i) % Segment<Key_t>::kNumSlot;
	if constexpr(sizeof(Key_t)>8){
	    if(memcmp(target->_[loc].key, key, sizeof(Key_t)) == 0){
		    memcpy(target->_[loc].key, INVALID<Key_t>, sizeof(Key_t));
		target->mutex.unlock();
		return true;
	    }
	}
	else{
	    if(memcmp(&target->_[loc].key, &key, sizeof(Key_t)) == 0){
		    memcpy(&target->_[loc].key, &INVALID<Key_t>, sizeof(Key_t));
		target->mutex.unlock();
		return true;
	    }
	}
    }

#ifdef S_HASH
    size_t s_hash;
    if constexpr(sizeof(Key_t) > 8)
	s_hash = hash_funcs[2](key, sizeof(Key_t), s_seed);
    else
	s_hash = hash_funcs[2](&key, sizeof(Key_t), s_seed);
    auto s_idx = (s_hash & kMask) * kNumPairPerCacheLine;

    for(unsigned i=0; i<kNumPairPerCacheLine * kNumCacheLine; ++i){
	auto loc = (s_idx+i) % Segment<Key_t>::kNumSlot;
	if constexpr(sizeof(Key_t)>8){
	    if(memcmp(target->_[loc].key, key, sizeof(Key_t)) == 0){
		    memcpy(target->_[loc].key, INVALID<Key_t>, sizeof(Key_t));
		target->mutex.unlock();
		return true; 
	    }
	}
	else{
	    if(memcmp(&target->_[loc].key, &key, sizeof(Key_t)) == 0){
		    memcpy(&target->_[loc].key, &INVALID<Key_t>, sizeof(Key_t));
		target->mutex.unlock();
		return true; 
	    }
	}

    }
#endif

    target->mutex.unlock();
    return false; 
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movl $0x20, %esi
movl $0xc70697, %edx         # imm = 0xC70697
movq %rbx, %rdi
callq 0x2050
movq %rax, %r12
leaq (,%rax,4), %rax
movq %rax, 0x20(%rsp)
movl %eax, 0x4(%rsp)
movq %r14, 0x18(%rsp)
movq %r12, 0x10(%rsp)
movq 0x8(%r14), %rax
cmpq $0x0, 0x8(%rax)
jns 0x8e45
movq 0x8(%r14), %rax
nop
cmpq $0x0, 0x8(%rax)
js 0x8e3d
xorl %ecx, %ecx
subb 0x18(%rax), %cl
movq %r12, %rdx
shrq %cl, %rdx
movq (%rax), %rax
movq (%rax,%rdx,8), %r15
testq %r15, %r15
je 0x8e97
leaq 0xa008(%r15), %rdi
movq %rdi, 0x8(%rsp)
callq 0x2360
cmpl $0x10, %eax
je 0x8e97
movq 0x8(%r14), %rax
xorl %ecx, %ecx
subb 0x18(%rax), %cl
movq %r12, %rdx
shrq %cl, %rdx
movq (%rax), %rax
cmpq (%rax,%rdx,8), %r15
setne %al
je 0x8ea7
movq 0x8(%rsp), %rdi
callq 0x2240
callq 0x2280
movb $0x1, %al
testb %al, %al
jne 0x8e2e
jmp 0x8f71
movb %al, 0x3(%rsp)
xorl %r14d, %r14d
xorl %r13d, %r13d
movq 0x20(%rsp), %rax
addl %r14d, %eax
andl $0x3ff, %eax            # imm = 0x3FF
leaq (%rax,%rax,4), %rax
movdqu (%r15,%rax,8), %xmm0
movdqu 0x10(%r15,%rax,8), %xmm1
movdqu (%rbx), %xmm2
pcmpeqb %xmm0, %xmm2
movdqu 0x10(%rbx), %xmm0
pcmpeqb %xmm1, %xmm0
pand %xmm2, %xmm0
pmovmskb %xmm0, %ecx
xorl %ebp, %ebp
cmpl $0xffff, %ecx           # imm = 0xFFFF
setne %r12b
jne 0x8f21
leaq (%r15,%rax,8), %rax
movaps 0xb3df(%rip), %xmm0     # 0x142e0
movups %xmm0, 0x10(%rax)
movdqa 0xb3c3(%rip), %xmm0     # 0x142d0
movdqu %xmm0, (%rax)
movq 0x8(%rsp), %rdi
callq 0x2240
movb $0x1, %al
movl %eax, 0x4(%rsp)
movb %r12b, %bpl
testl %ebp, %ebp
je 0x8f46
cmpq $0x3ff, %r14            # imm = 0x3FF
leaq 0x1(%r14), %rax
setae %r13b
movq %rax, %r14
cmpq $0x400, %rax            # imm = 0x400
jne 0x8eb1
testb $0x1, %r13b
je 0x8f5e
movq 0x8(%rsp), %rdi
callq 0x2240
movl $0x0, 0x4(%rsp)
movq 0x18(%rsp), %r14
movq 0x10(%rsp), %r12
movb 0x3(%rsp), %al
jmp 0x8e9e
movl 0x4(%rsp), %eax
andb $0x1, %al
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq