// File: attractivechaos[P]udb2/tommyds/./tommytrie.c
// Function: trie_bucket_insert
static void trie_bucket_insert(tommy_trie* trie, tommy_uint_t shift, tommy_trie_node** let_ptr, tommy_trie_node* insert, tommy_key_t key)
{
	tommy_trie_tree* tree;
	tommy_trie_node* node;
	void* ptr;
	tommy_uint_t i;
	tommy_uint_t j;

recurse:
	ptr = *let_ptr;

	/* if null, just insert the node */
	if (!ptr) {
		/* setup the node as a list */
		tommy_list_insert_first(let_ptr, insert);
		return;
	}

	if (trie_get_type(ptr) == TOMMY_TRIE_TYPE_TREE) {
		/* repeat the process one level down */
		let_ptr = &trie_get_tree(ptr)->map[(key >> shift) & TOMMY_TRIE_TREE_MASK];
		shift -= TOMMY_TRIE_TREE_BIT;
		goto recurse;
	}

	node = tommy_cast(tommy_trie_node*, ptr);

	/* if it's the same key, insert in the list */
	if (node->key == key) {
		tommy_list_insert_tail_not_empty(node, insert);
		return;
	}

expand:
	/* convert to a tree */
	tree = tommy_cast(tommy_trie_tree*, tommy_allocator_alloc(trie->alloc));
	++trie->node_count;
	*let_ptr = tommy_cast(tommy_trie_node*, trie_set_tree(tree));

	/* initialize it */
	for (i = 0; i < TOMMY_TRIE_TREE_MAX; ++i)
		tree->map[i] = 0;

	/* get the position of the two elements */
	i = (node->key >> shift) & TOMMY_TRIE_TREE_MASK;
	j = (key >> shift) & TOMMY_TRIE_TREE_MASK;

	/* if they don't collide */
	if (i != j) {
		/* insert the already existing element */
		tree->map[i] = node;

		/* insert the new node */
		tommy_list_insert_first(&tree->map[j], insert);
		return;
	}

	/* expand one more level */
	let_ptr = &tree->map[i];
	shift -= TOMMY_TRIE_TREE_BIT;
	goto expand;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movl %esi, 0x3c(%rsp)
movq %rdx, 0x30(%rsp)
movq %rcx, 0x28(%rsp)
movl %r8d, 0x24(%rsp)
movq 0x30(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, 0x8(%rsp)
jne 0x3ae5
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x6090
jmp 0x3c47
movq 0x8(%rsp), %rax
andq $0x1, %rax
cmpq $0x1, %rax
jne 0x3b28
movq 0x8(%rsp), %rax
subq $0x1, %rax
movl 0x24(%rsp), %edx
movl 0x3c(%rsp), %ecx
shrl %cl, %edx
movl %edx, %ecx
movl %ecx, %ecx
andq $0x7, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, 0x30(%rsp)
movl 0x3c(%rsp), %eax
subl $0x3, %eax
movl %eax, 0x3c(%rsp)
jmp 0x3abc
movq 0x8(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
movl 0x18(%rax), %eax
cmpl 0x24(%rsp), %eax
jne 0x3b54
movq 0x10(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x60d0
jmp 0x3c47
jmp 0x3b56
movq 0x40(%rsp), %rax
movq 0x108(%rax), %rdi
callq 0x2650
movq %rax, 0x18(%rsp)
movq 0x40(%rsp), %rax
movl 0x104(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x104(%rax)
movq 0x18(%rsp), %rcx
addq $0x1, %rcx
movq 0x30(%rsp), %rax
movq %rcx, (%rax)
movl $0x0, 0x4(%rsp)
movl 0x4(%rsp), %eax
cmpq $0x8, %rax
jae 0x3bc1
movq 0x18(%rsp), %rax
movl 0x4(%rsp), %ecx
movq $0x0, (%rax,%rcx,8)
movl 0x4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4(%rsp)
jmp 0x3b99
movq 0x10(%rsp), %rax
movl 0x18(%rax), %eax
movl 0x3c(%rsp), %ecx
shrl %cl, %eax
movl %eax, %eax
andq $0x7, %rax
movl %eax, 0x4(%rsp)
movl 0x24(%rsp), %eax
movl 0x3c(%rsp), %ecx
shrl %cl, %eax
movl %eax, %eax
andq $0x7, %rax
movl %eax, (%rsp)
movl 0x4(%rsp), %eax
cmpl (%rsp), %eax
je 0x3c22
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rax
movl 0x4(%rsp), %ecx
movq %rdx, (%rax,%rcx,8)
movq 0x18(%rsp), %rdi
movl (%rsp), %eax
shlq $0x3, %rax
addq %rax, %rdi
movq 0x28(%rsp), %rsi
callq 0x6090
jmp 0x3c47
movq 0x18(%rsp), %rax
movl 0x4(%rsp), %ecx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, 0x30(%rsp)
movl 0x3c(%rsp), %eax
subl $0x3, %eax
movl %eax, 0x3c(%rsp)
jmp 0x3b56
addq $0x48, %rsp
retq
nopl (%rax)