// File: /workspace/github_cpp_makefile_star2_O3/Alcaro[P]bridges/arlib/staticmap.cpp
// Function: staticmap::insert(arrayview<unsigned char>, arrayview<unsigned char>)
bytesw staticmap::insert(bytesr key, bytesr val)
{
//puts("INSERT "+tostringhex(key)+" "+tostringhex(val));
//puts("XINSERT "+tostringhex(key)+" "+tostring(val.size())+" 55");
	desync();
	
	rehash_if_needed();
	
	uint64_t hash = sm_hash(key);
	uint64_t hashmap_pos = hashmap_locate(hash, key);
	
	uint64_t prev_ptr = rd64(hashmap_pos+off_h_ptr);
	uint64_t alloc_size = bitround(off_d_keystart+key.size()+val.size());
	if (alloc_size <= sector_size && prev_ptr > 1 && val.size() == rd64(prev_ptr+off_d_valsz))
	{
		// choose in-place update if possible
		f.pwrite(prev_ptr+off_d_keystart+key.size(), val);
		return mmap.slice(prev_ptr+off_d_keystart+key.size(), val.size());
	}
	uint64_t pos = alloc(alloc_size);
	
	uint8_t head[off_d_keystart];
	wr64(head, alloc_size+t_data, key.size(), val.size());
	
	if (alloc_size <= sector_size)
	{
		iovec iov[] = { { head, off_d_keystart }, { (void*)key.ptr(), key.size() }, { (void*)val.ptr(), val.size() } };
		f.pwritev(pos, iov);
	}
	else
	{
		iovec iov[] = {                           { (void*)key.ptr(), key.size() }, { (void*)val.ptr(), val.size() } };
		f.pwritev(pos+off_d_keystart, iov);
		f.pwrite(pos, head);
	}
	
	if (prev_ptr > 1)
		free(prev_ptr);
	else
		wr64(off_r_hm_load, rd64(off_r_hm_load)+(prev_ptr==0), rd64(off_r_entries)+1);
	wr64(hashmap_pos, pos, hash);
	
	return mmap.slice(pos+off_r_entries+key.size(), val.size());
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %r9, %rbx
movq %r8, 0x8(%rsp)
movq %rcx, %r15
movq %rdx, %rbp
movq %rsi, %r12
movq %rdi, 0x18(%rsp)
movq %rsi, %rdi
callq 0x186ca
movq %r12, %rdi
callq 0x18230
movq %rbp, %rdi
movq %r15, %rsi
callq 0x15ad7
movq %rax, %rcx
shrq $0x1e, %rcx
xorq %rax, %rcx
movabsq $-0x40a7b892e31b1a47, %rax # imm = 0xBF58476D1CE4E5B9
imulq %rcx, %rax
movq %rax, %rcx
shrq $0x1b, %rcx
xorq %rax, %rcx
movabsq $-0x6b2fb644ecceee15, %rax # imm = 0x94D049BB133111EB
imulq %rcx, %rax
movq %rax, %r13
shrq $0x1f, %r13
xorq %rax, %r13
movq %r12, %rdi
movq %r13, %rsi
movq %rbp, %rdx
movq %r15, %rcx
callq 0x1816e
movq %rbx, %rdx
movq 0x8(%r12), %r8
movq (%r8,%rax), %r14
leaq (%r15,%rbx), %rdi
addq $0x18, %rdi
leaq (%r15,%rbx), %rcx
addq $0x17, %rcx
bsrq %rcx, %rcx
movl $0x2, %esi
shlq %cl, %rsi
cmpq $0x2, %rdi
movl $0x1, %ebx
cmovaeq %rsi, %rbx
cmpq $0x2, %r14
jb 0x18557
movl 0x1c(%r12), %ecx
cmpq %rcx, %rbx
ja 0x18557
cmpq %rdx, 0x10(%r8,%r14)
jne 0x18557
addq $0x18, %r15
addq %r14, %r15
movl 0x4(%r12), %edi
movq 0x8(%rsp), %rsi
movq %r15, %rcx
movq %rdx, %rbx
callq 0x30d0
addq 0x8(%r12), %r15
movq 0x18(%rsp), %rcx
movq %r15, (%rcx)
movq %rbx, 0x8(%rcx)
jmp 0x186b4
movq %rbp, 0x10(%rsp)
movq %rax, 0x28(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
movq %rdx, 0x20(%rsp)
callq 0x17f70
movq 0x20(%rsp), %rcx
movq %rax, %rbp
leaq 0x1(%rbx), %rax
movq %rax, 0x30(%rsp)
movq %r15, 0x38(%rsp)
movq %rcx, 0x40(%rsp)
movl 0x1c(%r12), %eax
cmpq %rax, %rbx
jbe 0x185e3
leaq 0x50(%rsp), %rsi
movq 0x10(%rsp), %rax
movq %rax, (%rsi)
movq %r15, 0x8(%rsi)
movq 0x8(%rsp), %rax
movq %rax, 0x10(%rsi)
movq %rcx, 0x18(%rsi)
movq %rbp, %rcx
addq $0x18, %rcx
movl 0x4(%r12), %edi
movl $0x2, %edx
callq 0x3260
movl 0x4(%r12), %edi
leaq 0x30(%rsp), %rsi
movl $0x18, %edx
movq %rbp, %rcx
callq 0x30d0
jmp 0x18624
leaq 0x30(%rsp), %rax
leaq 0x50(%rsp), %rsi
movq %rax, (%rsi)
movq $0x18, 0x8(%rsi)
movq 0x10(%rsp), %rax
movq %rax, 0x10(%rsi)
movq %r15, 0x18(%rsi)
movq 0x8(%rsp), %rax
movq %rax, 0x20(%rsi)
movq %rcx, 0x28(%rsi)
movl 0x4(%r12), %edi
movl $0x3, %edx
movq %rbp, %rcx
callq 0x3260
cmpq $0x2, %r14
jb 0x18637
movq %r12, %rdi
movq %r14, %rsi
callq 0x17e62
jmp 0x18674
movq 0x8(%r12), %rax
xorq $0x1, %r14
movq %r14, %xmm0
movdqu 0x18(%rax), %xmm1
shufpd $0x2, 0x16d1d(%rip), %xmm0 # xmm0 = xmm0[0],mem[1]
paddq %xmm1, %xmm0
leaq 0x50(%rsp), %rsi
movdqa %xmm0, (%rsi)
movl 0x4(%r12), %edi
movl $0x10, %edx
movl $0x18, %ecx
callq 0x30d0
leaq 0x50(%rsp), %rsi
movq %rbp, (%rsi)
movq %r13, 0x8(%rsi)
movl 0x4(%r12), %edi
movl $0x10, %edx
movq 0x28(%rsp), %rcx
callq 0x30d0
movq 0x8(%r12), %rax
addq %rbp, %rax
addq %r15, %rax
addq $0x20, %rax
movq 0x18(%rsp), %rcx
movq %rax, (%rcx)
movq 0x20(%rsp), %rax
movq %rax, 0x8(%rcx)
movq %rcx, %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop