// File: /workspace/github_cpp_makefile_star2_O2/attractivechaos[P]udb2/tommyds/./tommytrie.c
// Function: trie_bucket_remove_existing
static tommy_trie_node* trie_bucket_remove_existing(tommy_trie* trie, tommy_uint_t shift, tommy_trie_node** let_ptr, tommy_trie_node* remove, tommy_key_t key)
{
	tommy_trie_node* node;
	tommy_trie_tree* tree;
	void* ptr;
	tommy_trie_node** let_back[TOMMY_TRIE_LEVEL_MAX + 1];
	tommy_uint_t level;
	tommy_uint_t i;
	tommy_uint_t count;
	tommy_uint_t last;

	level = 0;
recurse:
	ptr = *let_ptr;

	if (!ptr)
		return 0;

	if (trie_get_type(ptr) == TOMMY_TRIE_TYPE_TREE) {
		tree = trie_get_tree(ptr);

		/* save the path */
		let_back[level++] = let_ptr;

		/* go down one level */
		let_ptr = &tree->map[(key >> shift) & TOMMY_TRIE_TREE_MASK];
		shift -= TOMMY_TRIE_TREE_BIT;

		goto recurse;
	}

	node = tommy_cast(tommy_trie_node*, ptr);

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

		/* check if it's really the element to remove */
		if (remove->key != key)
			return 0;
	}

	tommy_list_remove_existing(let_ptr, remove);

	/* if the list is not empty, try to reduce */
	if (*let_ptr || !level)
		return remove;

reduce:
	/* go one level up */
	let_ptr = let_back[--level];

	tree = trie_get_tree(*let_ptr);

	/* check if there is only one child node */
	count = 0;
	last = 0;
	for (i = 0; i < TOMMY_TRIE_TREE_MAX; ++i) {
		if (tree->map[i]) {
			/* if we have a sub tree, we cannot reduce */
			if (trie_get_type(tree->map[i]) != TOMMY_TRIE_TYPE_NODE)
				return remove;
			/* if more than one node, we cannot reduce */
			if (++count > 1)
				return remove;
			last = i;
		}
	}

	/* here count is never 0, as we cannot have a tree with only one sub node */
	assert(count == 1);

	*let_ptr = tree->map[last];

	tommy_allocator_free(trie->alloc, tree);
	--trie->node_count;

	/* repeat until more level */
	if (level)
		goto reduce;

	return remove;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x50, %rsp
movl %ecx, %eax
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
pushq $0x1b
popq %rcx
xorl %ebp, %ebp
movq (%r15), %rdx
testq %rdx, %rdx
je 0x23e4
movl %ebp, %r12d
testb $0x1, %dl
je 0x234a
movq %r15, (%rsp,%r12,8)
movl %eax, %esi
shrl %cl, %esi
incl %ebp
andl $0x7, %esi
leaq (%rdx,%rsi,8), %r15
decq %r15
addl $-0x3, %ecx
jmp 0x231d
testq %rbx, %rbx
jne 0x235b
movq %rdx, %rbx
cmpl %eax, 0x18(%rdx)
jne 0x23e4
movq %r15, %rdi
movq %rbx, %rsi
callq 0x27a9
cmpq $0x0, (%r15)
sete %al
testl %ebp, %ebp
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x23e6
pushq $0x1
popq %rax
movq -0x8(%rsp,%r12,8), %rdx
decq %r12
movq (%rdx), %rcx
decq %rcx
xorl %esi, %esi
xorl %edi, %edi
xorl %r8d, %r8d
cmpq $0x8, %rsi
je 0x23b4
movq (%rcx,%rsi,8), %r9
testq %r9, %r9
je 0x23af
testb $0x1, %r9b
jne 0x23e6
testl %edi, %edi
jne 0x23e6
movl %eax, %edi
movl %esi, %r8d
incq %rsi
jmp 0x2391
cmpl $0x1, %edi
jne 0x23f6
movl %r8d, %esi
movq (%rcx,%rsi,8), %rsi
movq %rsi, (%rdx)
movq 0x108(%r14), %rdx
movq (%rdx), %rsi
movq %rsi, (%rcx)
movq %rcx, (%rdx)
decl 0x20(%rdx)
decl 0x104(%r14)
testq %r12, %r12
jne 0x237c
jmp 0x23e6
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1e9b(%rip), %rdi      # 0x4298
leaq 0x1d82(%rip), %rsi      # 0x4186
leaq 0x1e98(%rip), %rcx      # 0x42a3
movl $0xee, %edx
callq 0x1050