// File: /workspace/github_cpp_makefile_star2_O3/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 %rbx
subq $0x50, %rsp
movq (%rsi), %r9
testq %r9, %r9
je 0x2a18
movl %ecx, %eax
movl $0x1b, %ecx
xorl %r8d, %r8d
testb $0x1, %r9b
je 0x2a23
movl %r8d, %r10d
incl %r8d
movq %rsi, (%rsp,%r10,8)
movl %eax, %esi
shrl %cl, %esi
andl $0x7, %esi
leaq (%r9,%rsi,8), %rsi
decq %rsi
addl $-0x3, %ecx
movq (%rsi), %r9
testq %r9, %r9
jne 0x29ef
xorl %edx, %edx
movq %rdx, %rax
addq $0x50, %rsp
popq %rbx
retq
testq %rdx, %rdx
jne 0x2a31
movq %r9, %rdx
cmpl %eax, 0x18(%r9)
jne 0x2a18
movq (%rdx), %rax
movq 0x8(%rdx), %rcx
testq %rax, %rax
movq %rax, %r10
cmoveq %r9, %r10
movq %rcx, 0x8(%r10)
cmpq %rdx, %r9
cmoveq %rsi, %rcx
movq %rax, (%rcx)
cmpq $0x0, (%rsi)
sete %al
testl %r8d, %r8d
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x2a1a
movl %r8d, %eax
movq -0x8(%rsp,%rax,8), %rsi
decq %rax
movq (%rsi), %rcx
decq %rcx
movb $0x1, %r8b
xorl %ebx, %ebx
xorl %r9d, %r9d
xorl %r10d, %r10d
movq %rbx, %r11
movq (%rcx,%r11,8), %rbx
testq %rbx, %rbx
jne 0x2a97
incq %r11
cmpq $0x8, %r11
jne 0x2a83
jmp 0x2ac2
testb $0x1, %bl
sete %r9b
testb %r8b, %r9b
je 0x2a1a
leaq 0x1(%r11), %rbx
movb $0x1, %r10b
xorl %r8d, %r8d
movq %r11, %r9
cmpq $0x7, %r11
jne 0x2a80
movl $0x7, %r9d
jmp 0x2ac8
testb $0x1, %r10b
je 0x2af9
movl %r9d, %r8d
movq (%rcx,%r8,8), %r8
movq %r8, (%rsi)
movq 0x108(%rdi), %rsi
movq (%rsi), %r8
movq %r8, (%rcx)
movq %rcx, (%rsi)
decl 0x20(%rsi)
decl 0x104(%rdi)
testq %rax, %rax
jne 0x2a67
jmp 0x2a1a
leaq 0x17c8(%rip), %rdi      # 0x42c8
leaq 0x16af(%rip), %rsi      # 0x41b6
leaq 0x17c5(%rip), %rcx      # 0x42d3
movl $0xee, %edx
callq 0x1050