// File: 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
movq %rsp, %rbp
subq $0x1e0, %rsp            # imm = 0x1E0
movq %rdi, -0x140(%rbp)
movq %rdi, %rax
movq %rax, -0x138(%rbp)
movq %rdi, -0x8(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x10(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x20(%rbp)
movq %rsi, -0x30(%rbp)
movq -0x30(%rbp), %rdi
movq %rdi, -0x128(%rbp)
callq 0x34740
movq -0x128(%rbp), %rdi
callq 0x33db0
movq -0x18(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x33710
movq -0x128(%rbp), %rdi
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rsi
movq -0x18(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x60(%rbp), %rdx
movq -0x58(%rbp), %rcx
callq 0x33bf0
movq -0x128(%rbp), %rdi
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rsi
addq $0x0, %rsi
callq 0x353f0
movq %rax, -0x68(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x6290
addq $0x18, %rax
movq %rax, -0x130(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6290
movq -0x130(%rbp), %rdi
addq %rax, %rdi
callq 0x347b0
movq -0x128(%rbp), %rcx
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movl 0x1c(%rcx), %ecx
cmpq %rcx, %rax
ja 0x3440f
cmpq $0x1, -0x68(%rbp)
jbe 0x3440f
leaq -0x28(%rbp), %rdi
callq 0x6290
movq -0x128(%rbp), %rdi
movq %rax, -0x148(%rbp)
movq -0x68(%rbp), %rsi
addq $0x10, %rsi
callq 0x353f0
movq %rax, %rcx
movq -0x148(%rbp), %rax
cmpq %rcx, %rax
jne 0x3440f
movq -0x128(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x168(%rbp)
movq -0x68(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x170(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x6290
movq -0x170(%rbp), %rsi
movq -0x168(%rbp), %rdi
addq %rax, %rsi
movq -0x28(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x80(%rbp), %rdx
movq -0x78(%rbp), %rcx
callq 0x35470
movq -0x128(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x158(%rbp)
movq -0x68(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x160(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x6290
movq %rax, %rcx
movq -0x160(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x150(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6290
movq -0x140(%rbp), %rdi
movq -0x158(%rbp), %rsi
movq -0x150(%rbp), %rdx
movq %rax, %rcx
callq 0xc4c0
jmp 0x3472f
movq -0x128(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x33960
movq %rax, -0x88(%rbp)
leaq -0xa0(%rbp), %rax
movq %rax, -0x188(%rbp)
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x180(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x6290
movq %rax, -0x178(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6290
movq -0x188(%rbp), %rsi
movq -0x180(%rbp), %rdx
movq -0x178(%rbp), %rcx
movq -0x128(%rbp), %rdi
movq %rax, %r8
callq 0x35c10
movq -0x128(%rbp), %rcx
movq -0x70(%rbp), %rax
movl 0x1c(%rcx), %ecx
cmpq %rcx, %rax
ja 0x3454c
leaq -0xa0(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq $0x18, -0xc8(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x62c0
movq %rax, -0xc0(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x6290
movq %rax, -0xb8(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x62c0
movq %rax, -0xb0(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6290
movq %rax, %rcx
movq -0x128(%rbp), %rax
movq %rcx, -0xa8(%rbp)
addq $0x4, %rax
movq %rax, -0x198(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x190(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x35d40
movq -0x198(%rbp), %rdi
movq -0x190(%rbp), %rsi
movq -0xe0(%rbp), %rdx
movq -0xd8(%rbp), %rcx
callq 0x35ce0
jmp 0x3463b
leaq -0x18(%rbp), %rdi
callq 0x62c0
movq %rax, -0x100(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x6290
movq %rax, -0xf8(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x62c0
movq %rax, -0xf0(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6290
movq %rax, %rcx
movq -0x128(%rbp), %rax
movq %rcx, -0xe8(%rbp)
addq $0x4, %rax
movq %rax, -0x1b8(%rbp)
movq -0x88(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x1b0(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x35d70
movq -0x1b8(%rbp), %rdi
movq -0x1b0(%rbp), %rsi
movq -0x110(%rbp), %rdx
movq -0x108(%rbp), %rcx
callq 0x35ce0
movq -0x128(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x1a8(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x1a0(%rbp)
leaq -0x120(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x35da0
movq -0x1a8(%rbp), %rdi
movq -0x1a0(%rbp), %rsi
movq -0x120(%rbp), %rdx
movq -0x118(%rbp), %rcx
callq 0x35470
cmpq $0x1, -0x68(%rbp)
jbe 0x34654
movq -0x128(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x33760
jmp 0x346ad
movq -0x128(%rbp), %rdi
movl $0x18, %esi
callq 0x353f0
movq -0x128(%rbp), %rdi
cmpq $0x0, -0x68(%rbp)
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
addq %rcx, %rax
movq %rax, -0x1c0(%rbp)
movl $0x20, %esi
callq 0x353f0
movq -0x128(%rbp), %rdi
movq -0x1c0(%rbp), %rdx
movq %rax, %rcx
addq $0x1, %rcx
movl $0x18, %esi
callq 0x35b30
movq -0x128(%rbp), %rdi
movq -0x50(%rbp), %rsi
movq -0x88(%rbp), %rdx
movq -0x38(%rbp), %rcx
callq 0x35b30
movq -0x128(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x1d0(%rbp)
movq -0x88(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x1d8(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x6290
movq %rax, %rcx
movq -0x1d8(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x1c8(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6290
movq -0x140(%rbp), %rdi
movq -0x1d0(%rbp), %rsi
movq -0x1c8(%rbp), %rdx
movq %rax, %rcx
callq 0xc4c0
movq -0x138(%rbp), %rax
addq $0x1e0, %rsp            # imm = 0x1E0
popq %rbp
retq
nop