// File: attractivechaos[P]udb2/tommyds/./tommytrieinp.c
// Function: trie_inplace_bucket_remove
static tommy_trie_inplace_node* trie_inplace_bucket_remove(tommy_uint_t shift, tommy_trie_inplace_node** let_ptr, tommy_trie_inplace_node* remove, tommy_key_t key)
{
	tommy_trie_inplace_node* node;
	int i;
	tommy_trie_inplace_node** leaf_let_ptr;
	tommy_trie_inplace_node* leaf;

	node = *let_ptr;
	while (node && node->key != key) {
		let_ptr = &node->map[(key >> shift) & TOMMY_TRIE_INPLACE_TREE_MASK];
		node = *let_ptr;
		shift -= TOMMY_TRIE_INPLACE_TREE_BIT;
	}

	if (!node)
		return 0;

	/* if the node to remove is not specified */
	if (!remove)
		remove = node; /* remove the first */

	tommy_trie_inplace_list_remove(let_ptr, remove);

	/* if not change in the node, nothing more to do */
	if (*let_ptr == node)
		return remove;

	/* if we have a substitute */
	if (*let_ptr != 0) {
		/* copy the child pointers to the new one */
		node = *let_ptr;
		for (i = 0; i < TOMMY_TRIE_INPLACE_TREE_MAX; ++i)
			node->map[i] = remove->map[i];

		return remove;
	}

	/* find a leaf */
	leaf_let_ptr = 0;
	leaf = remove;

	/* search backward, statistically we have more zeros than ones */
	i = TOMMY_TRIE_INPLACE_TREE_MAX - 1;
	while (i >= 0) {
		if (leaf->map[i]) {
			leaf_let_ptr = &leaf->map[i];
			leaf = *leaf_let_ptr;
			i = TOMMY_TRIE_INPLACE_TREE_MAX - 1;
			continue;
		}
		--i;
	}

	/* if it's itself a leaf */
	if (!leaf_let_ptr)
		return remove;

	/* remove the leaf */
	*leaf_let_ptr = 0;

	/* copy the child pointers */
	for (i = 0; i < TOMMY_TRIE_INPLACE_TREE_MAX; ++i)
		leaf->map[i] = remove->map[i];

	/* put it in place */
	*let_ptr = leaf;

	return remove;
}

// Assembly:
subq $0x58, %rsp
movl %edi, 0x4c(%rsp)
movq %rsi, 0x40(%rsp)
movq %rdx, 0x38(%rsp)
movl %ecx, 0x34(%rsp)
movq 0x40(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x28(%rsp)
xorl %eax, %eax
cmpq $0x0, 0x28(%rsp)
movb %al, 0xf(%rsp)
je 0x4404
movq 0x28(%rsp), %rax
movl 0x18(%rax), %eax
cmpl 0x34(%rsp), %eax
setne %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x440e
jmp 0x444e
movq 0x28(%rsp), %rax
addq $0x20, %rax
movl 0x34(%rsp), %edx
movl 0x4c(%rsp), %ecx
shrl %cl, %edx
movl %edx, %ecx
andl $0x3, %ecx
movl %ecx, %ecx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x28(%rsp)
movl 0x4c(%rsp), %eax
subl $0x2, %eax
movl %eax, 0x4c(%rsp)
jmp 0x43e3
cmpq $0x0, 0x28(%rsp)
jne 0x4464
movq $0x0, 0x50(%rsp)
jmp 0x45e7
cmpq $0x0, 0x38(%rsp)
jne 0x4476
movq 0x28(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x61a0
movq 0x40(%rsp), %rax
movq (%rax), %rax
cmpq 0x28(%rsp), %rax
jne 0x44a3
movq 0x38(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0x45e7
movq 0x40(%rsp), %rax
cmpq $0x0, (%rax)
je 0x4504
movq 0x40(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x28(%rsp)
movl $0x0, 0x24(%rsp)
cmpl $0x4, 0x24(%rsp)
jge 0x44f5
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq 0x20(%rax,%rcx,8), %rdx
movq 0x28(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq %rdx, 0x20(%rax,%rcx,8)
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x44c3
movq 0x38(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0x45e7
movq $0x0, 0x18(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x10(%rsp)
movl $0x3, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
jl 0x4576
movq 0x10(%rsp), %rax
movslq 0x24(%rsp), %rcx
cmpq $0x0, 0x20(%rax,%rcx,8)
je 0x4569
movq 0x10(%rsp), %rax
addq $0x20, %rax
movslq 0x24(%rsp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x10(%rsp)
movl $0x3, 0x24(%rsp)
jmp 0x451f
movl 0x24(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x451f
cmpq $0x0, 0x18(%rsp)
jne 0x458a
movq 0x38(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0x45e7
movq 0x18(%rsp), %rax
movq $0x0, (%rax)
movl $0x0, 0x24(%rsp)
cmpl $0x4, 0x24(%rsp)
jge 0x45d0
movq 0x38(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq 0x20(%rax,%rcx,8), %rdx
movq 0x10(%rsp), %rax
movslq 0x24(%rsp), %rcx
movq %rdx, 0x20(%rax,%rcx,8)
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x459e
movq 0x10(%rsp), %rcx
movq 0x40(%rsp), %rax
movq %rcx, (%rax)
movq 0x38(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)