static char *i_cid_pid() { if(db_vars_get(0, "cid") && db_vars_get(0, "pid")) return NULL; guint64 r = rand_64(); struct tiger_ctx t; char pid[24]; tiger_init(&t); tiger_update(&t, (char *)&r, 8); tiger_final(&t, pid); // now hash the PID so we have our CID char cid[24]; tiger_init(&t); tiger_update(&t, pid, 24); tiger_final(&t, cid); // encode and save char enc[40] = {}; base32_encode(pid, enc); db_vars_set(0, "pid", enc); base32_encode(cid, enc); db_vars_set(0, "cid", enc); return NULL; }
//------------------------------------------------ // Get a random large block offset for a device. // static uint64_t random_large_block_offset(device* p_device) { if (! p_device->num_large_blocks) { return 0; } return (rand_64() % p_device->num_large_blocks) * g_large_block_ops_bytes; }
int write_new_value(uint32_t key, cl_object *key_o, cf_digest *d) { uint64_t new_value_int; do { new_value_int = rand_64(); } while (new_value_int == VALUE_UNINIT || new_value_int == VALUE_DELETED); g_config.values[key] = new_value_int; char new_value_str[g_config.value_len+1]; my_itoa(new_value_str, new_value_int, g_config.value_len); cl_bin values[1]; strcpy(values[0].bin_name, g_config.bin); citrusleaf_object_init_str(&values[0].object, new_value_str); cl_write_parameters cl_w_p; cl_write_parameters_set_default(&cl_w_p); cl_w_p.timeout_ms = g_config.timeout_ms; int rv; rv = citrusleaf_put(g_config.asc, g_config.ns, g_config.set, key_o, values, 1, &cl_w_p); if (rv != 0) { fprintf(stderr, "aerospike put returned error %d, fail digest %"PRIx64"\n",rv, *(uint64_t *)d); if (g_config.strict) return(-1); } citrusleaf_object_init(&values[0].object); rv = citrusleaf_verify(g_config.asc, g_config.ns, g_config.set, key_o, values, 1, g_config.timeout_ms, NULL); if (rv != 0) { fprintf(stderr, "aerospike get returned error %d digest %"PRIx64"\n",rv, *(uint64_t *)d); if (g_config.strict) return(-1); } // test! if (values[0].object.type != CL_STR) { fprintf(stderr, "read value has wrong type: expect string (3) got %d, fail digest %"PRIx64"\n",(int)values[0].object.type, *(uint64_t *)d); if (g_config.strict) return(-1); } if (strcmp(values[0].object.u.str, new_value_str) != 0) { fprintf(stderr, "read value does not match set value. digest %"PRIx64"\n", *(uint64_t *)d); fprintf(stderr, " expecting: %s\n",new_value_str); fprintf(stderr, " got: %s\n",values[0].object.u.str); if (g_config.strict) return( -1); } citrusleaf_object_free(&values[0].object); atomic_int_add(g_config.read_counter, 1); atomic_int_add(g_config.write_counter, 1); return(0); }
//------------------------------------------------ // Get a random read offset for a device. // static uint64_t random_read_offset(device* p_device) { if (! p_device->num_512_blocks) { return 0; } uint64_t num_read_offsets = p_device->num_512_blocks - (uint64_t)g_read_req_num_512_blocks + 1; return (rand_64() % num_read_offsets) * MIN_BLOCK_BYTES; }
//------------------------------------------------ // Get a random uint32_t. // static inline uint32_t rand_32() { return (uint32_t)rand_64(); }
void * work_fn(void *gcc_is_ass) { // Forever, do { // Pick a key to use. Look it up to see if anyone else is using it. uint32_t key = rand_64() % g_config.n_keys; uint32_t die = rand_64() & 0x03; if (SHASH_OK == shash_put_unique(g_config.in_progress_hash, &key, 0) ) { cl_rv rv; // Make the key into a string char key_s[g_config.key_len+1]; my_itoa(key_s, key, g_config.key_len); // Make an cl_object that represents the key cl_object key_o; citrusleaf_object_init_str(&key_o, key_s); cf_digest d; citrusleaf_calculate_digest(g_config.set, &key_o, &d); if (VALUE_UNINIT == g_config.values[key]) { // simply set the value to something - can't really check anything because we don't know the state if (0 != write_new_value(key, &key_o, &d)) { if (g_config.strict) goto Fail; } atomic_int_add(g_config.key_counter, 1); } else if (VALUE_DELETED == g_config.values[key]) { // Shouldn't exist cl_bin *cl_v = 0; int cl_v_len; rv = citrusleaf_get_all(g_config.asc, g_config.ns, g_config.set, &key_o, &cl_v, &cl_v_len, g_config.timeout_ms, NULL); if (rv != CITRUSLEAF_FAIL_NOTFOUND) { fprintf(stderr, "Get after delete returned improper value when should be deleted %d key %s digest %"PRIx64"\n",rv,key_s, *(uint64_t *)&d); if (g_config.strict) goto Fail; } if (cl_v) free(cl_v); atomic_int_add(g_config.read_counter, 1); // did two ops here // write a new value if (die < 2) { if (0 != write_new_value(key, &key_o, &d)) { if (g_config.strict) goto Fail; } atomic_int_add(g_config.key_counter, 1); } } // Value is well known. Check to see that it's still right. else { cl_bin values[1]; strcpy(values[0].bin_name, g_config.bin); citrusleaf_object_init(&values[0].object); // Make string version of old value for checking char new_value_str[g_config.value_len+1]; my_itoa(new_value_str, g_config.values[key], g_config.value_len); citrusleaf_object_init_str(&values[0].object, new_value_str); rv = citrusleaf_verify(g_config.asc, g_config.ns, g_config.set, &key_o, values, 1, g_config.timeout_ms, NULL); if (rv != 0) { fprintf(stderr, "Get returned improper value %d when should be set : key %d digest %"PRIx64"\n",rv,key, *(uint64_t *)&d); if (g_config.strict) goto Fail; goto V1; } // test! if (values[0].object.type != CL_STR) { fprintf(stderr, "read value has wrong type: expect string (3) got %d\n",(int)values[0].object.type); if (g_config.strict) return((void *)-1); } else if (strcmp(values[0].object.u.str, new_value_str) != 0) { fprintf(stderr, "read value does not match set value.\n"); fprintf(stderr, " expecting: %s\n",new_value_str); fprintf(stderr, " got: %s\n",values[0].object.u.str); if (g_config.strict) goto Fail; } citrusleaf_object_free(&values[0].object); atomic_int_add(g_config.read_counter, 1); // Delete, write new value, what's your pleasure? V1: if (die < 2) { if (0 != write_new_value(key, &key_o, &d)) { if (g_config.strict) return((void *)-1); } } // Delete! else if (die == 2) { rv = citrusleaf_delete_verify(g_config.asc, g_config.ns, g_config.set, &key_o, 0); if (rv != 0) { fprintf(stderr, "Delete returned improper value %d, fail: key %d digest %"PRIx64"\n",rv, key, *(uint64_t *)&d); if (g_config.strict) goto Fail; } cl_bin values[1]; strcpy(values[0].bin_name, g_config.bin); citrusleaf_object_init(&values[0].object); rv = citrusleaf_get(g_config.asc, g_config.ns, g_config.set, &key_o, values, 1, g_config.timeout_ms, NULL); if (rv != CITRUSLEAF_FAIL_NOTFOUND) { fprintf(stderr, "Get after delete returned improper value %d digest %"PRIx64"\n",rv, *(uint64_t *)&d); if (g_config.strict) goto Fail; } citrusleaf_object_free(&values[0].object); g_config.values[key] = VALUE_DELETED; atomic_int_add(g_config.read_counter, 1); // did two ops here atomic_int_add(g_config.delete_counter, 1); atomic_int_add(g_config.key_counter, -1); } } // remove my lock on this key shash_delete(g_config.in_progress_hash, &key); } } while (1); Fail: abort(); return((void *)-1); }
static inline uint64_t random_write_offset(const device* dev) { return (rand_64() % dev->n_write_offsets) * dev->min_commit_bytes; }
static inline uint64_t random_read_offset(const device* dev) { return (rand_64() % dev->n_read_offsets) * dev->min_op_bytes; }
static inline uint64_t random_large_block_offset(const device* dev) { return (rand_64() % dev->n_large_blocks) * g_scfg.large_block_ops_bytes; }