// File: /workspace/github_c_makefile_star2_O3/sharpyfox[P]citrusleaf-client/src/cl_cluster.c
// Function: cluster_tend
static void
cluster_tend(cl_cluster *asc)
{
	pthread_mutex_lock(&asc->LOCK);
	// If thre is already a tending process running for this cluster, there is no
	// point in running one more immediately. Moreover, there are assumptions in
	// the code that only one tender function is running at a time. So, abort.
	if ((asc->state & CLS_FREED) || (asc->state & CLS_TENDER_RUNNING)) {
		cf_debug("Not running cluster tend as the state of the cluster is 0x%x", asc->state);
		pthread_mutex_unlock(&asc->LOCK);
		return;
	}
	asc->state |= CLS_TENDER_RUNNING;

	// Start off by removing dunned hosts
	for (uint i=0;i<cf_vector_size(&asc->node_v);i++) {
		cl_cluster_node *cn = cf_vector_pointer_get(&asc->node_v, i);
		if (!cn)	continue;
		if (cn->dunned) {
			cf_debug(" DELETE DUNNED NODE %s %p i %d",cn->name,cn,i);
			cf_vector_delete(&asc->node_v, i);
			i--;
			cl_partition_table_remove_node(asc, cn);
			cl_cluster_node_release(cn);
		}
	}
	pthread_mutex_unlock(&asc->LOCK);

	// For all registered hosts --- resolve into the cluster's sockaddr_in list
	uint n_hosts = cf_vector_size(&asc->host_str_v);
	cf_vector_define(sockaddr_in_v, sizeof( struct sockaddr_in ), 0);
	for (uint i=0;i<n_hosts;i++) {
		/*
        if (cf_debug_enabled()) {
		    char *host = cf_vector_pointer_get(&asc->host_str_v, i);
		    int port = cf_vector_integer_get(&asc->host_port_v, i);
    		cf_debug("lookup hosts: %s:%d",host,port);
        }
        */
		cl_lookup(asc, cf_vector_pointer_get(&asc->host_str_v, i), 
					cf_vector_integer_get(&asc->host_port_v, i),
					&sockaddr_in_v);
	}
	// Compare this list against the current list of addresses of known nodes.
	// anything new, ping and get its info
	for (uint i=0;i<cf_vector_size(&sockaddr_in_v);i++) {
		struct sockaddr_in *sin = cf_vector_getp(&sockaddr_in_v,i);
		if (0 == cl_cluster_node_get_byaddr(asc, sin)) {
			cluster_ping_address(asc, sin);
		}
	}
	
	if (asc->n_partitions == 0)
		cluster_get_n_partitions(asc, &sockaddr_in_v);
	
	// vector will now contain an accumulation of the service addresses
	cf_vector_reset(&sockaddr_in_v);

	// Now, ping known nodes to see if there's an update
	// No need to lock node list because nodes are only added/removed in this thread.
	for (uint i = 0; i < cf_vector_size(&asc->node_v); i++) {
		cl_cluster_node *cn = cf_vector_pointer_get(&asc->node_v, i);
		cluster_ping_node(asc, cn, &sockaddr_in_v);
		for (uint j=0;j<cf_vector_size(&cn->sockaddr_in_v);j++) {
			struct sockaddr_in *sa_in = cf_vector_getp(&cn->sockaddr_in_v,j);
			cf_vector_append_unique(&sockaddr_in_v, sa_in);
		}
	}
	
	// cf_debug("CLUSTER TEND: sockaddr_in_v len %d %s",cf_vector_size(&sockaddr_in_v), asc->found_all?"foundall":"notfound" );
	
	// Compare all services with known nodes - explore if new
	if (asc->follow == true) {
		int n_new = 0;
		for (uint i=0;i<cf_vector_size(&sockaddr_in_v);i++) {
			struct sockaddr_in *sin = cf_vector_getp(&sockaddr_in_v, i);
			/*
			if (cf_debug_enabled()) {
				dump_sockaddr_in("testing service address",sin);
			}
			*/
			if (0 == cl_cluster_node_get_byaddr(asc, sin)) {
				if (cf_debug_enabled()) {
					cf_print_sockaddr_in("pinging",sin);
				}		
				cluster_ping_address(asc, sin);
				n_new++;
			}
		}
		if (n_new == 0)	{
			//cf_debug("CLUSTER TEND: *** FOUND ALL ***");
			asc->found_all = true;
		}
		//cf_debug("CLUSTER TEND: n_new is %d foundall %d",n_new,asc->found_all);
	}

	cf_vector_destroy(&sockaddr_in_v);

#ifdef DEBUG	
	dump_cluster(asc);
#endif	

	pthread_mutex_lock(&asc->LOCK);
	asc->state &= ~CLS_TENDER_RUNNING;
	pthread_mutex_unlock(&asc->LOCK);

	return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd48, %rsp            # imm = 0xD48
leaq 0x158(%rdi), %rbx
movq %rdi, %r14
movq %rbx, %rdi
callq 0x23b0
movl 0x10(%r14), %edx
testb $0x3, %dl
je 0x7361
leaq 0xefa1(%rip), %rax      # 0x162c8
movl (%rax), %eax
cmpl $0x3, %eax
jl 0x7348
leaq 0xef9b(%rip), %rax      # 0x162d0
leaq 0x875f(%rip), %rsi      # 0xfa9b
movl $0x3, %edi
movq (%rax), %rcx
xorl %eax, %eax
callq *%rcx
movq %rbx, %rdi
addq $0xd48, %rsp            # imm = 0xD48
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2190
orl $0x1, %edx
leaq 0xf8(%r14), %rax
movq %rbx, 0x10(%rsp)
movl %edx, 0x10(%r14)
movq %rax, 0x18(%rsp)
movq %r14, 0x8(%rsp)
cmpl $0x0, 0x104(%r14)
je 0x7423
leaq 0xef35(%rip), %r12      # 0x162c8
leaq 0xef36(%rip), %r13      # 0x162d0
leaq 0x140(%rsp), %rbx
leaq 0x872f(%rip), %r14      # 0xfad8
xorl %ebp, %ebp
movq 0x18(%rsp), %rdi
movl %ebp, %esi
movq %rbx, %rdx
callq 0xe7d4
movq 0x140(%rsp), %r15
testq %r15, %r15
je 0x7414
cmpb $0x1, 0x18(%r15)
jne 0x7414
movl (%r12), %eax
cmpl $0x3, %eax
jl 0x73f1
movq (%r13), %r9
movl $0x3, %edi
movq %r14, %rsi
movq %r15, %rdx
movq %r15, %rcx
movl %ebp, %r8d
xorl %eax, %eax
callq *%r9
movq 0x18(%rsp), %rdi
movl %ebp, %esi
callq 0xe8c1
movq 0x8(%rsp), %rdi
movq %r15, %rsi
decl %ebp
callq 0x889c
movq %r15, %rdi
callq 0x7188
movq 0x8(%rsp), %rax
incl %ebp
cmpl 0x104(%rax), %ebp
jb 0x73ab
movq 0x10(%rsp), %rdi
callq 0x2190
movq 0x8(%rsp), %rax
leaq 0x38(%rsp), %rdi
leaq 0x940(%rsp), %rdx
movl $0x10, %esi
movl $0x400, %ecx            # imm = 0x400
xorl %r8d, %r8d
xorl %ebx, %ebx
movl 0x24(%rax), %r13d
callq 0xe49a
testl %r13d, %r13d
je 0x74b4
movq 0x8(%rsp), %rax
leaq 0x140(%rsp), %r12
leaq 0x18(%rax), %r14
leaq 0x60(%rax), %r15
movq %r14, %rdi
movl %ebx, %esi
movq %r12, %rdx
callq 0xe7d4
movq 0x140(%rsp), %rbp
movq %r15, %rdi
movl %ebx, %esi
movq %r12, %rdx
callq 0xe7d4
movswl 0x140(%rsp), %edx
movq 0x8(%rsp), %rdi
movq %rbp, %rsi
leaq 0x38(%rsp), %rcx
callq 0x8bfc
incl %ebx
cmpl %ebx, %r13d
jne 0x7471
cmpl $0x0, 0x44(%rsp)
movq 0x8(%rsp), %r13
je 0x74f7
xorl %ebx, %ebx
leaq 0x38(%rsp), %r14
movq %r14, %rdi
movl %ebx, %esi
callq 0xe834
movq %r13, %rdi
movq %rax, %rsi
movq %rax, %r15
callq 0x6a14
testq %rax, %rax
jne 0x74ef
movq %r13, %rdi
movq %r15, %rsi
callq 0x85b7
incl %ebx
cmpl 0x44(%rsp), %ebx
jb 0x74c7
cmpw $0x0, 0x140(%r13)
jne 0x750f
leaq 0x38(%rsp), %rsi
movq %r13, %rdi
callq 0x848a
movl $0x0, 0x44(%rsp)
testb $0x2, 0x3c(%rsp)
je 0x7533
movl 0x38(%rsp), %edx
movq 0x48(%rsp), %rdi
xorl %esi, %esi
imull 0x40(%rsp), %edx
callq 0x2140
cmpl $0x0, 0x104(%r13)
je 0x78c7
leaq 0xf8(%rsp), %r15
leaq 0x38(%rsp), %r12
xorl %esi, %esi
movq 0x18(%rsp), %rdi
leaq 0x140(%rsp), %rdx
movl %esi, 0x2c(%rsp)
callq 0xe7d4
movq 0x140(%rsp), %rbx
cmpl $0x0, 0x2c(%rbx)
je 0x78b4
leaq 0x20(%rbx), %r14
xorl %ebp, %ebp
movq %r14, %rdi
movl %ebp, %esi
callq 0xe834
movq %rbx, %rdi
movq %rax, %rsi
leaq 0x80(%rsp), %rdx
callq 0xbaff
testl %eax, %eax
je 0x75f3
leaq 0xed22(%rip), %rax      # 0x162c8
movl (%rax), %eax
cmpl $0x3, %eax
jl 0x75ca
leaq 0xed1c(%rip), %rax      # 0x162d0
movl $0x3, %edi
leaq 0x853f(%rip), %rsi      # 0xfaff
movq %rbx, %rdx
movq (%rax), %rcx
xorl %eax, %eax
callq *%rcx
cmpb $0x0, 0x18(%rbx)
jne 0x75e5
movl $0x12c, %eax            # imm = 0x12C
lock
xaddl %eax, 0x14(%rbx)
cmpl $0x1f5, %eax            # imm = 0x1F5
jl 0x75e5
movb $0x1, 0x18(%rbx)
movl 0x2c(%rbx), %eax
incl %ebp
cmpl %eax, %ebp
jb 0x757e
jmp 0x7892
movb 0x18(%rbx), %bpl
cmpb $0x1, 0xac(%rsp)
jne 0x762d
testb %bpl, %bpl
jne 0x761b
movl $0x12c, %eax            # imm = 0x12C
lock
xaddl %eax, 0x14(%rbx)
cmpl $0x1f5, %eax            # imm = 0x1F5
jl 0x761b
movb $0x1, 0x18(%rbx)
leaq 0x80(%rsp), %rdi
callq 0xbd06
jmp 0x788f
testb %bpl, %bpl
jne 0x7639
movl $0x0, 0x14(%rbx)
leaq 0x88(%rsp), %rdi
movq %rbx, %rsi
callq 0x2350
testl %eax, %eax
je 0x769d
leaq 0xec74(%rip), %rax      # 0x162c8
movl (%rax), %eax
cmpl $0x2, %eax
jl 0x7685
leaq 0xec6e(%rip), %rax      # 0x162d0
movl $0x2, %edi
leaq 0x84ac(%rip), %rsi      # 0xfb1a
movq %rbx, %rdx
leaq 0x88(%rsp), %rcx
movq (%rax), %r8
xorl %eax, %eax
callq *%r8
movb 0x18(%rbx), %bpl
testb $0x1, %bpl
jne 0x769d
movl $0x321, %eax            # imm = 0x321
lock
xaddl %eax, 0x14(%rbx)
testl %eax, %eax
js 0x769d
movb $0x1, 0x18(%rbx)
movl 0x68(%rbx), %eax
movl 0xa8(%rsp), %ecx
cmpl %ecx, %eax
movl %eax, 0x28(%rsp)
je 0x76b2
movl %ecx, 0x68(%rbx)
movq 0xa0(%rsp), %rbp
leaq 0xb0(%rsp), %r13
movl %ecx, 0x24(%rsp)
movl $0x8, %esi
leaq 0x140(%rsp), %rdx
movl $0x400, %ecx            # imm = 0x400
xorl %r8d, %r8d
movq %r13, %rdi
callq 0xe49a
movl $0x3b, %edi
movq %rbp, %rsi
movq %r13, %rdx
callq 0x81c6
cmpl $0x0, 0xbc(%rsp)
je 0x77ba
xorl %ebp, %ebp
movq %r15, %r12
leaq 0x540(%rsp), %r15
leaq 0xb0(%rsp), %rdi
movl %ebp, %esi
movq %r15, %rdx
callq 0xe7d4
movq 0x540(%rsp), %r13
movq %r15, %rdx
movq %r12, %rdi
movl $0x8, %esi
movl $0x400, %ecx            # imm = 0x400
xorl %r8d, %r8d
movq %r12, %r15
callq 0xe49a
movl $0x3a, %edi
movq %r13, %rsi
movq %r12, %rdx
callq 0x81c6
cmpl $0x2, 0x104(%rsp)
jne 0x77a3
leaq 0x30(%rsp), %r12
movq %r15, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0xe7d4
movq 0x30(%rsp), %r13
movq %r15, %rdi
movl $0x1, %esi
movq %r12, %rdx
callq 0xe7d4
movq 0x30(%rsp), %rdi
callq 0x2440
movq 0x8(%rsp), %rdi
movswl %ax, %edx
movq %r13, %rsi
leaq 0x38(%rsp), %rcx
callq 0x8bfc
movq %r15, %rdi
callq 0xe580
incl %ebp
cmpl 0xbc(%rsp), %ebp
jb 0x7703
leaq 0xb0(%rsp), %rdi
callq 0xe580
leaq 0x80(%rsp), %rdi
callq 0xbd06
movl 0x24(%rsp), %eax
movq 0x8(%rsp), %r13
leaq 0x38(%rsp), %r12
cmpl %eax, 0x28(%rsp)
je 0x788f
movq 0x10(%rsp), %r13
movq %r13, %rdi
callq 0x23b0
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
callq 0x889c
movq %r13, %rdi
movq 0x8(%rsp), %r13
callq 0x2190
cmpl $0x0, 0x2c(%rbx)
je 0x78b4
xorl %ebp, %ebp
movq %r14, %rdi
movl %ebp, %esi
callq 0xe834
movq %rbx, %rdi
movq %rax, %rsi
leaq 0x140(%rsp), %rdx
callq 0xbd13
testl %eax, %eax
je 0x784b
movl 0x2c(%rbx), %eax
incl %ebp
cmpl %eax, %ebp
jb 0x781f
jmp 0x7892
movq 0x148(%rsp), %rdx
testq %rdx, %rdx
je 0x7868
movq %r13, %rdi
movq %rbx, %rsi
movl $0x1, %ecx
callq 0x863c
movq 0x150(%rsp), %rdx
testq %rdx, %rdx
je 0x7882
movq %r13, %rdi
movq %rbx, %rsi
xorl %ecx, %ecx
callq 0x863c
leaq 0x140(%rsp), %rdi
callq 0xbf11
movl 0x2c(%rbx), %eax
testl %eax, %eax
je 0x78b4
xorl %ebp, %ebp
movq %r14, %rdi
movl %ebp, %esi
callq 0xe834
movq %r12, %rdi
movq %rax, %rsi
callq 0xe762
incl %ebp
cmpl 0x2c(%rbx), %ebp
jb 0x7898
movl 0x2c(%rsp), %esi
incl %esi
cmpl 0x104(%r13), %esi
jb 0x7550
cmpb $0x1, 0x14(%r13)
jne 0x7944
cmpl $0x0, 0x44(%rsp)
je 0x793f
leaq 0xe9ec(%rip), %r13      # 0x162c8
xorl %ebx, %ebx
leaq 0x38(%rsp), %r14
leaq 0x820d(%rip), %r15      # 0xfaf7
xorl %ebp, %ebp
movq %r14, %rdi
movl %ebx, %esi
callq 0xe834
movq 0x8(%rsp), %rdi
movq %rax, %rsi
movq %rax, %r12
callq 0x6a14
testq %rax, %rax
jne 0x792e
movl (%r13), %eax
cmpl $0x3, %eax
jl 0x791f
movq %r15, %rdi
movq %r12, %rsi
callq 0xe24d
movq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x85b7
incl %ebp
incl %ebx
cmpl 0x44(%rsp), %ebx
jb 0x78ec
movq 0x8(%rsp), %r13
testl %ebp, %ebp
jne 0x7944
movb $0x1, 0x16(%r13)
leaq 0x38(%rsp), %rdi
callq 0xe580
movq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0x23b0
andb $-0x2, 0x10(%r13)
movq %rbx, %rdi
callq 0x2190
addq $0xd48, %rsp            # imm = 0xD48
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq