void test_set_and_get() { constexpr size_t NUM_ROWS = 1 << 16; // Create a table and insert the first row. auto db = grnxx::open_db(""); auto table = db->create_table("Table"); auto column = table->create_column("Column", T::type()); grnxx::Array<T> values; values.resize(NUM_ROWS); for (size_t i = 0; i < NUM_ROWS; ++i) { generate_random_value(&values[i]); grnxx::Int row_id = table->insert_row(); column->set(row_id, values[i]); grnxx::Datum datum; column->get(row_id, &datum); T stored_value; datum.force(&stored_value); assert(stored_value.match(values[i])); } // Test all the values again. for (size_t i = 0; i < NUM_ROWS; ++i) { grnxx::Int row_id = grnxx::Int(i); grnxx::Datum datum; column->get(row_id, &datum); T stored_value; datum.force(&stored_value); assert(stored_value.match(values[i])); } }
// Invoked when a value is delivered void on_deliver(void* cmd_value, size_t cmd_size, void * arg) { client * cl = arg; cl->current_inst_number += 1; client_proposal * c; unsigned i; //Check if the delivered values was sent from this process. for(i = 0; i < CONCURRENT_VALUES; i++) { c = &cl->pending_values[i]; submit_cmd_msg * msg = c->submit_msg; //If so, submit another one if(cmd_size == msg->cmd_size && memcmp(msg->cmd_value, cmd_value, cmd_size) == 0) { // printf("CMD %u accepted in instance %lu\n", i, current_inst_number); cl->deliver_count += 1; cl->deliver_bytes += cmd_size; gettimeofday(&cl->current_time, NULL); save_latency(cl, &c->submit_time, &cl->current_time); generate_random_value(c->submit_msg); submit_value(cl->us, c->submit_msg); save_submit_time(c, &cl->current_time); timer_set_timeout(&cl->current_time, &c->timeout, &cl->value_timeout_interval); break; } } }
std::string generate_random_node(int deep = 2) { std::string str; str += "{"; do { // Generate key str += generate_random_value(); str += ":"; // Generate value str += dis(gen) % deep == 0 ? generate_random_node(deep + 1) : generate_random_value(); str += ","; } while (dis(gen) % 3 == 0); str.pop_back(); str += "}"; return str; }
void generate_random_value(grnxx::Vector<T> *value) { static grnxx::Array<grnxx::Array<T>> bodies; if ((rng() % 256) == 0) { *value = grnxx::Vector<T>::na(); } else { grnxx::Array<T> body; body.resize(rng() % 16); for (size_t i = 0; i < body.size(); ++i) { generate_random_value(&body[i]); } *value = grnxx::Vector<T>(body.data(), body.size()); bodies.push_back(std::move(body)); } }
//Custom init for the learner void client_pl_init(void * arg) { client * cl = arg; printf("FastClient: submitting %d values of size [%lu...%lu]\n", CONCURRENT_VALUES, MIN_VAL_SIZE, MAX_VAL_SIZE); //Use an udp sender instead of a submit_proxy cl->us = udp_sender_init( lptopo_get_leader_addr(learner_get_topolo_mngr(cl->l)), lptopo_get_leader_clients_port(learner_get_topolo_mngr(cl->l)), learner_get_config_mngr(cl->l)); // No autoflush, it's manual for this client assert(cl->us != NULL); udp_sender_enable_autoflush(cl->us, 25); //Periodically check for timeouts cl->periodic_check = set_periodic_event( &cl->value_timeout_interval, /*Interval for this event*/ values_timeout_check, /*Called periodically*/ cl /*Argument passed to above function*/ ); //Periodically print statistics cl->periodic_stats = set_periodic_event( &cl->print_stats_interval, /*Interval for this event*/ print_stats, /*Called periodically*/ cl /*Argument passed to above function*/ ); printf("Client initialization completed\n"); cl->start_time = time(NULL); gettimeofday(&cl->current_time, NULL); //Submit the initial amount of values client_proposal * c; unsigned i; for(i = 0; i < CONCURRENT_VALUES; i++) { c = &cl->pending_values[i]; // c->submit_msg = malloc(sizeof(submit_cmd_msg) + MAX_VAL_SIZE); c->submit_msg = (submit_cmd_msg*) &cl->values_buffer[i * (MAX_VAL_SIZE + sizeof(submit_cmd_msg))]; generate_random_value(c->submit_msg); submit_value(cl->us, c->submit_msg); save_submit_time(c, &cl->current_time); timer_set_timeout(&cl->current_time, &c->timeout, &cl->value_timeout_interval); } }
void test_contains_and_find_one() { constexpr size_t NUM_ROWS = 1 << 10; // Create a table and insert the first row. auto db = grnxx::open_db(""); auto table = db->create_table("Table"); auto column = table->create_column("Column", T::type()); grnxx::Array<T> values; values.resize(NUM_ROWS); for (size_t i = 0; i < NUM_ROWS; ++i) { generate_random_value(&values[i]); grnxx::Int row_id = table->insert_row(); column->set(row_id, values[i]); } // Test all the values. for (size_t i = 0; i < NUM_ROWS; ++i) { assert(column->contains(values[i])); grnxx::Int row_id = column->find_one(values[i]); assert(!row_id.is_na()); assert(values[i].match(values[row_id.raw()])); } // Test all the values with index if available. try { column->create_index("Index", GRNXX_TREE_INDEX); for (size_t i = 0; i < NUM_ROWS; ++i) { assert(column->contains(values[i])); grnxx::Int row_id = column->find_one(values[i]); assert(!row_id.is_na()); assert(values[i].match(values[row_id.raw()])); } column->remove_index("Index"); } catch (...) { } // Remove N/A values. for (size_t i = 0; i < NUM_ROWS; ++i) { if (values[i].is_na()) { table->remove_row(grnxx::Int(i)); } } // Test all the values. for (size_t i = 0; i < NUM_ROWS; ++i) { if (!values[i].is_na()) { assert(column->contains(values[i])); grnxx::Int row_id = column->find_one(values[i]); assert(!row_id.is_na()); assert(values[i].match(values[row_id.raw()])); } } assert(!column->contains(T::na())); assert(column->find_one(T::na()).is_na()); // Test all the values with index if available. try { column->create_index("Index", GRNXX_TREE_INDEX); for (size_t i = 0; i < NUM_ROWS; ++i) { if (!values[i].is_na()) { assert(column->contains(values[i])); grnxx::Int row_id = column->find_one(values[i]); assert(!row_id.is_na()); assert(values[i].match(values[row_id.raw()])); } } assert(!column->contains(T::na())); assert(column->find_one(T::na()).is_na()); column->remove_index("Index"); } catch (...) { } // Insert a trailing N/A value. table->insert_row_at(grnxx::Int(NUM_ROWS)); assert(column->contains(T::na())); assert(column->find_one(T::na()).match(grnxx::Int(NUM_ROWS))); try { column->create_index("Index", GRNXX_TREE_INDEX); assert(column->contains(T::na())); assert(column->find_one(T::na()).match(grnxx::Int(NUM_ROWS))); column->remove_index("Index"); } catch (...) { } // Remove non-N/A values. for (size_t i = 0; i < NUM_ROWS; ++i) { if (!values[i].is_na()) { table->remove_row(grnxx::Int(i)); } } // Test all the values. for (size_t i = 0; i < NUM_ROWS; ++i) { if (!values[i].is_na()) { assert(!column->contains(values[i])); assert(column->find_one(values[i]).is_na()); } } assert(column->contains(T::na())); assert(column->find_one(T::na()).match(grnxx::Int(NUM_ROWS))); // Test all the values with index if available. try { column->create_index("Index", GRNXX_TREE_INDEX); for (size_t i = 0; i < NUM_ROWS; ++i) { if (!values[i].is_na()) { assert(!column->contains(values[i])); assert(column->find_one(values[i]).is_na()); } } assert(column->contains(T::na())); assert(column->find_one(T::na()).match(grnxx::Int(NUM_ROWS))); column->remove_index("Index"); } catch (...) { } }