// File: /workspace/github_c_makefile_star2_O2/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 0x40e6
leaq 0x28(%rbx), %rdi
callq 0x23b0
xorl %r14d, %r14d
movl 0x18(%rbx), %eax
cmpq %rax, %r14
jae 0x4204
testb $0x8, 0xc(%rbx)
jne 0x4105
movq $0x0, (%rsp)
jmp 0x4116
imulq $0x28, %r14, %rdi
addq 0x50(%rbx), %rdi
movq %rdi, (%rsp)
callq 0x23b0
movl 0x4(%rbx), %eax
movl 0x8(%rbx), %ecx
movq %r14, 0x8(%rsp)
leaq 0x10(%rax,%rcx), %rax
imulq %r14, %rax
addq 0x20(%rbx), %rax
xorl %r14d, %r14d
movq %rax, %r13
leaq 0x9(%rax), %rbp
testq %r13, %r13
je 0x41b7
cmpb $0x0, 0x8(%r13)
je 0x41b7
movl 0x4(%rbx), %esi
movq 0x10(%rsp), %rdx
movq %rbp, %rdi
addq %rbp, %rsi
callq *%r15
cmpl $0x1, %eax
jne 0x418b
movq (%r13), %r12
testq %r14, %r14
jne 0x419b
testq %r12, %r12
je 0x41ab
movl 0x4(%rbx), %eax
movl 0x8(%rbx), %ecx
movq %r13, %rdi
movq %r12, %rsi
leaq 0x10(%rax,%rcx), %rdx
callq 0x21b0
movq %r12, %rdi
callq 0x22c0
xorl %r14d, %r14d
jmp 0x4138
movl %eax, %r12d
testl %eax, %eax
jne 0x41d2
movq (%r13), %rax
movq %r13, %r14
jmp 0x4131
movq %r13, %rdi
movq %r12, (%r14)
callq 0x22c0
movq (%r14), %rax
jmp 0x4131
movb $0x0, 0x8(%r13)
xorl %eax, %eax
jmp 0x412e
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x41c5
callq 0x2190
movq 0x8(%rsp), %r14
incq %r14
jmp 0x40e9
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x41e0
callq 0x2190
testb $0x4, 0xc(%rbx)
je 0x41f2
addq $0x28, %rbx
movq %rbx, %rdi
callq 0x2190
movl %r12d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r12d, %r12d
jmp 0x41e0