// File: /workspace/github_c_makefile_star2_O3/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
testb $0x4, 0xc(%rdi)
movq %rsi, %r15
movq %rdi, %rbx
movq %rdx, 0x10(%rsp)
je 0x4444
leaq 0x28(%rbx), %rdi
callq 0x23b0
cmpl $0x0, 0x18(%rbx)
je 0x454b
xorl %r12d, %r12d
testb $0x8, 0xc(%rbx)
jne 0x4462
movq $0x0, 0x8(%rsp)
jmp 0x4478
leaq (%r12,%r12,4), %rdi
shlq $0x3, %rdi
addq 0x50(%rbx), %rdi
movq %rdi, 0x8(%rsp)
callq 0x23b0
movq 0x20(%rbx), %r13
testq %r13, %r13
je 0x4513
movl 0x4(%rbx), %eax
movl 0x8(%rbx), %ecx
xorl %r14d, %r14d
leaq 0x10(%rax,%rcx), %rax
imulq %r12, %rax
addq %rax, %r13
cmpb $0x0, 0x8(%r13)
je 0x4513
movl 0x4(%rbx), %eax
movq 0x10(%rsp), %rdx
leaq 0x9(%r13), %rdi
leaq 0x9(%r13,%rax), %rsi
callq *%r15
testl %eax, %eax
je 0x44d9
movl %eax, %ebp
cmpl $0x1, %eax
jne 0x453a
movq (%r13), %rbp
testq %r14, %r14
je 0x44e2
movq %r13, %rdi
movq %rbp, (%r14)
callq 0x22c0
movq (%r14), %rax
jmp 0x450b
movq (%r13), %rax
movq %r13, %r14
jmp 0x450b
testq %rbp, %rbp
je 0x4533
movl 0x4(%rbx), %eax
movl 0x8(%rbx), %ecx
movq %r13, %rdi
movq %rbp, %rsi
leaq 0x10(%rax,%rcx), %rdx
callq 0x21b0
movq %rbp, %rdi
callq 0x22c0
movq %r13, %rax
xorl %r14d, %r14d
testq %rax, %rax
movq %rax, %r13
jne 0x449a
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x4522
callq 0x2190
movl 0x18(%rbx), %eax
incq %r12
cmpq %rax, %r12
jb 0x4451
jmp 0x454b
movb $0x0, 0x8(%r13)
jmp 0x4513
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x454d
callq 0x2190
jmp 0x454d
xorl %ebp, %ebp
testb $0x4, 0xc(%rbx)
je 0x455f
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