// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x4d8, %rsp            # imm = 0x4D8
movq %rdi, 0x4d0(%rsp)
movq 0x4d0(%rsp), %rdi
addq $0x158, %rdi            # imm = 0x158
callq 0x23e0
movq 0x4d0(%rsp), %rax
movl 0x10(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0xab89
movq 0x4d0(%rsp), %rax
movl 0x10(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xabd9
leaq 0x13748(%rip), %rax     # 0x1e2d8
movl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0xabc0
leaq 0x1373e(%rip), %rax     # 0x1e2e0
movq (%rax), %rcx
movq 0x4d0(%rsp), %rax
movl 0x10(%rax), %edx
movl $0x3, %edi
leaq 0xdf2b(%rip), %rsi      # 0x18ae7
movb $0x0, %al
callq *%rcx
movq 0x4d0(%rsp), %rdi
addq $0x158, %rdi            # imm = 0x158
callq 0x21c0
jmp 0xb080
movq 0x4d0(%rsp), %rax
movl 0x10(%rax), %ecx
orl $0x1, %ecx
movl %ecx, 0x10(%rax)
movl $0x0, 0x4cc(%rsp)
movl 0x4cc(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0x4d0(%rsp), %rdi
addq $0xf8, %rdi
callq 0x9da0
movl %eax, %ecx
movl 0x24(%rsp), %eax
cmpl %ecx, %eax
jae 0xad12
movq 0x4d0(%rsp), %rdi
addq $0xf8, %rdi
movl 0x4cc(%rsp), %esi
callq 0x9db0
movq %rax, 0x4c0(%rsp)
cmpq $0x0, 0x4c0(%rsp)
jne 0xac55
jmp 0xacfc
movq 0x4c0(%rsp), %rax
testb $0x1, 0x18(%rax)
je 0xacfa
leaq 0x1366a(%rip), %rax     # 0x1e2d8
movl (%rax), %ecx
movl $0x3, %eax
cmpl %ecx, %eax
jg 0xacac
leaq 0x13660(%rip), %rax     # 0x1e2e0
movq (%rax), %r9
movq 0x4c0(%rsp), %rdx
movq 0x4c0(%rsp), %rcx
movl 0x4cc(%rsp), %r8d
movl $0x3, %edi
leaq 0xde7d(%rip), %rsi      # 0x18b24
movb $0x0, %al
callq *%r9
movq 0x4d0(%rsp), %rdi
addq $0xf8, %rdi
movl 0x4cc(%rsp), %esi
callq 0x17480
movl 0x4cc(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x4cc(%rsp)
movq 0x4d0(%rsp), %rdi
movq 0x4c0(%rsp), %rsi
callq 0xce50
movq 0x4c0(%rsp), %rdi
callq 0xa8f0
jmp 0xacfc
movl 0x4cc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4cc(%rsp)
jmp 0xabf5
movq 0x4d0(%rsp), %rdi
addq $0x158, %rdi            # imm = 0x158
callq 0x21c0
movq 0x4d0(%rsp), %rdi
addq $0x18, %rdi
callq 0x9da0
movl %eax, 0x4bc(%rsp)
leaq 0xb0(%rsp), %rdx
leaq 0x68(%rsp), %rdi
movl $0x10, %esi
movl $0x400, %ecx            # imm = 0x400
xorl %r8d, %r8d
callq 0x16c50
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
cmpl 0x4bc(%rsp), %eax
jae 0xadd2
movq 0x4d0(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x4d0(%rsp), %rdi
addq $0x18, %rdi
movl 0x64(%rsp), %esi
callq 0x9db0
movq %rax, 0x18(%rsp)
movq 0x4d0(%rsp), %rdi
addq $0x60, %rdi
movl 0x64(%rsp), %esi
callq 0xa220
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rsi
leaq 0x68(%rsp), %rcx
movswl %ax, %edx
callq 0xd460
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0xad65
movl $0x0, 0x60(%rsp)
movl 0x60(%rsp), %eax
movl %eax, 0xc(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x9da0
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jae 0xae46
movl 0x60(%rsp), %esi
leaq 0x68(%rsp), %rdi
callq 0x17340
movq %rax, 0x58(%rsp)
movq 0x4d0(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x9ca0
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jne 0xae37
movq 0x4d0(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0xc580
jmp 0xae39
movl 0x60(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x60(%rsp)
jmp 0xadda
movq 0x4d0(%rsp), %rax
movzwl 0x140(%rax), %eax
cmpl $0x0, %eax
jne 0xae6c
movq 0x4d0(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0xc2b0
movl $0x0, 0x74(%rsp)
movl 0x6c(%rsp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0xae99
movq 0x78(%rsp), %rdi
movl 0x70(%rsp), %eax
imull 0x68(%rsp), %eax
movl %eax, %eax
movl %eax, %edx
xorl %esi, %esi
callq 0x2170
movl $0x0, 0x54(%rsp)
movl 0x54(%rsp), %eax
movl %eax, 0x8(%rsp)
movq 0x4d0(%rsp), %rdi
addq $0xf8, %rdi
callq 0x9da0
movl %eax, %ecx
movl 0x8(%rsp), %eax
cmpl %ecx, %eax
jae 0xaf6c
movq 0x4d0(%rsp), %rdi
addq $0xf8, %rdi
movl 0x54(%rsp), %esi
callq 0x9db0
movq %rax, 0x48(%rsp)
movq 0x4d0(%rsp), %rdi
movq 0x48(%rsp), %rsi
leaq 0x68(%rsp), %rdx
callq 0xc630
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
movl %eax, 0x4(%rsp)
movq 0x48(%rsp), %rdi
addq $0x20, %rdi
callq 0x9da0
movl %eax, %ecx
movl 0x4(%rsp), %eax
cmpl %ecx, %eax
jae 0xaf5a
movq 0x48(%rsp), %rdi
addq $0x20, %rdi
movl 0x44(%rsp), %esi
callq 0x17340
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0x171b0
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0xaf07
jmp 0xaf5c
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0xaea1
movq 0x4d0(%rsp), %rax
movb 0x14(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xb03d
movl $0x0, 0x34(%rsp)
movl $0x0, 0x30(%rsp)
movl 0x30(%rsp), %eax
movl %eax, (%rsp)
leaq 0x68(%rsp), %rdi
callq 0x9da0
movl %eax, %ecx
movl (%rsp), %eax
cmpl %ecx, %eax
jae 0xb028
movl 0x30(%rsp), %esi
leaq 0x68(%rsp), %rdi
callq 0x17340
movq %rax, 0x28(%rsp)
movq 0x4d0(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x9ca0
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jne 0xb016
callq 0xce30
cmpl $0x0, %eax
je 0xaff9
movq 0x28(%rsp), %rsi
leaq 0xdb4f(%rip), %rdi      # 0x18b43
callq 0x167d0
movq 0x4d0(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0xc580
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0xb018
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0xaf95
cmpl $0x0, 0x34(%rsp)
jne 0xb03b
movq 0x4d0(%rsp), %rax
movb $0x1, 0x16(%rax)
jmp 0xb03d
leaq 0x68(%rsp), %rdi
callq 0x16e10
movq 0x4d0(%rsp), %rdi
addq $0x158, %rdi            # imm = 0x158
callq 0x23e0
movq 0x4d0(%rsp), %rax
movl 0x10(%rax), %ecx
andl $-0x2, %ecx
movl %ecx, 0x10(%rax)
movq 0x4d0(%rsp), %rdi
addq $0x158, %rdi            # imm = 0x158
callq 0x21c0
addq $0x4d8, %rsp            # imm = 0x4D8
retq
nopl (%rax,%rax)