// File: /workspace/github_c_makefile_star2_O3/sharpyfox[P]citrusleaf-client/tests/key_c/src/key.c
// Function: read_fn
void *
read_fn(void *udata)
{
	read_work *work = (read_work *) udata;
	uint32_t delay_factor = 0;

	if (g_config.verbose) fprintf(stderr, " read thread started: key_start %d nkeys %d\n",work->start_key,work->n_keys);
	
	for (uint i=0;i<work->n_reads;i++) {
	
		cl_rv rv;
		uint key_int = (rand_64() % work->n_keys) + work->start_key;
		key_value *kv = make_key_value(key_int, work->key_len, work->value_len);

		// Create the key we want to read
		cl_object o_key;
		if (g_config.key_type == CL_STR) {
			citrusleaf_object_init_str(&o_key,kv->key_str);
		}
		else if (g_config.key_type == CL_INT) {
			citrusleaf_object_init_int(&o_key,kv->key_int);
		}
		else {
			if (!g_config.silent) fprintf(stderr, " read thread: unsupport key type %d\n",g_config.key_type);
		}
	
		// bundle it into a value array
		cl_bin values[1];
		memset(values, 0, sizeof(values));
		strcpy(values[0].bin_name, g_config.bin);
	
#ifdef PRINT_KEY
		cf_digest d;
		citrusleaf_calculate_digest(g_config.table, &o_key, &d);
		fprintf(stderr, "get: key %d digest %"PRIx64"\n",key_int, *(uint64_t *)&d);
#endif
		
		
		if (g_config.server_validate) {
	
			if (g_config.value_type == CL_STR) {
				citrusleaf_object_init_str(&values[0].object, kv->value_str);
			}
			else if (g_config.value_type == CL_BLOB) {
				citrusleaf_object_init_blob(&values[0].object, kv->value_blob, kv->value_blob_len);
			}
			else if (g_config.value_type == CL_INT) {
				citrusleaf_object_init_int(&values[0].object, kv->value_int);
			}
			else {
				if (!g_config.silent) fprintf(stderr, "INTERNAL ERROR: unexpected value type under verify, help!\n");
			}
			if (CITRUSLEAF_OK != (rv = citrusleaf_verify(work->asc, g_config.ns, g_config.table, &o_key,values, 1, g_config.timeout, NULL) ) ) 
			{
				if (!g_config.silent) fprintf(stderr, "read: validate: key %d value %"PRIu64" failed with %d\n",key_int,kv->value_int, rv);
				citrusleaf_object_free(&values[0].object);
				if (g_config.continuous == false) {
					free(kv);
					return((void *)-1);
				}
				goto NextRead;
			}
		}

		else {
			// do the actual work of reading
			uint64_t start_time = cf_getms();
			if (CITRUSLEAF_OK != (rv = citrusleaf_get(work->asc, g_config.ns, g_config.table, &o_key, values, 1, g_config.timeout, 0))) {
	            uint64_t stop_time = cf_getms();
	            uint64_t diff = safe_delta_ms(start_time, stop_time);

	        	if (rv == CITRUSLEAF_FAIL_TIMEOUT || rv == CITRUSLEAF_FAIL_SERVERSIDE_TIMEOUT) {
	                histogram_insert_data_point(g_p_read_timeout_histogram, diff);

	                if (!g_config.silent) {
                        fprintf(stderr, "citrusleaf get timeout %d %"PRIu64" %d\n",rv,diff,g_config.timeout);
	                }
	        	}
	        	else {
	                if (!g_config.silent) {
	                	fprintf(stderr, "read: failed with error %d\n",rv);
	                }
	        	}
				citrusleaf_object_free(&values[0].object);
				if (g_config.continuous == false) {
					free(kv);
					return((void *)-1);
				}
				goto NextRead;
			}
			uint64_t stop_time = cf_getms();
 			histogram_insert_data_point(g_p_read_histogram,
			safe_delta_ms(start_time, stop_time));
		}
		
		// validate
		
		
		if (values[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) values[0].object.type);
			if (g_config.continuous == false) {
				citrusleaf_object_free(&values[0].object);
				free(kv);
				return((void *)-1);
			}
			raise(SIGINT);
			goto NextRead;
		}
		
		if (g_config.value_type == CL_STR) {
			if (values[0].object.u.str == 0) {
				if (!g_config.silent) fprintf(stderr, "read value pointer is null. Yuck.\n");
				citrusleaf_object_free(&values[0].object);
				if (g_config.continuous == false) {
					free(kv);
					return((void *)-1);
				}
				goto NextRead;
			}
						
			if (values[0].object.sz  != strlen(kv->value_str)) {
				if (!g_config.silent) fprintf(stderr, "read value size doesn't match expected. Is %zd expecting %zd\n",
					values[0].object.sz,strlen(kv->value_str)+1);
				citrusleaf_object_free(&values[0].object);
				if (g_config.continuous == false) {
					free(kv);					
					return((void *)-1);
				}
				goto NextRead;
			}			
			
			if (strcmp(values[0].object.u.str, kv->value_str) != 0) {
				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",values[0].object.u.str);
				}
				citrusleaf_object_free(&values[0].object);

				if (g_config.continuous == false) {
					free(kv);
					return((void *)-1);
				}
				goto NextRead;
			}
		}
		else if (g_config.value_type == CL_BLOB) {
			if (values[0].object.u.blob == 0) {
				if (!g_config.silent) fprintf(stderr, "read value pointer is null. Yuck.\n");
				citrusleaf_object_free(&values[0].object);
				if (g_config.continuous == false) {
					free(kv);
					return((void *)-1);
				}
				goto NextRead;
			}
			
			if (values[0].object.sz  != kv->value_blob_len) {
				if (!g_config.silent) fprintf(stderr, "read value size doesn't match expected. Is %zd expecting %d\n",
					values[0].object.sz,kv->value_blob_len);
				citrusleaf_object_free(&values[0].object);

				if (g_config.continuous == false) {
					free(kv);					
					return((void *)-1);
				}
				goto NextRead;
			}			
			
			if (memcmp(values[0].object.u.blob, kv->value_blob, kv->value_blob_len) != 0) {
				if (!g_config.silent) {
					int k;
					uint8_t *b1 = (uint8_t *) values[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(&values[0].object);

				if (g_config.continuous == false) {
					free(kv);
					return((void *)-1);
				}
				goto NextRead;
			}

			
		}
		else if (g_config.value_type == CL_INT) {
			
			if (values[0].object.u.i64 != kv->value_int) {
				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",values[0].object.u.i64);
				}
				citrusleaf_object_free(&values[0].object);
				if (g_config.continuous == false) {
					free(kv);
					return((void *)-1);
				}
				goto NextRead;

			}			
			
		}

		// have to hand back any possible malloced memory
		citrusleaf_object_free(&values[0].object);
NextRead:
		free(kv);
		
		atomic_int_add(work->completed, 1);
		
		if (g_config.delay) {
			if (g_config.delay >= 1000) {
				usleep( (g_config.delay - 1000) * 1000 );
			}
			else {
				if ( (delay_factor++ % (1000 - g_config.delay)) == 0) {
					usleep( 1000 );
				}
			}
		}
		
	}
	return((void *)0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
leaq 0x189a8(%rip), %r13     # 0x1c330
movq %rdi, %r14
cmpb $0x1, 0x28(%r13)
je 0x4049
xorl %eax, %eax
cmpl $0x0, (%r14)
je 0x4037
leaq 0x50(%rsp), %rbx
xorl %ebp, %ebp
movq $0x0, 0x28(%rsp)
movq %r14, 0x8(%rsp)
xorl %eax, %eax
callq 0x31de
movl 0x8(%r14), %ecx
xorl %edx, %edx
movl 0xc(%r14), %esi
divq %rcx
movq %rdx, %r15
movl 0x10(%r14), %edx
addl 0x4(%r14), %r15d
movl %r15d, %edi
callq 0x4056
movl 0x4c(%r13), %edx
movq %rax, 0x10(%rsp)
cmpl $0x1, %edx
je 0x3a01
cmpl $0x3, %edx
jne 0x3a10
movq 0x8(%rax), %rsi
leaq 0x78(%rsp), %rdi
callq 0x5dcd
jmp 0x3a1b
movq (%rax), %rsi
leaq 0x78(%rsp), %rdi
callq 0x5e14
jmp 0x3a1b
cmpb $0x0, 0x29(%r13)
je 0x3e77
movq 0x20(%r13), %rsi
leaq 0x30(%rsp), %r12
xorps %xmm0, %xmm0
movq %r12, %rdi
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
callq 0x2210
cmpb $0x1, 0x2c(%r13)
jne 0x3a85
movl 0x48(%r13), %eax
cmpl $0x1, %eax
je 0x3bfc
movq 0x8(%rsp), %r14
movq 0x10(%rsp), %r12
cmpl $0x4, %eax
je 0x3be8
cmpl $0x3, %eax
jne 0x3c15
movq 0x10(%r12), %rsi
movq %rbx, %rdi
callq 0x5dcd
jmp 0x3c20
leaq 0x18(%rsp), %r14
movl $0x1, %edi
movl %ebp, (%rsp)
movq %r14, %rsi
callq 0x2200
movabsq $0x431bde82d7b634db, %rbp # imm = 0x431BDE82D7B634DB
imulq $0x3e8, 0x18(%rsp), %rbx # imm = 0x3E8
movq 0x10(%r13), %rsi
leaq 0x78(%rsp), %rcx
movq %r12, %r8
movl $0x1, %r9d
movq %rbp, %rax
mulq 0x20(%rsp)
movq 0x8(%rsp), %rax
shrq $0x12, %rdx
movq 0x20(%rax), %rdi
movl 0x34(%r13), %eax
addq %rdx, %rbx
movq 0x18(%r13), %rdx
pushq $0x0
pushq %rax
callq 0x6df7
addq $0x10, %rsp
testl %eax, %eax
je 0x3b8d
movl $0x1, %edi
movq %r14, %rsi
movl %eax, %r12d
callq 0x2200
movq %rbp, %rax
movl $0x0, %r15d
mulq 0x20(%rsp)
imulq $0x3e8, 0x18(%rsp), %rax # imm = 0x3E8
shrq $0x12, %rdx
addq %rdx, %rax
subq %rbx, %rax
cmovaeq %rax, %r15
cmpl $0x9, %r12d
je 0x3b38
cmpl $-0x2, %r12d
jne 0x3d29
movq 0x18851(%rip), %rdi     # 0x1c390
movq %r15, %rsi
callq 0x5cc2
leaq 0x187e2(%rip), %r13     # 0x1c330
movq 0x8(%rsp), %r14
movl (%rsp), %ebp
leaq 0x50(%rsp), %rbx
cmpb $0x0, 0x29(%r13)
jne 0x3d48
movq 0x16473(%rip), %rax     # 0x19fe0
movl 0x34(%r13), %r8d
leaq 0xee4c(%rip), %rsi      # 0x129c4
movl %r12d, %edx
movq %r15, %rcx
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2390
jmp 0x3d48
movl $0x1, %edi
movq %r14, %rsi
callq 0x2200
movq %rbp, %rax
movq 0x187f4(%rip), %rdi     # 0x1c398
movl $0x0, %esi
mulq 0x20(%rsp)
imulq $0x3e8, 0x18(%rsp), %rax # imm = 0x3E8
shrq $0x12, %rdx
addq %rdx, %rax
subq %rbx, %rax
cmovaeq %rax, %rsi
callq 0x5cc2
leaq 0x1875f(%rip), %r13     # 0x1c330
movq 0x8(%rsp), %r14
movl (%rsp), %ebp
movq 0x10(%rsp), %r12
leaq 0x50(%rsp), %rbx
jmp 0x3c73
movq 0x20(%r12), %rsi
movslq 0x18(%r12), %rdx
movq %rbx, %rdi
callq 0x5e2f
jmp 0x3c20
movq 0x10(%rsp), %r12
movq %rbx, %rdi
movq 0x28(%r12), %rsi
callq 0x5e14
movq 0x8(%rsp), %r14
jmp 0x3c20
cmpb $0x0, 0x29(%r13)
je 0x3f78
movl 0x34(%r13), %eax
movq 0x20(%r14), %rdi
movq 0x10(%r13), %rsi
movq 0x18(%r13), %rdx
leaq 0x78(%rsp), %rcx
leaq 0x30(%rsp), %r8
movl $0x1, %r9d
pushq $0x0
pushq %rax
callq 0x7e0a
addq $0x10, %rsp
testl %eax, %eax
je 0x3c73
cmpb $0x0, 0x29(%r13)
je 0x3e94
movq %rbx, %rdi
callq 0x5e7d
cmpb $0x0, 0x2b(%r13)
jne 0x3de3
jmp 0x4028
movl 0x50(%rsp), %ecx
movl 0x48(%r13), %edx
cmpl %edx, %ecx
jne 0x3d04
cmpl $0x1, %ecx
je 0x3dc8
cmpl $0x4, %ecx
je 0x3d65
cmpl $0x3, %ecx
jne 0x3dd4
movq 0x60(%rsp), %r13
testq %r13, %r13
je 0x3ed8
movq 0x10(%r12), %rdi
movq 0x58(%rsp), %r15
movq %rdi, (%rsp)
callq 0x20d0
cmpq %rax, %r15
jne 0x3f23
movq (%rsp), %rsi
movq %r13, %rdi
callq 0x2360
testl %eax, %eax
je 0x3dd4
leaq 0x1864d(%rip), %r13     # 0x1c330
cmpb $0x0, 0x29(%r13)
jne 0x3c5b
movq %r12, %rdi
leaq 0x60(%rsp), %rsi
addq $0x10, %rdi
callq 0x2abd
jmp 0x3c5b
cmpb $0x0, 0x29(%r13)
je 0x3f5b
cmpb $0x0, 0x2b(%r13)
je 0x4020
movl $0x2, %edi
callq 0x2230
jmp 0x3de3
leaq 0x18600(%rip), %r13     # 0x1c330
movq 0x8(%rsp), %r14
movl (%rsp), %ebp
leaq 0x50(%rsp), %rbx
cmpb $0x0, 0x29(%r13)
je 0x3f82
movq %rbx, %rdi
callq 0x5e7d
cmpb $0x0, 0x2b(%r13)
movq 0x10(%rsp), %r12
jne 0x3de3
jmp 0x4028
movq 0x60(%rsp), %r13
testq %r13, %r13
je 0x3ebc
movslq 0x18(%r12), %rax
movq 0x58(%rsp), %rdx
movl %eax, %ecx
cmpq %rax, %rdx
jne 0x3ef4
movq 0x20(%r12), %rsi
movq %r13, %rdi
movq %rcx, 0x70(%rsp)
movq %rsi, (%rsp)
callq 0x2240
testl %eax, %eax
je 0x3dd4
leaq 0x18587(%rip), %r12     # 0x1c330
cmpb $0x0, 0x29(%r12)
je 0x3fa2
movq %rbx, %rdi
callq 0x5e7d
cmpb $0x0, 0x2b(%r12)
movq %r12, %r13
jmp 0x3d55
movq 0x60(%rsp), %rax
cmpq 0x28(%r12), %rax
jne 0x3e4f
movq %rbx, %rdi
callq 0x5e7d
leaq 0x1854d(%rip), %r13     # 0x1c330
movq %r12, %rdi
callq 0x22a0
movq 0x18(%r14), %rdi
movl $0x1, %esi
callq 0x304d
movl 0x54(%r13), %edx
testl %edx, %edx
je 0x3e3f
cmpl $0x3e8, %edx            # imm = 0x3E8
jb 0x3e17
imull $0x3e8, %edx, %edi      # imm = 0x3E8
addl $0xfff0bdc0, %edi       # imm = 0xFFF0BDC0
jmp 0x3e3a
movq 0x28(%rsp), %rax
movl $0x3e8, %esi            # imm = 0x3E8
movl $0x3e8, %edi            # imm = 0x3E8
subl %edx, %esi
xorl %edx, %edx
leal 0x1(%rax), %ecx
divl %esi
testl %edx, %edx
movl %ecx, %eax
movq %rax, 0x28(%rsp)
jne 0x3e3f
callq 0x2370
incl %ebp
cmpl (%r14), %ebp
jb 0x39b7
jmp 0x401c
leaq 0x184da(%rip), %r13     # 0x1c330
cmpb $0x0, 0x29(%r13)
jne 0x3c5b
movq %r12, %rdi
leaq 0x60(%rsp), %rsi
addq $0x28, %rdi
callq 0x2a46
jmp 0x3c5b
movq 0x16162(%rip), %rax     # 0x19fe0
leaq 0xeaae(%rip), %rsi      # 0x12933
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2390
jmp 0x3a1b
movq 0x16145(%rip), %rcx     # 0x19fe0
movl %eax, %r8d
leaq 0xeaee(%rip), %rsi      # 0x12993
movl %r15d, %edx
xorl %eax, %eax
movq (%rcx), %rdi
movq 0x28(%r12), %rcx
callq 0x2390
jmp 0x3c5b
leaq 0x1846d(%rip), %r13     # 0x1c330
cmpb $0x0, 0x29(%r13)
jne 0x3c5b
callq 0x2a9b
jmp 0x3c5b
leaq 0x18451(%rip), %r13     # 0x1c330
cmpb $0x0, 0x29(%r13)
jne 0x3c5b
callq 0x2b12
jmp 0x3c5b
leaq 0x18435(%rip), %r13     # 0x1c330
cmpb $0x0, 0x29(%r13)
jne 0x3c5b
movq 0x160d3(%rip), %rax     # 0x19fe0
leaq 0xebc4(%rip), %rsi      # 0x12ad8
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2390
jmp 0x3c5b
leaq 0x18406(%rip), %r13     # 0x1c330
cmpb $0x0, 0x29(%r13)
jne 0x3c5b
movq 0x160a4(%rip), %rcx     # 0x19fe0
incq %rax
leaq 0xeb0c(%rip), %rsi      # 0x12a52
movq %r15, %rdx
movq (%rcx), %rdi
movq %rax, %rcx
xorl %eax, %eax
callq 0x2390
jmp 0x3c5b
movq 0x1607e(%rip), %rax     # 0x19fe0
leaq 0xea99(%rip), %rsi      # 0x12a02
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2390
jmp 0x3d0f
callq 0x2a24
jmp 0x3c20
movq 0x16057(%rip), %rax     # 0x19fe0
leaq 0xea56(%rip), %rsi      # 0x129e6
movl %r12d, %edx
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2390
jmp 0x3d48
movq 0x70(%rsp), %rsi
movq 0x10(%rsp), %r12
xorl %ecx, %ecx
testl %esi, %esi
jle 0x3fcc
movq (%rsp), %rdx
xorl %ecx, %ecx
movb (%r13,%rcx), %al
cmpb (%rdx,%rcx), %al
jne 0x3fcc
incq %rcx
cmpq %rcx, %rsi
jne 0x3fb8
movl %esi, %ecx
movq 0x1600d(%rip), %rax     # 0x19fe0
leaq 0xeb3b(%rip), %rsi      # 0x12b15
movl %r15d, %edx
movq (%rax), %rdi
xorl %eax, %eax
callq 0x2390
movslq 0x18(%r12), %rdx
leaq 0xeb78(%rip), %rdi      # 0x12b6b
movq %r13, %rsi
callq 0x2953
movslq 0x18(%r12), %rdx
movq (%rsp), %rsi
leaq 0xeb6a(%rip), %rdi      # 0x12b75
callq 0x2953
leaq 0x18319(%rip), %r12     # 0x1c330
jmp 0x3db5
xorl %eax, %eax
jmp 0x4037
movq %rbx, %rdi
callq 0x5e7d
movq %r12, %rdi
callq 0x22a0
movq $-0x1, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
callq 0x2a03
jmp 0x3996