// File: /workspace/github_c_makefile_star2_O3/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 0x60(%rsp), %rbp
movslq 0x18(%rbp), %rcx
testq %rcx, %rcx
jle 0x4331
movq (%rbp), %rdx
movdqu (%rsi), %xmm0
movd 0x10(%rsi), %xmm1
movq %r9, %r14
xorl %eax, %eax
movdqu (%rdx), %xmm2
movd 0x10(%rdx), %xmm3
pcmpeqb %xmm0, %xmm2
pcmpeqb %xmm1, %xmm3
pand %xmm2, %xmm3
pmovmskb %xmm3, %esi
cmpl $0xffff, %esi           # imm = 0xFFFF
je 0x4287
incq %rax
addq $0x14, %rdx
cmpq %rax, %rcx
jne 0x4255
jmp 0x4331
movq 0x8(%rbp), %rcx
movq (%rcx,%rax,8), %r15
testq %r15, %r15
je 0x4331
leaq 0x18091(%rip), %r13     # 0x1c330
movl 0x20(%r14), %ecx
leaq 0x20(%r14), %rbx
movl 0x48(%r13), %edx
cmpl %edx, %ecx
jne 0x4355
cmpl $0x1, %ecx
je 0x43d4
cmpl $0x4, %ecx
je 0x4374
cmpl $0x3, %ecx
jne 0x43de
movq 0x30(%r14), %r12
testq %r12, %r12
je 0x4426
movq 0x10(%r15), %rdi
movq 0x28(%r14), %rax
addq $0x10, %r15
movq %rax, 0x8(%rsp)
movq %rdi, 0x10(%rsp)
callq 0x20d0
cmpq %rax, 0x8(%rsp)
jne 0x4471
movq 0x10(%rsp), %rsi
movq %r12, %rdi
callq 0x2360
testl %eax, %eax
je 0x43de
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x4363
addq $0x30, %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x2c4d
jmp 0x4363
leaq 0x17ff8(%rip), %rax     # 0x1c330
cmpb $0x0, 0x29(%rax)
je 0x436d
incl 0x20(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x0, 0x29(%r13)
je 0x4493
incl 0x20(%rbp)
movq %rbx, %rdi
callq 0x5e7d
jmp 0x4341
callq 0x2cbd
jmp 0x433e
movq 0x30(%r14), %rdi
testq %rdi, %rdi
je 0x440e
movq 0x28(%r14), %rdx
movslq 0x18(%r15), %rcx
leaq 0x18(%r15), %r12
cmpq %rcx, %rdx
jne 0x443e
movq 0x10(%rbp), %rcx
movq 0x20(%r15), %rsi
movl (%rcx,%rax,4), %eax
movl %eax, 0x8(%rsp)
callq 0x2240
testl %eax, %eax
je 0x43de
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x4363
movl 0x8(%rsp), %ecx
addq $0x30, %r14
addq $0x20, %r15
movq %r12, %rdx
movq %r14, %rdi
movq %r15, %rsi
callq 0x2b88
jmp 0x4363
movq 0x30(%r14), %rax
cmpq 0x28(%r15), %rax
jne 0x43e8
incl 0x1c(%rbp)
xorl %eax, %eax
jmp 0x4346
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x4363
addq $0x30, %r14
addq $0x28, %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x2b34
jmp 0x4363
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x4363
callq 0x2bf9
jmp 0x4363
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x4363
callq 0x2ca1
jmp 0x4363
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x4363
movq 0x15b8d(%rip), %rax     # 0x19fe0
movq 0x28(%r14), %rdx
movl (%r12), %ecx
leaq 0xe676(%rip), %rsi      # 0x12ad8
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2390
jmp 0x4363
incl 0x20(%rbp)
cmpb $0x0, 0x29(%r13)
jne 0x4363
addq $0x28, %r14
movq %r15, %rsi
movq %r14, %rdi
callq 0x2c15
jmp 0x4363
movq 0x15b46(%rip), %rax     # 0x19fe0
leaq 0xe561(%rip), %rsi      # 0x12a02
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2390
jmp 0x4360