// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq %rdx, 0x30(%rsp)
movl $0x0, 0x2c(%rsp)
movq 0x40(%rsp), %rax
movl 0xc(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x5119
movq 0x40(%rsp), %rdi
addq $0x28, %rdi
callq 0x23e0
movl $0x0, 0x28(%rsp)
movl 0x28(%rsp), %eax
movq 0x40(%rsp), %rcx
cmpl 0x18(%rcx), %eax
jae 0x5300
movq $0x0, 0x20(%rsp)
movq 0x40(%rsp), %rax
movl 0xc(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x516f
movq 0x40(%rsp), %rax
movq 0x50(%rax), %rax
movl 0x28(%rsp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
callq 0x23e0
movq 0x40(%rsp), %rax
movq 0x20(%rax), %rax
movq 0x40(%rsp), %rcx
movl 0x4(%rcx), %ecx
addq $0x10, %rcx
movq 0x40(%rsp), %rdx
movl 0x8(%rdx), %edx
addq %rdx, %rcx
movl 0x28(%rsp), %edx
imulq %rdx, %rcx
addq %rcx, %rax
movq %rax, 0x18(%rsp)
movq $0x0, 0x10(%rsp)
cmpq $0x0, 0x18(%rsp)
je 0x52dc
movq 0x18(%rsp), %rax
movb 0x8(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x51cb
jmp 0x52dc
movq 0x38(%rsp), %rax
movq 0x18(%rsp), %rdi
addq $0x9, %rdi
movq 0x18(%rsp), %rsi
addq $0x9, %rsi
movq 0x40(%rsp), %rcx
movl 0x4(%rcx), %ecx
addq %rcx, %rsi
movq 0x30(%rsp), %rdx
callq *%rax
movl %eax, 0x2c(%rsp)
cmpl $0x1, 0x2c(%rsp)
jne 0x52a2
cmpq $0x0, 0x10(%rsp)
je 0x5234
movq 0x18(%rsp), %rax
movq (%rax), %rcx
movq 0x10(%rsp), %rax
movq %rcx, (%rax)
movq 0x18(%rsp), %rdi
callq 0x22e0
movq 0x10(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
jmp 0x5298
movq 0x18(%rsp), %rcx
xorl %eax, %eax
cmpq (%rcx), %rax
jne 0x5254
movq 0x18(%rsp), %rax
movb $0x0, 0x8(%rax)
movq $0x0, 0x18(%rsp)
jmp 0x5296
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x8(%rsp)
movq 0x18(%rsp), %rdi
movq 0x18(%rsp), %rax
movq (%rax), %rsi
movq 0x40(%rsp), %rax
movl 0x4(%rax), %eax
movl %eax, %edx
addq $0x10, %rdx
movq 0x40(%rsp), %rax
movl 0x8(%rax), %eax
addq %rax, %rdx
callq 0x21e0
movq 0x8(%rsp), %rdi
callq 0x22e0
jmp 0x5298
movl $0x0, 0x2c(%rsp)
jmp 0x52d7
xorl %eax, %eax
cmpl 0x2c(%rsp), %eax
je 0x52be
cmpq $0x0, 0x20(%rsp)
je 0x52bc
movq 0x20(%rsp), %rdi
callq 0x21c0
jmp 0x5302
movq 0x18(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
jmp 0x52d7
jmp 0x51a8
cmpq $0x0, 0x20(%rsp)
je 0x52ee
movq 0x20(%rsp), %rdi
callq 0x21c0
jmp 0x52f0
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0x5121
jmp 0x5302
movq 0x40(%rsp), %rax
movl 0xc(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x5320
movq 0x40(%rsp), %rdi
addq $0x28, %rdi
callq 0x21c0
movl 0x2c(%rsp), %eax
addq $0x48, %rsp
retq
nopl (%rax)