// File: /workspace/github_c_makefile_star2_O1/sharpyfox[P]citrusleaf-client/tests/key_c/src/key.c
// Function: batch_getmany_cb
int
batch_getmany_cb(char *ns, cf_digest *keyd, char *set, uint32_t generation, uint32_t record_ttl, cl_bin *bins, int n_bins,
	bool is_last, void *udata)
{
	getmany_userdata *gm_udata = (getmany_userdata *) udata;
	cf_digest *keys = gm_udata->digests;
	int batch_factor = gm_udata->batch_factor;
	
	// find the kvs * key_int that matches the request we're making
	key_value *kv = 0;
	uint key_int = 0;
	for (int i=0;i<batch_factor;i++) {
		if (0 == memcmp(&keys[i],keyd,sizeof(cf_digest))) {
			kv = gm_udata->kvs[i];
			key_int = gm_udata->key_ints[i];
			break;
		}
	}
	if (kv == 0) {
		if (!g_config.silent) fprintf(stderr, "read batch value: digest does not match digests we are looking for\n");
		gm_udata->n_received_error++; // maybe needs atomic?
		return(-1);
	}
	
	// start validating	
	if (bins[0].object.type != g_config.value_type) {
		if (!g_config.silent) fprintf(stderr, "read value has wrong type: expect %d got %d\n",(int) g_config.value_type, (int) bins[0].object.type);
		gm_udata->n_received_error++; // maybe needs atomic?
		citrusleaf_object_free(&bins[0].object);
		return(-1);
	}
	
	if (g_config.value_type == CL_STR) {
		if (bins[0].object.u.str == 0) {
			gm_udata->n_received_error++; // maybe needs atomic?
			if (!g_config.silent) fprintf(stderr, "read value pointer is null. Yuck.\n");
			citrusleaf_object_free(&bins[0].object);
			return(-1);
		}
					
		if (bins[0].object.sz  != strlen(kv->value_str)) {
			gm_udata->n_received_error++; // maybe needs atomic?
			if (!g_config.silent) fprintf(stderr, "read value size doesn't match expected. Is %zd expecting %zd\n",
				bins[0].object.sz,strlen(kv->value_str)+1);
			citrusleaf_object_free(&bins[0].object);
			return(-1);
		}			
		
		if (strcmp(bins[0].object.u.str, kv->value_str) != 0) {
			gm_udata->n_received_error++; // maybe needs atomic?
			if (!g_config.silent) {
				fprintf(stderr, "read value does not match set value.\n");
				fprintf(stderr, "  expecting: %s\n",kv->value_str);
				fprintf(stderr, "  got:       %s\n",bins[0].object.u.str);
			}
			citrusleaf_object_free(&bins[0].object);
			return(-1);
		}
	}
	else if (g_config.value_type == CL_BLOB) {
		if (bins[0].object.u.blob == 0) {
			gm_udata->n_received_error++; // maybe needs atomic?
			if (!g_config.silent) fprintf(stderr, "read value pointer is null. Yuck.\n");
			citrusleaf_object_free(&bins[0].object);
			return(-1);
		}
		
		if (bins[0].object.sz  != kv->value_blob_len) {
			gm_udata->n_received_error++; // maybe needs atomic?
			if (!g_config.silent) fprintf(stderr, "read value size doesn't match expected. Is %zd expecting %d\n",
				bins[0].object.sz,kv->value_blob_len);
			citrusleaf_object_free(&bins[0].object);
			return(-1);
		}			
		
		if (memcmp(bins[0].object.u.blob, kv->value_blob, kv->value_blob_len) != 0) {
			gm_udata->n_received_error++; // maybe needs atomic?
			if (!g_config.silent) {
				int k;
				uint8_t *b1 = (uint8_t *) bins[0].object.u.blob;
				uint8_t *b2 = (uint8_t *) kv->value_blob;
				for (k=0;k<kv->value_blob_len;k++) {
					if (b1[k] != b2[k]) break;
				}
				
				fprintf(stderr, "read value does not match set value, key int %d, differ at byte %d (length correct).\n",key_int,k);
				dump_buf("got buf: ", b1, kv->value_blob_len);
				dump_buf("expecting buf: ", b2, kv->value_blob_len);

			}
			citrusleaf_object_free(&bins[0].object);
			return(-1);
		}
		
	}
	else if (g_config.value_type == CL_INT) {
		
		if (bins[0].object.u.i64 != kv->value_int) {
			gm_udata->n_received_error++; // maybe needs atomic?
			if (!g_config.silent) {
				fprintf(stderr, "read value does not match set value.\n");
				fprintf(stderr, "  expecting: %"PRIu64"\n",kv->value_int);
				fprintf(stderr, "  got:       %"PRIu64"\n",bins[0].object.u.i64);
			}
			citrusleaf_object_free(&bins[0].object);
			return(-1);

		}			
		
	}
	
	gm_udata->n_received_success++; // maybe needs atomic?

//	fprintf(stderr, "read value success\n");
//	fprintf(stderr, "  expecting: %"PRIu64"\n",kv->value_int);
//	fprintf(stderr, "  got:       %"PRIu64"\n",bins[0].object.u.i64);

	
	// have to hand back any possible malloced memory
//	citrusleaf_object_free(&values[0].object);
	
	return(0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r9, %r14
movq 0x60(%rsp), %rbp
movslq 0x18(%rbp), %rax
testq %rax, %rax
jle 0x42d8
movq (%rbp), %rdx
xorl %ecx, %ecx
movdqu (%rsi), %xmm0
movd 0x10(%rsi), %xmm1
movdqu (%rdx), %xmm2
pcmpeqb %xmm0, %xmm2
movd 0x10(%rdx), %xmm3
pcmpeqb %xmm1, %xmm3
pand %xmm2, %xmm3
pmovmskb %xmm3, %esi
cmpl $0xffff, %esi           # imm = 0xFFFF
je 0x42e0
incq %rcx
addq $0x14, %rdx
cmpq %rcx, %rax
jne 0x42ab
xorl %r12d, %r12d
xorl %r15d, %r15d
jmp 0x42f0
movq 0x8(%rbp), %rax
movq 0x10(%rbp), %rdx
movq (%rax,%rcx,8), %r15
movl (%rdx,%rcx,4), %r12d
testq %r15, %r15
je 0x4392
leaq 0x20(%r14), %rbx
movl 0x20(%r14), %ecx
leaq 0x18028(%rip), %r13     # 0x1c330
movl 0x48(%r13), %edx
cmpl %edx, %ecx
jne 0x43a8
cmpl $0x1, %edx
je 0x442a
cmpl $0x4, %edx
je 0x43d2
cmpl $0x3, %edx
jne 0x4434
movq 0x30(%r14), %r12
testq %r12, %r12
je 0x4479
movq 0x28(%r14), %rax
movq %rax, 0x8(%rsp)
movq 0x10(%r15), %rdi
addq $0x10, %r15
movq %rdi, 0x10(%rsp)
callq 0x20d0
cmpq %rax, 0x8(%rsp)
jne 0x44c2
movq %r12, %rdi
movq 0x10(%rsp), %rsi
callq 0x2360
testl %eax, %eax
je 0x4434
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x43b6
addq $0x30, %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x2c41
jmp 0x43b6
leaq 0x17f97(%rip), %rax     # 0x1c330
cmpb $0x0, 0x29(%rax)
je 0x44e4
incl 0x20(%rbp)
jmp 0x43be
cmpb $0x0, 0x29(%r13)
je 0x44ee
incl 0x20(%rbp)
movq %rbx, %rdi
callq 0x5f99
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x30(%r14), %rdi
testq %rdi, %rdi
je 0x4461
leaq 0x18(%r15), %rcx
movslq 0x18(%r15), %rdx
cmpq %rdx, 0x28(%r14)
jne 0x4491
movq %rcx, 0x8(%rsp)
movq 0x20(%r15), %rsi
callq 0x2240
testl %eax, %eax
je 0x4434
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x43b6
addq $0x30, %r14
addq $0x20, %r15
movq %r14, %rdi
movq %r15, %rsi
movq 0x8(%rsp), %rdx
movl %r12d, %ecx
callq 0x2b7c
jmp 0x43b6
movq 0x30(%r14), %rax
cmpq 0x28(%r15), %rax
jne 0x443b
incl 0x1c(%rbp)
xorl %eax, %eax
jmp 0x43c3
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x43b6
addq $0x30, %r14
addq $0x28, %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x2b28
jmp 0x43b6
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x43b6
callq 0x2bed
jmp 0x43b6
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x43b6
callq 0x2c95
jmp 0x43b6
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x43b6
movq 0x15b3a(%rip), %rax     # 0x19fe0
movq (%rax), %rdi
movq 0x28(%r14), %rdx
movl (%rcx), %ecx
leaq 0xe626(%rip), %rsi      # 0x12adc
xorl %eax, %eax
callq 0x2390
jmp 0x43b6
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x43b6
addq $0x28, %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x2c09
jmp 0x43b6
callq 0x2cb1
jmp 0x43a3
movq 0x15aeb(%rip), %rax     # 0x19fe0
movq (%rax), %rdi
leaq 0xe507(%rip), %rsi      # 0x12a06
xorl %eax, %eax
callq 0x2390
jmp 0x43b3