// File: /workspace/github_cpp_makefile_star2_O2/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, %r14
movq %rsi, %r12
movq %rdi, 0x10(%rsp)
movq %rsi, %rdi
callq 0x13a4e
movq %r12, %rdi
callq 0x13686
movq %r14, %rdi
movq %r15, %rsi
callq 0x13380
movq %r12, %rdi
movq %rax, 0x28(%rsp)
movq %rax, %rsi
movq %r14, %rdx
movq %r15, %rcx
callq 0x135d2
movq 0x8(%r12), %rdi
movq (%rdi,%rax), %r13
leaq (%r15,%rbx), %rdx
addq $0x18, %rdx
leaq (%r15,%rbx), %rcx
addq $0x17, %rcx
bsrq %rcx, %rcx
pushq $0x2
popq %rsi
shlq %cl, %rsi
cmpq $0x2, %rdx
pushq $0x1
popq %rbp
cmovaeq %rsi, %rbp
cmpq $0x2, %r13
jb 0x13915
movl 0x1c(%r12), %ecx
cmpq %rcx, %rbp
ja 0x13915
cmpq %rbx, 0x10(%rdi,%r13)
jne 0x13915
addq $0x18, %r15
leaq 0x4(%r12), %rdi
addq %r13, %r15
movq %r15, %rsi
movq 0x8(%rsp), %rdx
movq %rbx, %rcx
callq 0x13f72
addq 0x8(%r12), %r15
movq 0x10(%rsp), %rax
movq %r15, (%rax)
movq %rbx, 0x8(%rax)
jmp 0x13a3b
movq %rax, 0x20(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, 0x18(%rsp)
callq 0x13490
movq 0x18(%rsp), %rcx
movq %rax, %rbx
leaq 0x1(%rbp), %rax
movq %rax, 0x30(%rsp)
movq %r15, 0x38(%rsp)
movq %rcx, 0x40(%rsp)
movl 0x1c(%r12), %eax
cmpq %rax, %rbp
jbe 0x13994
leaq 0x50(%rsp), %rdx
movq %r14, (%rdx)
movq %r15, 0x8(%rdx)
movq 0x8(%rsp), %rax
movq %rax, 0x10(%rdx)
movq %rcx, 0x18(%rdx)
leaq 0x4(%r12), %r14
movq %rbx, %rsi
addq $0x18, %rsi
pushq $0x2
popq %rcx
movq %r14, %rdi
callq 0x14088
leaq 0x30(%rsp), %rdx
pushq $0x18
popq %rcx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x13f72
jmp 0x139ce
leaq 0x30(%rsp), %rax
leaq 0x50(%rsp), %rdx
movq %rax, (%rdx)
movq $0x18, 0x8(%rdx)
movq %r14, 0x10(%rdx)
movq %r15, 0x18(%rdx)
movq 0x8(%rsp), %rax
movq %rax, 0x20(%rdx)
movq %rcx, 0x28(%rdx)
leaq 0x4(%r12), %rdi
pushq $0x3
popq %rcx
movq %rbx, %rsi
callq 0x14088
cmpq $0x2, %r13
jb 0x139e1
movq %r12, %rdi
movq %r13, %rsi
callq 0x13390
jmp 0x13a03
movq 0x8(%r12), %rax
xorq $0x1, %r13
addq 0x18(%rax), %r13
movq 0x20(%rax), %rcx
incq %rcx
pushq $0x18
popq %rsi
movq %r12, %rdi
movq %r13, %rdx
callq 0x1405e
movq %r12, %rdi
movq 0x20(%rsp), %rsi
movq %rbx, %rdx
movq 0x28(%rsp), %rcx
callq 0x1405e
movq 0x8(%r12), %rax
addq %rbx, %rax
addq %r15, %rax
addq $0x20, %rax
movq 0x10(%rsp), %rcx
movq %rax, (%rcx)
movq %rcx, %rax
movq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rax)
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop