// File: /workspace/github_c_makefile_star2_O1/sharpyfox[P]citrusleaf-client/tests/loop_c/src/shash.c
// Function: shash_reduce_delete
int
shash_reduce_delete(shash *h, shash_reduce_fn reduce_fn, void *udata)
{
	int rv = 0;
	
	if (h->flags & SHASH_CR_MT_BIGLOCK) {
		pthread_mutex_lock( &h->biglock);
	}
	
	for (uint i=0; i<h->table_len ; i++) {

		pthread_mutex_t *l = 0;
		if (h->flags & SHASH_CR_MT_MANYLOCK) {
			l = &(h->lock_table[i]);
			pthread_mutex_lock( l );
		}
		
		shash_elem *list_he = (shash_elem *) ( ((uint8_t *)h->table) + (SHASH_ELEM_SZ(h) * i));
		shash_elem *prev_he = 0;
		
		while (list_he) {
			// This kind of structure might have the head as an empty element,
			// that's a signal to move along
			if (list_he->in_use == false)
				break;
			
			rv = reduce_fn( SHASH_ELEM_KEY_PTR(h, list_he), SHASH_ELEM_VALUE_PTR(h, list_he), udata);
			
			// Delete is requested
			// Leave the pointers in a "next" state
			if (rv == SHASH_REDUCE_DELETE) {

				// patchup pointers & free element if not head
				if (prev_he) {
					prev_he->next = list_he->next;
					free (list_he);
					list_he = prev_he->next;
				}
				// am at head - more complicated
				else {
					// at head with no next - easy peasy!
					if (0 == list_he->next) {
						list_he->in_use = false;
						list_he = 0;
					}
					// at head with a next - more complicated -
					// copy next into current and free next
					// (the old trick of how to delete from a singly
					// linked list without a prev pointer)
					// Somewhat confusingly, prev_he stays 0
					// and list_he stays where it is
					else {
						shash_elem *_t = list_he->next;
						memcpy(list_he, list_he->next, SHASH_ELEM_SZ(h) );
						free(_t);
					}
				}
				rv = 0;
			}
			else if (0 != rv) {
				if (l)	pthread_mutex_unlock(l);
				goto Out;
			}
			else { // don't delete, just forward everything
				prev_he = list_he;
				list_he = list_he->next;
			}	
		};
		
		if (l) pthread_mutex_unlock(l);
	}

Out:

	if (h->flags & SHASH_CR_MT_BIGLOCK)
		pthread_mutex_unlock( &h->biglock);
	
	return(rv);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, 0x10(%rsp)
movq %rsi, 0x8(%rsp)
movq %rdi, %rbx
testb $0x4, 0xc(%rdi)
je 0x446f
leaq 0x28(%rbx), %rdi
callq 0x23b0
movl $0x2, %r15d
cmpl $0x0, 0x18(%rbx)
je 0x459c
xorl %r14d, %r14d
xorl %ebp, %ebp
testb $0x8, 0xc(%rbx)
jne 0x4494
movq $0x0, (%rsp)
jmp 0x44a9
leaq (%r14,%r14,4), %rdi
shlq $0x3, %rdi
addq 0x50(%rbx), %rdi
movq %rdi, (%rsp)
callq 0x23b0
movq 0x20(%rbx), %rax
testq %rax, %rax
je 0x4567
movl 0x4(%rbx), %ecx
movl 0x8(%rbx), %edx
leaq 0x10(%rcx,%rdx), %rcx
imulq %r14, %rcx
cmpb $0x0, 0x8(%rax,%rcx)
je 0x4567
leaq (%rax,%rcx), %r13
leaq 0x8(%rax,%rcx), %r12
xorl %r15d, %r15d
leaq 0x9(%r13), %rdi
movl 0x4(%rbx), %eax
leaq 0x9(%r13,%rax), %rsi
movq 0x10(%rsp), %rdx
callq *0x8(%rsp)
testl %eax, %eax
je 0x4519
movl %eax, %ebp
cmpl $0x1, %eax
jne 0x4591
testq %r15, %r15
movq (%r13), %rbp
je 0x4536
movq %rbp, (%r15)
movq %r13, %rdi
callq 0x22c0
movq (%r15), %rax
jmp 0x4520
movq (%r13), %rax
movq %r13, %r15
xorl %ebp, %ebp
testq %rax, %rax
je 0x4567
leaq 0x8(%rax), %r12
cmpb $0x0, 0x8(%rax)
movq %rax, %r13
jne 0x44dc
jmp 0x4567
testq %rbp, %rbp
je 0x455e
movl 0x4(%rbx), %eax
movl 0x8(%rbx), %ecx
leaq 0x10(%rax,%rcx), %rdx
movq %r13, %rdi
movq %rbp, %rsi
callq 0x21b0
movq %rbp, %rdi
callq 0x22c0
movq %r13, %rax
jmp 0x4520
movb $0x0, (%r12)
xorl %eax, %eax
jmp 0x4520
xorl %r15d, %r15d
movb $0x1, %r12b
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x457b
callq 0x2190
testb %r12b, %r12b
je 0x45a6
incq %r14
movl 0x18(%rbx), %eax
cmpq %rax, %r14
jb 0x4484
jmp 0x45a0
movl $0x7, %r15d
xorl %r12d, %r12d
jmp 0x456d
xorl %ebp, %ebp
jmp 0x45a6
movl $0x2, %r15d
cmpl $0x7, %r15d
je 0x45b2
cmpl $0x2, %r15d
jne 0x45c4
testb $0x4, 0xc(%rbx)
je 0x45c4
addq $0x28, %rbx
movq %rbx, %rdi
callq 0x2190
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq