BaseQuery * TPCCQueryGenerator::gen_new_order(uint64_t home_partition) { TPCCQuery * query = new TPCCQuery; set<uint64_t> partitions_accessed; query->txn_type = TPCC_NEW_ORDER; query->items.init(g_max_items_per_txn); if (FIRST_PART_LOCAL) { while(wh_to_part(query->w_id = URand(1, g_num_wh)) != home_partition) {} } else query->w_id = URand(1, g_num_wh); query->d_id = URand(1, g_dist_per_wh); query->c_id = NURand(1023, 1, g_cust_per_dist); // FIXME: No rollback //rbk = URand(1, 100) == 1 ? true : false; query->rbk = false; query->ol_cnt = URand(5, g_max_items_per_txn); query->o_entry_d = 2013; partitions_accessed.insert(wh_to_part(query->w_id)); double r_mpr = (double)(rand() % 10000) / 10000; uint64_t part_limit; if(r_mpr < g_mpr) part_limit = g_part_per_txn; else part_limit = 1; std::set<uint64_t> ol_i_ids; while(query->items.size() < query->ol_cnt) { Item_no * item = new Item_no; while(ol_i_ids.count( item->ol_i_id = NURand(8191, 1, g_max_items)) > 0) {} ol_i_ids.insert(item->ol_i_id); item->ol_quantity = URand(1, 10); double r_rem = (double)(rand() % 100000) / 100000; if (r_rem > 0.01 || r_mpr > g_mpr || g_num_wh == 1) { // home warehouse item->ol_supply_w_id = query->w_id; } else { if(partitions_accessed.size() < part_limit) { item->ol_supply_w_id = URand(1, g_num_wh); partitions_accessed.insert(wh_to_part(item->ol_supply_w_id)); } else { // select warehouse from among those already selected while( partitions_accessed.count(wh_to_part(item->ol_supply_w_id = URand(1, g_num_wh))) == 0) {} } } query->items.add(item); } query->partitions.init(partitions_accessed.size()); for(auto it = partitions_accessed.begin(); it != partitions_accessed.end(); ++it) { query->partitions.add(*it); } return query; }
RC TPCCTxnManager::run_tpcc_phase2() { TPCCQuery* tpcc_query = (TPCCQuery*) query; RC rc = RCOK; assert(CC_ALG == CALVIN); uint64_t w_id = tpcc_query->w_id; uint64_t d_id = tpcc_query->d_id; uint64_t c_id = tpcc_query->c_id; //uint64_t d_w_id = tpcc_query->d_w_id; //uint64_t c_w_id = tpcc_query->c_w_id; //uint64_t c_d_id = tpcc_query->c_d_id; //char * c_last = tpcc_query->c_last; //double h_amount = tpcc_query->h_amount; //bool by_last_name = tpcc_query->by_last_name; bool remote = tpcc_query->remote; uint64_t ol_cnt = tpcc_query->ol_cnt; uint64_t o_entry_d = tpcc_query->o_entry_d; //uint64_t o_id = tpcc_query->o_id; uint64_t part_id_w = wh_to_part(w_id); //uint64_t part_id_c_w = wh_to_part(c_w_id); bool w_loc = GET_NODE_ID(part_id_w) == g_node_id; //bool c_w_loc = GET_NODE_ID(part_id_c_w) == g_node_id; switch (tpcc_query->txn_type) { case TPCC_PAYMENT : break; case TPCC_NEW_ORDER : if(w_loc) { rc = new_order_0( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); rc = new_order_1( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); rc = new_order_2( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); rc = new_order_3( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); rc = new_order_4( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); tpcc_query->o_id = *(int64_t *) row->get_value(D_NEXT_O_ID); //rc = new_order_5( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); } for(uint64_t i = 0; i < tpcc_query->ol_cnt; i++) { uint64_t ol_number = i; uint64_t ol_i_id = tpcc_query->items[ol_number]->ol_i_id; uint64_t ol_supply_w_id = tpcc_query->items[ol_number]->ol_supply_w_id; //uint64_t ol_quantity = tpcc_query->items[ol_number].ol_quantity; //uint64_t ol_amount = tpcc_query->ol_amount; uint64_t part_id_ol_supply_w = wh_to_part(ol_supply_w_id); bool ol_supply_w_loc = GET_NODE_ID(part_id_ol_supply_w) == g_node_id; if(ol_supply_w_loc) { rc = new_order_6(ol_i_id, row); rc = new_order_7(ol_i_id, row); } } break; default: assert(false); } return rc; }
BaseQuery * TPCCQueryGenerator::gen_payment(uint64_t home_partition) { TPCCQuery * query = new TPCCQuery; set<uint64_t> partitions_accessed; query->txn_type = TPCC_PAYMENT; uint64_t home_warehouse; if (FIRST_PART_LOCAL) { while(wh_to_part(home_warehouse = URand(1, g_num_wh)) != home_partition) {} } else home_warehouse = URand(1, g_num_wh); query->w_id = home_warehouse; query->d_w_id = home_warehouse; partitions_accessed.insert(wh_to_part(query->w_id)); query->d_id = URand(1, g_dist_per_wh); query->h_amount = URand(1, 5000); query->rbk = false; double x = (double)(rand() % 10000) / 10000; int y = URand(1, 100); //if(x > g_mpr) { if(x > 0.15) { // home warehouse query->c_d_id = query->d_id; query->c_w_id = query->w_id; } else { // remote warehouse query->c_d_id = URand(1, g_dist_per_wh); if(g_num_wh > 1) { while((query->c_w_id = URand(1, g_num_wh)) == query->w_id) {} if (wh_to_part(query->w_id) != wh_to_part(query->c_w_id)) { partitions_accessed.insert(wh_to_part(query->c_w_id)); } } else query->c_w_id = query->w_id; } if(y <= 60) { // by last name query->by_last_name = true; Lastname(NURand(255,0,999),query->c_last); } else { // by cust id query->by_last_name = false; query->c_id = NURand(1023, 1, g_cust_per_dist); } query->partitions.init(partitions_accessed.size()); for(auto it = partitions_accessed.begin(); it != partitions_accessed.end(); ++it) { query->partitions.add(*it); } return query; }
void tpcc_query::gen_new_order(uint64_t thd_id) { type = TPCC_NEW_ORDER; if (FIRST_PART_LOCAL) w_id = thd_id % g_num_wh + 1; else w_id = URand(1, g_num_wh); d_id = URand(1, DIST_PER_WARE); c_id = NURand(1023, 1, g_cust_per_dist); rbk = URand(1, 100); ol_cnt = URand(5, 15); o_entry_d = 2013; items = (Item_no *) mem_allocator.alloc(sizeof(Item_no) * ol_cnt, thd_id); remote = false; part_to_access[0] = wh_to_part(w_id); part_num = 1; for (UInt32 oid = 0; oid < ol_cnt; oid ++) { items[oid].ol_i_id = NURand(8191, 1, g_max_items); UInt32 x = URand(1, 100); if (x > 1 || g_num_wh == 1) items[oid].ol_supply_w_id = w_id; else { while((items[oid].ol_supply_w_id = URand(1, g_num_wh)) == w_id) {} remote = true; } items[oid].ol_quantity = URand(1, 10); } // Remove duplicate items for (UInt32 i = 0; i < ol_cnt; i ++) { for (UInt32 j = 0; j < i; j++) { if (items[i].ol_i_id == items[j].ol_i_id) { for (UInt32 k = i; k < ol_cnt - 1; k++) items[k] = items[k + 1]; ol_cnt --; i--; } } } for (UInt32 i = 0; i < ol_cnt; i ++) for (UInt32 j = 0; j < i; j++) assert(items[i].ol_i_id != items[j].ol_i_id); // update part_to_access for (UInt32 i = 0; i < ol_cnt; i ++) { UInt32 j; for (j = 0; j < part_num; j++ ) if (part_to_access[j] == wh_to_part(items[i].ol_supply_w_id)) break; if (j == part_num) // not found! add to it. part_to_access[part_num ++] = wh_to_part( items[i].ol_supply_w_id ); } }
uint64_t TPCCQuery::participants(bool *& pps,Workload * wl) { int n = 0; for(uint64_t i = 0; i < g_node_cnt; i++) pps[i] = false; uint64_t id; switch(txn_type) { case TPCC_PAYMENT: id = GET_NODE_ID(wh_to_part(w_id)); if(!pps[id]) { pps[id] = true; n++; } id = GET_NODE_ID(wh_to_part(c_w_id)); if(!pps[id]) { pps[id] = true; n++; } break; case TPCC_NEW_ORDER: id = GET_NODE_ID(wh_to_part(w_id)); if(!pps[id]) { pps[id] = true; n++; } /* id = GET_NODE_ID(wh_to_part(c_w_id)); if(!pps[id]) { pps[id] = true; n++; } id = GET_NODE_ID(wh_to_part(d_w_id)); if(!pps[id]) { pps[id] = true; n++; } */ for(uint64_t i = 0; i < ol_cnt; i++) { uint64_t req_nid = GET_NODE_ID(wh_to_part(items[i]->ol_supply_w_id)); if(!pps[req_nid]) { pps[req_nid] = true; n++; } } break; default: assert(false); } return n; }
inline RC TPCCTxnManager::run_payment_0(uint64_t w_id, uint64_t d_id, uint64_t d_w_id, double h_amount, row_t *& r_wh_local) { uint64_t key; itemid_t * item; /*====================================================+ EXEC SQL UPDATE warehouse SET w_ytd = w_ytd + :h_amount WHERE w_id=:w_id; +====================================================*/ /*===================================================================+ EXEC SQL SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name INTO :w_street_1, :w_street_2, :w_city, :w_state, :w_zip, :w_name FROM warehouse WHERE w_id=:w_id; +===================================================================*/ RC rc; key = w_id; INDEX * index = _wl->i_warehouse; item = index_read(index, key, wh_to_part(w_id)); assert(item != NULL); row_t * r_wh = ((row_t *)item->location); if (g_wh_update) rc = get_row(r_wh, WR, r_wh_local); else rc = get_row(r_wh, RD, r_wh_local); return rc; }
// new_order 2 inline RC TPCCTxnManager::new_order_8(uint64_t w_id,uint64_t d_id,bool remote, uint64_t ol_i_id, uint64_t ol_supply_w_id, uint64_t ol_quantity,uint64_t ol_number,uint64_t o_id, row_t *& r_stock_local) { uint64_t key; itemid_t * item; /*===================================================================+ EXEC SQL SELECT s_quantity, s_data, s_dist_01, s_dist_02, s_dist_03, s_dist_04, s_dist_05, s_dist_06, s_dist_07, s_dist_08, s_dist_09, s_dist_10 INTO :s_quantity, :s_data, :s_dist_01, :s_dist_02, :s_dist_03, :s_dist_04, :s_dist_05, :s_dist_06, :s_dist_07, :s_dist_08, :s_dist_09, :s_dist_10 FROM stock WHERE s_i_id = :ol_i_id AND s_w_id = :ol_supply_w_id; EXEC SQL UPDATE stock SET s_quantity = :s_quantity WHERE s_i_id = :ol_i_id AND s_w_id = :ol_supply_w_id; +===============================================*/ key = stockKey(ol_i_id, ol_supply_w_id); INDEX * index = _wl->i_stock; item = index_read(index, key, wh_to_part(ol_supply_w_id)); assert(item != NULL); row_t * r_stock = ((row_t *)item->location); RC rc = get_row(r_stock, WR, r_stock_local); return rc; }
void tpcc_wl::init_tab_dist(uint64_t wid) { for (uint64_t did = 1; did <= DIST_PER_WARE; did++) { row_t * row; uint64_t row_id; t_district->get_new_row(row, 0, row_id); row->set_primary_key(did); row->set_value(D_ID, did); row->set_value(D_W_ID, wid); char name[10]; MakeAlphaString(6, 10, name); row->set_value(D_NAME, name); char street[20]; MakeAlphaString(10, 20, street); row->set_value(D_STREET_1, street); MakeAlphaString(10, 20, street); row->set_value(D_STREET_2, street); MakeAlphaString(10, 20, street); row->set_value(D_CITY, street); char state[2]; MakeAlphaString(2, 2, state); /* State */ row->set_value(D_STATE, state); char zip[9]; MakeNumberString(9, 9, zip); /* Zip */ row->set_value(D_ZIP, zip); double tax = (double)URand(0L,200L)/1000.0; double w_ytd=30000.00; row->set_value(D_TAX, tax); row->set_value(D_YTD, w_ytd); row->set_value(D_NEXT_O_ID, 3001); index_insert(i_district, distKey(did, wid), row, wh_to_part(wid)); } }
void tpcc_wl::init_tab_wh(uint32_t wid) { assert(wid >= 1 && wid <= g_num_wh); row_t * row; uint64_t row_id; t_warehouse->get_new_row(row, 0, row_id); row->set_primary_key(wid); row->set_value(W_ID, wid); char name[10]; MakeAlphaString(6, 10, name, wid-1); row->set_value(W_NAME, name); char street[20]; MakeAlphaString(10, 20, street, wid-1); row->set_value(W_STREET_1, street); MakeAlphaString(10, 20, street, wid-1); row->set_value(W_STREET_2, street); MakeAlphaString(10, 20, street, wid-1); row->set_value(W_CITY, street); char state[2]; MakeAlphaString(2, 2, state, wid-1); /* State */ row->set_value(W_STATE, state); char zip[9]; MakeNumberString(9, 9, zip, wid-1); /* Zip */ row->set_value(W_ZIP, zip); double tax = (double)URand(0L,200L,wid-1)/1000.0; double w_ytd=300000.00; row->set_value(W_TAX, tax); row->set_value(W_YTD, w_ytd); index_insert(i_warehouse, wid, row, wh_to_part(wid)); return; }
inline RC TPCCTxnManager::new_order_9(uint64_t w_id,uint64_t d_id,bool remote, uint64_t ol_i_id, uint64_t ol_supply_w_id, uint64_t ol_quantity,uint64_t ol_number, uint64_t ol_amount, uint64_t o_id, row_t * r_stock_local) { assert(r_stock_local != NULL); // XXX s_dist_xx are not retrieved. UInt64 s_quantity; int64_t s_remote_cnt; s_quantity = *(int64_t *)r_stock_local->get_value(S_QUANTITY); #if !TPCC_SMALL int64_t s_ytd; int64_t s_order_cnt; char * s_data __attribute__ ((unused)); r_stock_local->get_value(S_YTD, s_ytd); r_stock_local->set_value(S_YTD, s_ytd + ol_quantity); // In Coordination Avoidance, this record must be protected! r_stock_local->get_value(S_ORDER_CNT, s_order_cnt); r_stock_local->set_value(S_ORDER_CNT, s_order_cnt + 1); s_data = r_stock_local->get_value(S_DATA); #endif if (remote) { s_remote_cnt = *(int64_t*)r_stock_local->get_value(S_REMOTE_CNT); s_remote_cnt ++; r_stock_local->set_value(S_REMOTE_CNT, &s_remote_cnt); } uint64_t quantity; if (s_quantity > ol_quantity + 10) { quantity = s_quantity - ol_quantity; } else { quantity = s_quantity - ol_quantity + 91; } r_stock_local->set_value(S_QUANTITY, &quantity); /*====================================================+ EXEC SQL INSERT INTO order_line(ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info) VALUES(:o_id, :d_id, :w_id, :ol_number, :ol_i_id, :ol_supply_w_id, :ol_quantity, :ol_amount, :ol_dist_info); +====================================================*/ row_t * r_ol; uint64_t row_id; _wl->t_orderline->get_new_row(r_ol, wh_to_part(ol_supply_w_id), row_id); r_ol->set_value(OL_O_ID, &o_id); r_ol->set_value(OL_D_ID, &d_id); r_ol->set_value(OL_W_ID, &w_id); r_ol->set_value(OL_NUMBER, &ol_number); r_ol->set_value(OL_I_ID, &ol_i_id); #if !TPCC_SMALL r_ol->set_value(OL_SUPPLY_W_ID, &ol_supply_w_id); r_ol->set_value(OL_QUANTITY, &ol_quantity); r_ol->set_value(OL_AMOUNT, &ol_amount); #endif insert_row(r_ol, _wl->t_orderline); return RCOK; }
void tpcc_query::gen_payment(uint64_t thd_id) { type = TPCC_PAYMENT; if (FIRST_PART_LOCAL) w_id = thd_id % g_num_wh + 1; else w_id = URand(1, g_num_wh); d_w_id = w_id; uint64_t part_id = wh_to_part(w_id); part_to_access[0] = part_id; part_num = 1; d_id = URand(1, DIST_PER_WARE); h_amount = URand(1, 5000); int x = URand(1, 100); int y = URand(1, 100); if(x <= 85) { // home warehouse c_d_id = d_id; c_w_id = w_id; } else { // remote warehouse c_d_id = URand(1, DIST_PER_WARE); if(g_num_wh > 1) { while((c_w_id = URand(1, g_num_wh)) == w_id) {} if (wh_to_part(w_id) != wh_to_part(c_w_id)) { part_to_access[1] = wh_to_part(c_w_id); part_num = 2; } } else c_w_id = w_id; } if(y <= 60) { // by last name by_last_name = true; Lastname(NURand(255,0,999),c_last); } else { // by cust id by_last_name = false; c_id = NURand(1023, 1, g_cust_per_dist); } }
inline RC TPCCTxnManager::new_order_2(uint64_t w_id, uint64_t d_id, uint64_t c_id, bool remote, uint64_t ol_cnt,uint64_t o_entry_d, uint64_t * o_id, row_t *& r_cust_local) { uint64_t key; itemid_t * item; key = custKey(c_id, d_id, w_id); INDEX * index = _wl->i_customer_id; item = index_read(index, key, wh_to_part(w_id)); assert(item != NULL); row_t * r_cust = (row_t *) item->location; RC rc = get_row(r_cust, RD, r_cust_local); return rc; }
void TPCCTxnManager::copy_remote_items(TPCCQueryMessage * msg) { TPCCQuery* tpcc_query = (TPCCQuery*) query; msg->items.init(tpcc_query->items.size()); if(tpcc_query->txn_type == TPCC_PAYMENT) return; uint64_t dest_node_id = GET_NODE_ID(wh_to_part(tpcc_query->items[next_item_id]->ol_supply_w_id)); while(next_item_id < tpcc_query->items.size() && !is_local_item(next_item_id) && GET_NODE_ID(wh_to_part(tpcc_query->items[next_item_id]->ol_supply_w_id)) == dest_node_id) { Item_no * req = (Item_no*) mem_allocator.alloc(sizeof(Item_no)); req->copy(tpcc_query->items[next_item_id++]); msg->items.add(req); } }
uint64_t TPCCQuery::get_participants(Workload * wl) { uint64_t participant_cnt = 0; uint64_t active_cnt = 0; assert(participant_nodes.size()==0); assert(active_nodes.size()==0); for(uint64_t i = 0; i < g_node_cnt; i++) { participant_nodes.add(0); active_nodes.add(0); } assert(participant_nodes.size()==g_node_cnt); assert(active_nodes.size()==g_node_cnt); uint64_t home_wh_node; home_wh_node = GET_NODE_ID(wh_to_part(w_id)); participant_nodes.set(home_wh_node,1); active_nodes.set(home_wh_node,1); participant_cnt++; active_cnt++; if(txn_type == TPCC_PAYMENT) { uint64_t req_nid = GET_NODE_ID(wh_to_part(c_w_id)); if(participant_nodes[req_nid] == 0) { participant_cnt++; participant_nodes.set(req_nid,1); active_cnt++; active_nodes.set(req_nid,1); } } else if (txn_type == TPCC_NEW_ORDER) { for(uint64_t i = 0; i < ol_cnt; i++) { uint64_t req_nid = GET_NODE_ID(wh_to_part(items[i]->ol_supply_w_id)); if(participant_nodes[req_nid] == 0) { participant_cnt++; participant_nodes.set(req_nid,1); active_cnt++; active_nodes.set(req_nid,1); } } } return participant_cnt; }
inline RC TPCCTxnManager::new_order_5(uint64_t w_id, uint64_t d_id, uint64_t c_id, bool remote, uint64_t ol_cnt,uint64_t o_entry_d, uint64_t * o_id, row_t * r_dist_local) { assert(r_dist_local != NULL); //double d_tax; //int64_t o_id; //d_tax = *(double *) r_dist_local->get_value(D_TAX); *o_id = *(int64_t *) r_dist_local->get_value(D_NEXT_O_ID); (*o_id) ++; r_dist_local->set_value(D_NEXT_O_ID, *o_id); // return o_id /*========================================================================================+ EXEC SQL INSERT INTO ORDERS (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) VALUES (:o_id, :d_id, :w_id, :c_id, :datetime, :o_ol_cnt, :o_all_local); +========================================================================================*/ row_t * r_order; uint64_t row_id; _wl->t_order->get_new_row(r_order, wh_to_part(w_id), row_id); r_order->set_value(O_ID, *o_id); r_order->set_value(O_C_ID, c_id); r_order->set_value(O_D_ID, d_id); r_order->set_value(O_W_ID, w_id); r_order->set_value(O_ENTRY_D, o_entry_d); r_order->set_value(O_OL_CNT, ol_cnt); int64_t all_local = (remote? 0 : 1); r_order->set_value(O_ALL_LOCAL, all_local); insert_row(r_order, _wl->t_order); /*=======================================================+ EXEC SQL INSERT INTO NEW_ORDER (no_o_id, no_d_id, no_w_id) VALUES (:o_id, :d_id, :w_id); +=======================================================*/ row_t * r_no; _wl->t_neworder->get_new_row(r_no, wh_to_part(w_id), row_id); r_no->set_value(NO_O_ID, *o_id); r_no->set_value(NO_D_ID, d_id); r_no->set_value(NO_W_ID, w_id); insert_row(r_no, _wl->t_neworder); return RCOK; }
RC TPCCTxnManager::send_remote_request() { assert(IS_LOCAL(get_txn_id())); TPCCQuery* tpcc_query = (TPCCQuery*) query; TPCCRemTxnType next_state = TPCC_FIN; uint64_t w_id = tpcc_query->w_id; uint64_t c_w_id = tpcc_query->c_w_id; uint64_t dest_node_id = UINT64_MAX; if(state == TPCC_PAYMENT0) { dest_node_id = GET_NODE_ID(wh_to_part(w_id)); next_state = TPCC_PAYMENT2; } else if(state == TPCC_PAYMENT4) { dest_node_id = GET_NODE_ID(wh_to_part(c_w_id)); next_state = TPCC_FIN; } else if(state == TPCC_NEWORDER0) { dest_node_id = GET_NODE_ID(wh_to_part(w_id)); next_state = TPCC_NEWORDER6; } else if(state == TPCC_NEWORDER8) { dest_node_id = GET_NODE_ID(wh_to_part(tpcc_query->items[next_item_id]->ol_supply_w_id)); /* while(GET_NODE_ID(wh_to_part(tpcc_query->items[next_item_id]->ol_supply_w_id)) != dest_node_id) { msg->items.add(tpcc_query->items[next_item_id++]); } */ if(is_done()) next_state = TPCC_FIN; else next_state = TPCC_NEWORDER6; } else { assert(false); } TPCCQueryMessage * msg = (TPCCQueryMessage*)Message::create_message(this,RQRY); msg->state = state; query->partitions_touched.add_unique(GET_PART_ID(0,dest_node_id)); msg_queue.enqueue(get_thd_id(),msg,dest_node_id); state = next_state; return WAIT_REM; }
std::set<uint64_t> TPCCQuery::participants(Message * msg, Workload * wl) { std::set<uint64_t> participant_set; TPCCClientQueryMessage* tpcc_msg = ((TPCCClientQueryMessage*)msg); uint64_t id; id = GET_NODE_ID(wh_to_part(tpcc_msg->w_id)); participant_set.insert(id); switch(tpcc_msg->txn_type) { case TPCC_PAYMENT: id = GET_NODE_ID(wh_to_part(tpcc_msg->c_w_id)); participant_set.insert(id); break; case TPCC_NEW_ORDER: for(uint64_t i = 0; i < tpcc_msg->ol_cnt; i++) { uint64_t req_nid = GET_NODE_ID(wh_to_part(tpcc_msg->items[i]->ol_supply_w_id)); participant_set.insert(req_nid); } break; default: assert(false); } return participant_set; }
inline RC TPCCTxnManager::run_payment_2(uint64_t w_id, uint64_t d_id, uint64_t d_w_id, double h_amount, row_t *& r_dist_local) { /*=====================================================+ EXEC SQL UPDATE district SET d_ytd = d_ytd + :h_amount WHERE d_w_id=:w_id AND d_id=:d_id; +=====================================================*/ uint64_t key; itemid_t * item; key = distKey(d_id, d_w_id); item = index_read(_wl->i_district, key, wh_to_part(w_id)); assert(item != NULL); row_t * r_dist = ((row_t *)item->location); RC rc = get_row(r_dist, WR, r_dist_local); return rc; }
inline RC TPCCTxnManager::new_order_4(uint64_t w_id, uint64_t d_id, uint64_t c_id, bool remote, uint64_t ol_cnt,uint64_t o_entry_d, uint64_t * o_id, row_t *& r_dist_local) { uint64_t key; itemid_t * item; /*==================================================+ EXEC SQL SELECT d_next_o_id, d_tax INTO :d_next_o_id, :d_tax FROM district WHERE d_id = :d_id AND d_w_id = :w_id; EXEC SQL UPDATE d istrict SET d _next_o_id = :d _next_o_id + 1 WH ERE d _id = :d_id AN D d _w _id = :w _id ; +===================================================*/ key = distKey(d_id, w_id); item = index_read(_wl->i_district, key, wh_to_part(w_id)); assert(item != NULL); row_t * r_dist = ((row_t *)item->location); RC rc = get_row(r_dist, WR, r_dist_local); return rc; }
// new_order 0 inline RC TPCCTxnManager::new_order_0(uint64_t w_id, uint64_t d_id, uint64_t c_id, bool remote, uint64_t ol_cnt,uint64_t o_entry_d, uint64_t * o_id, row_t *& r_wh_local) { uint64_t key; itemid_t * item; /*=======================================================================+ EXEC SQL SELECT c_discount, c_last, c_credit, w_tax INTO :c_discount, :c_last, :c_credit, :w_tax FROM customer, warehouse WHERE w_id = :w_id AND c_w_id = w_id AND c_d_id = :d_id AND c_id = :c_id; +========================================================================*/ key = w_id; INDEX * index = _wl->i_warehouse; item = index_read(index, key, wh_to_part(w_id)); assert(item != NULL); row_t * r_wh = ((row_t *)item->location); RC rc = get_row(r_wh, RD, r_wh_local); return rc; }
void tpcc_wl::init_tab_stock(uint64_t wid) { for (UInt32 sid = 1; sid <= g_max_items; sid++) { row_t * row; uint64_t row_id; t_stock->get_new_row(row, 0, row_id); row->set_primary_key(sid); row->set_value(S_I_ID, sid); row->set_value(S_W_ID, wid); row->set_value(S_QUANTITY, URand(10, 100)); row->set_value(S_REMOTE_CNT, 0); #if !TPCC_SMALL char s_dist[25]; char row_name[10] = "S_DIST_"; for (int i = 1; i <= 10; i++) { if (i < 10) { row_name[7] = '0'; row_name[8] = i + '0'; } else { row_name[7] = '1'; row_name[8] = '0'; } row_name[9] = '\0'; MakeAlphaString(24, 24, s_dist); row->set_value(row_name, s_dist); } row->set_value(S_YTD, 0); row->set_value(S_ORDER_CNT, 0); char s_data[50]; int len = MakeAlphaString(26, 50, s_data); if (rand() % 100 < 10) { int idx = URand(0, len - 8); strcpy(&s_data[idx], "original"); } row->set_value(S_DATA, s_data); #endif index_insert(i_stock, stockKey(sid, wid), row, wh_to_part(wid)); } }
inline RC TPCCTxnManager::run_payment_5(uint64_t w_id, uint64_t d_id,uint64_t c_id,uint64_t c_w_id, uint64_t c_d_id, char * c_last, double h_amount, bool by_last_name, row_t * r_cust_local) { assert(r_cust_local != NULL); double c_balance; double c_ytd_payment; double c_payment_cnt; r_cust_local->get_value(C_BALANCE, c_balance); r_cust_local->set_value(C_BALANCE, c_balance - h_amount); r_cust_local->get_value(C_YTD_PAYMENT, c_ytd_payment); r_cust_local->set_value(C_YTD_PAYMENT, c_ytd_payment + h_amount); r_cust_local->get_value(C_PAYMENT_CNT, c_payment_cnt); r_cust_local->set_value(C_PAYMENT_CNT, c_payment_cnt + 1); //char * c_credit = r_cust_local->get_value(C_CREDIT); /*=============================================================================+ EXEC SQL INSERT INTO history (h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) VALUES (:c_d_id, :c_w_id, :c_id, :d_id, :w_id, :datetime, :h_amount, :h_data); +=============================================================================*/ row_t * r_hist; uint64_t row_id; // Which partition should we be inserting into? _wl->t_history->get_new_row(r_hist, wh_to_part(c_w_id), row_id); r_hist->set_value(H_C_ID, c_id); r_hist->set_value(H_C_D_ID, c_d_id); r_hist->set_value(H_C_W_ID, c_w_id); r_hist->set_value(H_D_ID, d_id); r_hist->set_value(H_W_ID, w_id); int64_t date = 2013; r_hist->set_value(H_DATE, date); r_hist->set_value(H_AMOUNT, h_amount); insert_row(r_hist, _wl->t_history); return RCOK; }
void tpcc_wl::init_tab_wh() { if (WL_VERB) printf("[init] workload table.\n"); for (UInt32 wid = 1; wid <= g_num_wh; wid ++) { row_t * row; uint64_t row_id; t_warehouse->get_new_row(row, 0, row_id); row->set_primary_key(wid); row->set_value(W_ID, wid); char name[10]; MakeAlphaString(6, 10, name); row->set_value(W_NAME, name); char street[20]; MakeAlphaString(10, 20, street); row->set_value(W_STREET_1, street); MakeAlphaString(10, 20, street); row->set_value(W_STREET_2, street); MakeAlphaString(10, 20, street); row->set_value(W_CITY, street); char state[2]; MakeAlphaString(2, 2, state); /* State */ row->set_value(W_STATE, state); char zip[9]; MakeNumberString(9, 9, zip); /* Zip */ row->set_value(W_ZIP, zip); double tax = (double)URand(0L,200L)/1000.0; double w_ytd=300000.00; row->set_value(W_TAX, tax); row->set_value(W_YTD, w_ytd); index_insert(i_warehouse, wid, row, wh_to_part(wid)); } return; }
RC TPCCTxnManager::run_txn_state() { TPCCQuery* tpcc_query = (TPCCQuery*) query; uint64_t w_id = tpcc_query->w_id; uint64_t d_id = tpcc_query->d_id; uint64_t c_id = tpcc_query->c_id; uint64_t d_w_id = tpcc_query->d_w_id; uint64_t c_w_id = tpcc_query->c_w_id; uint64_t c_d_id = tpcc_query->c_d_id; char * c_last = tpcc_query->c_last; double h_amount = tpcc_query->h_amount; bool by_last_name = tpcc_query->by_last_name; bool remote = tpcc_query->remote; uint64_t ol_cnt = tpcc_query->ol_cnt; uint64_t o_entry_d = tpcc_query->o_entry_d; uint64_t ol_i_id = 0; uint64_t ol_supply_w_id = 0; uint64_t ol_quantity = 0; if(tpcc_query->txn_type == TPCC_NEW_ORDER) { ol_i_id = tpcc_query->items[next_item_id]->ol_i_id; ol_supply_w_id = tpcc_query->items[next_item_id]->ol_supply_w_id; ol_quantity = tpcc_query->items[next_item_id]->ol_quantity; } uint64_t ol_number = next_item_id; uint64_t ol_amount = tpcc_query->ol_amount; uint64_t o_id = tpcc_query->o_id; uint64_t part_id_w = wh_to_part(w_id); uint64_t part_id_c_w = wh_to_part(c_w_id); uint64_t part_id_ol_supply_w = wh_to_part(ol_supply_w_id); bool w_loc = GET_NODE_ID(part_id_w) == g_node_id; bool c_w_loc = GET_NODE_ID(part_id_c_w) == g_node_id; bool ol_supply_w_loc = GET_NODE_ID(part_id_ol_supply_w) == g_node_id; RC rc = RCOK; switch (state) { case TPCC_PAYMENT0 : if(w_loc) rc = run_payment_0(w_id, d_id, d_w_id, h_amount, row); else { rc = send_remote_request(); } break; case TPCC_PAYMENT1 : rc = run_payment_1(w_id, d_id, d_w_id, h_amount, row); break; case TPCC_PAYMENT2 : rc = run_payment_2(w_id, d_id, d_w_id, h_amount, row); break; case TPCC_PAYMENT3 : rc = run_payment_3(w_id, d_id, d_w_id, h_amount, row); break; case TPCC_PAYMENT4 : if(c_w_loc) rc = run_payment_4( w_id, d_id, c_id, c_w_id, c_d_id, c_last, h_amount, by_last_name, row); else { rc = send_remote_request(); } break; case TPCC_PAYMENT5 : rc = run_payment_5( w_id, d_id, c_id, c_w_id, c_d_id, c_last, h_amount, by_last_name, row); break; case TPCC_NEWORDER0 : if(w_loc) rc = new_order_0( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); else { rc = send_remote_request(); } break; case TPCC_NEWORDER1 : rc = new_order_1( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); break; case TPCC_NEWORDER2 : rc = new_order_2( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); break; case TPCC_NEWORDER3 : rc = new_order_3( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); break; case TPCC_NEWORDER4 : rc = new_order_4( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); break; case TPCC_NEWORDER5 : rc = new_order_5( w_id, d_id, c_id, remote, ol_cnt, o_entry_d, &tpcc_query->o_id, row); break; case TPCC_NEWORDER6 : rc = new_order_6(ol_i_id, row); break; case TPCC_NEWORDER7 : rc = new_order_7(ol_i_id, row); break; case TPCC_NEWORDER8 : if(ol_supply_w_loc) { rc = new_order_8( w_id, d_id, remote, ol_i_id, ol_supply_w_id, ol_quantity, ol_number, o_id, row); } else { rc = send_remote_request(); } break; case TPCC_NEWORDER9 : rc = new_order_9( w_id, d_id, remote, ol_i_id, ol_supply_w_id, ol_quantity, ol_number, ol_amount, o_id, row); break; case TPCC_FIN : state = TPCC_FIN; if(tpcc_query->rbk) return Abort; //return finish(tpcc_query,false); break; default: assert(false); } if(rc == RCOK) next_tpcc_state(); return rc; }
RC tpcc_txn_man::run_new_order(tpcc_query * query) { RC rc = RCOK; uint64_t key; itemid_t * item; INDEX * index; bool remote = query->remote; uint64_t w_id = query->w_id; uint64_t d_id = query->d_id; uint64_t c_id = query->c_id; uint64_t ol_cnt = query->ol_cnt; uint64_t o_entry_d = query->o_entry_d; for (UInt32 ol_number = 0; ol_number < ol_cnt; ol_number++) { uint64_t ol_i_id = query->items[ol_number].ol_i_id; /*===========================================+ EXEC SQL SELECT i_price, i_name , i_data INTO :i_price, :i_name, :i_data FROM item WHERE i_id = :ol_i_id; +===========================================*/ key = ol_i_id; item = index_read(_wl->i_item, key, 0); assert(item != NULL); // rc = _wl->i_item->index_read(key, item, 0); // assert(rc == RCOK); row_t * r_item = ((row_t *)item->location); row_t * r_item_local = get_row(r_item, RD); if (r_item_local == NULL) { return finish(Abort); } int64_t i_price; //char * i_name; //char * i_data; r_item_local->get_value(I_PRICE, i_price); } /*=======================================================================+ EXEC SQL SELECT c_discount, c_last, c_credit, w_tax INTO :c_discount, :c_last, :c_credit, :w_tax FROM customer, warehouse WHERE w_id = :w_id AND c_w_id = w_id AND c_d_id = :d_id AND c_id = :c_id; +========================================================================*/ key = custKey(c_id, d_id, w_id); index = _wl->i_customer_id; item = index_read(index, key, wh_to_part(w_id)); assert(item != NULL); // rc = index->index_read(key, item, wh_to_part(w_id)); // assert(rc == RCOK); row_t * r_cust = (row_t *) item->location; row_t * r_cust_local = get_row(r_cust, RD); if (r_cust_local == NULL) { return finish(Abort); } uint64_t c_discount; //char * c_last; //char * c_credit; r_cust_local->get_value(C_DISCOUNT, c_discount); //c_last = r_cust_local->get_value(C_LAST); //c_credit = r_cust_local->get_value(C_CREDIT); /*==================================================+ EXEC SQL SELECT d_next_o_id, d_tax INTO :d_next_o_id, :d_tax FROM district WHERE d_id = :d_id AND d_w_id = :w_id; EXEC SQL UPDATE d istrict SET d _next_o_id = :d _next_o_id + 1 WH ERE d _id = :d_id AN D d _w _id = :w _id ; +===================================================*/ key = distKey(d_id, w_id); item = index_read(_wl->i_district, key, wh_to_part(w_id)); assert(item != NULL); // rc = _wl->i_district->index_read(key, item, wh_to_part(w_id)); // assert(rc == RCOK); row_t * r_dist = ((row_t *)item->location); row_t * r_dist_local = get_row(r_dist, WR); if (r_dist_local == NULL) { return finish(Abort); } //double d_tax; int64_t o_id; //d_tax = *(double *) r_dist_local->get_value(D_TAX); o_id = *(int64_t *) r_dist_local->get_value(D_NEXT_O_ID); o_id ++; /*========================================================================================+ EXEC SQL INSERT INTO ORDERS (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) VALUES (:o_id, :d_id, :w_id, :c_id, :datetime, :o_ol_cnt, :o_all_local); +========================================================================================*/ row_t * r_order; uint64_t row_id; _wl->t_order->get_new_row(r_order, 0, row_id); r_order->set_value(O_ID, o_id); r_order->set_value(O_C_ID, c_id); r_order->set_value(O_D_ID, d_id); r_order->set_value(O_W_ID, w_id); r_order->set_value(O_ENTRY_D, o_entry_d); r_order->set_value(O_OL_CNT, ol_cnt); int64_t all_local = (remote? 0 : 1); r_order->set_value(O_ALL_LOCAL, all_local); insert_row(r_order, _wl->t_order); /*=======================================================+ EXEC SQL INSERT INTO NEW_ORDER (no_o_id, no_d_id, no_w_id) VALUES (:o_id, :d_id, :w_id); +=======================================================*/ row_t * r_no; _wl->t_neworder->get_new_row(r_no, 0, row_id); r_no->set_value(NO_O_ID, o_id); r_no->set_value(NO_D_ID, d_id); r_no->set_value(NO_W_ID, w_id); insert_row(r_no, _wl->t_neworder); for (UInt32 ol_number = 0; ol_number < ol_cnt; ol_number++) { uint64_t ol_i_id = query->items[ol_number].ol_i_id; uint64_t ol_supply_w_id = query->items[ol_number].ol_supply_w_id; uint64_t ol_quantity = query->items[ol_number].ol_quantity; /*===================================================================+ EXEC SQL SELECT s_quantity, s_data, s_dist_01, s_dist_02, s_dist_03, s_dist_04, s_dist_05, s_dist_06, s_dist_07, s_dist_08, s_dist_09, s_dist_10 INTO :s_quantity, :s_data, :s_dist_01, :s_dist_02, :s_dist_03, :s_dist_04, :s_dist_05, :s_dist_06, :s_dist_07, :s_dist_08, :s_dist_09, :s_dist_10 FROM stock WHERE s_i_id = :ol_i_id AND s_w_id = :ol_supply_w_id; EXEC SQL UPDATE stock SET s_quantity = :s_quantity WHERE s_i_id = :ol_i_id AND s_w_id = :ol_supply_w_id; +===============================================*/ key = stockKey(ol_i_id, ol_supply_w_id); index = _wl->i_stock; item = index_read(index, key, wh_to_part(ol_supply_w_id)); assert(item != NULL); // rc = index->index_read(key, item, wh_to_part(ol_supply_w_id)); // assert(rc == RCOK); row_t * r_stock = ((row_t *)item->location); row_t * r_stock_local = get_row(r_stock, WR); if (r_stock_local == NULL) { return finish(Abort); } // XXX s_dist_xx are not retrieved. UInt64 s_quantity; int64_t s_remote_cnt; s_quantity = *(int64_t *)r_stock_local->get_value(S_QUANTITY); #if !TPCC_SMALL int64_t s_ytd; int64_t s_order_cnt; char * s_data; r_stock_local->get_value(S_YTD, s_ytd); r_stock_local->set_value(S_YTD, s_ytd + ol_quantity); r_stock_local->get_value(S_ORDER_CNT, s_order_cnt); r_stock_local->set_value(S_ORDER_CNT, s_order_cnt + 1); s_data = r_stock_local->get_value(S_DATA); #endif if (remote) { s_remote_cnt = *(int64_t*)r_stock_local->get_value(S_REMOTE_CNT); s_remote_cnt ++; r_stock_local->set_value(S_REMOTE_CNT, &s_remote_cnt); } uint64_t quantity; if (s_quantity > ol_quantity + 10) { quantity = s_quantity - ol_quantity; } else { quantity = s_quantity - ol_quantity + 91; } r_stock_local->set_value(S_QUANTITY, &quantity); /*====================================================+ EXEC SQL INSERT INTO order_line(ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info) VALUES(:o_id, :d_id, :w_id, :ol_number, :ol_i_id, :ol_supply_w_id, :ol_quantity, :ol_amount, :ol_dist_info); +====================================================*/ // XXX district info is not inserted. //int64_t ol_amount = ol_quantity * i_price * (1 + w_tax + d_tax) * (1 - c_discount); row_t * r_ol; uint64_t row_id; _wl->t_orderline->get_new_row(r_ol, 0, row_id); r_ol->set_value(OL_O_ID, &o_id); r_ol->set_value(OL_D_ID, &d_id); r_ol->set_value(OL_W_ID, &w_id); r_ol->set_value(OL_NUMBER, &ol_number); r_ol->set_value(OL_I_ID, &ol_i_id); #if !TPCC_SMALL r_ol->set_value(OL_SUPPLY_W_ID, &ol_supply_w_id); r_ol->set_value(OL_QUANTITY, &ol_quantity); r_ol->set_value(OL_AMOUNT, &ol_amount); #endif insert_row(r_ol, _wl->t_orderline); } r_dist_local->set_value(D_NEXT_O_ID, o_id); key = w_id; index = _wl->i_warehouse; // rc = index->index_read(key, item, wh_to_part(w_id)); item = index_read(index, key, wh_to_part(w_id)); assert(item != NULL); row_t * r_wh = ((row_t *)item->location); row_t * r_wh_local = get_row(r_wh, RD); if (r_wh_local == NULL) { return finish(Abort); } double w_tax; r_wh_local->get_value(W_TAX, w_tax); assert( rc == RCOK ); return finish(rc); }
inline RC TPCCTxnManager::run_payment_4(uint64_t w_id, uint64_t d_id,uint64_t c_id,uint64_t c_w_id, uint64_t c_d_id, char * c_last, double h_amount, bool by_last_name, row_t *& r_cust_local) { /*====================================================================+ EXEC SQL SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name INTO :d_street_1, :d_street_2, :d_city, :d_state, :d_zip, :d_name FROM district WHERE d_w_id=:w_id AND d_id=:d_id; +====================================================================*/ itemid_t * item; uint64_t key; row_t * r_cust; if (by_last_name) { /*==========================================================+ EXEC SQL SELECT count(c_id) INTO :namecnt FROM customer WHERE c_last=:c_last AND c_d_id=:c_d_id AND c_w_id=:c_w_id; +==========================================================*/ /*==========================================================================+ EXEC SQL DECLARE c_byname CURSOR FOR SELECT c_first, c_middle, c_id, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_since FROM customer WHERE c_w_id=:c_w_id AND c_d_id=:c_d_id AND c_last=:c_last ORDER BY c_first; EXEC SQL OPEN c_byname; +===========================================================================*/ key = custNPKey(c_last, c_d_id, c_w_id); // XXX: the list is not sorted. But let's assume it's sorted... // The performance won't be much different. INDEX * index = _wl->i_customer_last; item = index_read(index, key, wh_to_part(c_w_id)); assert(item != NULL); int cnt = 0; itemid_t * it = item; itemid_t * mid = item; while (it != NULL) { cnt ++; it = it->next; if (cnt % 2 == 0) mid = mid->next; } r_cust = ((row_t *)mid->location); /*============================================================================+ for (n=0; n<namecnt/2; n++) { EXEC SQL FETCH c_byname INTO :c_first, :c_middle, :c_id, :c_street_1, :c_street_2, :c_city, :c_state, :c_zip, :c_phone, :c_credit, :c_credit_lim, :c_discount, :c_balance, :c_since; } EXEC SQL CLOSE c_byname; +=============================================================================*/ // XXX: we don't retrieve all the info, just the tuple we are interested in } else { // search customers by cust_id /*=====================================================================+ EXEC SQL SELECT c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_since INTO :c_first, :c_middle, :c_last, :c_street_1, :c_street_2, :c_city, :c_state, :c_zip, :c_phone, :c_credit, :c_credit_lim, :c_discount, :c_balance, :c_since FROM customer WHERE c_w_id=:c_w_id AND c_d_id=:c_d_id AND c_id=:c_id; +======================================================================*/ key = custKey(c_id, c_d_id, c_w_id); INDEX * index = _wl->i_customer_id; item = index_read(index, key, wh_to_part(c_w_id)); assert(item != NULL); r_cust = (row_t *) item->location; } /*======================================================================+ EXEC SQL UPDATE customer SET c_balance = :c_balance, c_data = :c_new_data WHERE c_w_id = :c_w_id AND c_d_id = :c_d_id AND c_id = :c_id; +======================================================================*/ RC rc = get_row(r_cust, WR, r_cust_local); return rc; }
RC tpcc_txn_man::run_payment(tpcc_query * query) { RC rc = RCOK; uint64_t key; itemid_t * item; uint64_t w_id = query->w_id; uint64_t d_id = query->d_id; uint64_t c_w_id = query->c_w_id; uint64_t c_d_id = query->c_d_id; uint64_t c_id = query->c_id; double h_amount = query->h_amount; row_t * r_cust; if (query->by_last_name) { /*==========================================================+ EXEC SQL SELECT count(c_id) INTO :namecnt FROM customer WHERE c_last=:c_last AND c_d_id=:c_d_id AND c_w_id=:c_w_id; +==========================================================*/ /*==========================================================================+ EXEC SQL DECLARE c_byname CURSOR FOR SELECT c_first, c_middle, c_id, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_since FROM customer WHERE c_w_id=:c_w_id AND c_d_id=:c_d_id AND c_last=:c_last ORDER BY c_first; EXEC SQL OPEN c_byname; +===========================================================================*/ uint64_t key = custNPKey(query->c_last, query->c_d_id, query->c_w_id); // XXX: the list is not sorted. But let's assume it's sorted... // The performance won't be much different. INDEX * index = _wl->i_customer_last; item = index_read(index, key, wh_to_part(c_w_id)); assert(item != NULL); int cnt = 0; itemid_t * it = item; itemid_t * mid = item; while (it != NULL) { cnt ++; it = it->next; if (cnt % 2 == 0) mid = mid->next; } r_cust = ((row_t *)mid->location); /*============================================================================+ for (n=0; n<namecnt/2; n++) { EXEC SQL FETCH c_byname INTO :c_first, :c_middle, :c_id, :c_street_1, :c_street_2, :c_city, :c_state, :c_zip, :c_phone, :c_credit, :c_credit_lim, :c_discount, :c_balance, :c_since; } EXEC SQL CLOSE c_byname; +=============================================================================*/ // XXX: we don't retrieve all the info, just the tuple we are interested in } else { // search customers by cust_id /*=====================================================================+ EXEC SQL SELECT c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_since INTO :c_first, :c_middle, :c_last, :c_street_1, :c_street_2, :c_city, :c_state, :c_zip, :c_phone, :c_credit, :c_credit_lim, :c_discount, :c_balance, :c_since FROM customer WHERE c_w_id=:c_w_id AND c_d_id=:c_d_id AND c_id=:c_id; +======================================================================*/ key = custKey(query->c_id, query->c_d_id, query->c_w_id); INDEX * index = _wl->i_customer_id; item = index_read(index, key, wh_to_part(c_w_id)); assert(item != NULL); // rc = index->index_read(key, item, wh_to_part(c_w_id)); // assert(rc == RCOK); r_cust = (row_t *) item->location; } /*======================================================================+ EXEC SQL UPDATE customer SET c_balance = :c_balance, c_data = :c_new_data WHERE c_w_id = :c_w_id AND c_d_id = :c_d_id AND c_id = :c_id; +======================================================================*/ row_t * r_cust_local = get_row(r_cust, WR); if (r_cust_local == NULL) { return finish(Abort); } double c_balance; double c_ytd_payment; double c_payment_cnt; r_cust_local->get_value(C_BALANCE, c_balance); r_cust_local->set_value(C_BALANCE, c_balance - query->h_amount); r_cust_local->get_value(C_YTD_PAYMENT, c_ytd_payment); r_cust_local->set_value(C_YTD_PAYMENT, c_ytd_payment + query->h_amount); r_cust_local->get_value(C_PAYMENT_CNT, c_payment_cnt); r_cust_local->set_value(C_PAYMENT_CNT, c_payment_cnt + 1); char * c_credit = r_cust_local->get_value(C_CREDIT); if ( strstr(c_credit, "BC") ) { /*=====================================================+ EXEC SQL SELECT c_data INTO :c_data FROM customer WHERE c_w_id=:c_w_id AND c_d_id=:c_d_id AND c_id=:c_id; +=====================================================*/ // char c_new_data[501]; // sprintf(c_new_data,"| %4d %2d %4d %2d %4d $%7.2f", // c_id, c_d_id, c_w_id, d_id, w_id, query->h_amount); // char * c_data = r_cust->get_value("C_DATA"); // strncat(c_new_data, c_data, 500 - strlen(c_new_data)); // r_cust->set_value("C_DATA", c_new_data); } /*=====================================================+ EXEC SQL UPDATE district SET d_ytd = d_ytd + :h_amount WHERE d_w_id=:w_id AND d_id=:d_id; +=====================================================*/ uint64_t t3 = get_sys_clock(); key = distKey(query->d_id, query->d_w_id); item = index_read(_wl->i_district, key, wh_to_part(w_id)); assert(item != NULL); // rc = _wl->i_district->index_read(key, item, wh_to_part(w_id)); // assert(rc == RCOK); row_t * r_dist = ((row_t *)item->location); row_t * r_dist_local = get_row(r_dist, WR); if (r_dist_local == NULL) { return finish(Abort); } uint64_t tt3 = get_sys_clock() - t3; INC_STATS(get_thd_id(), debug3, tt3); double d_ytd; r_dist_local->get_value(D_YTD, d_ytd); r_dist_local->set_value(D_YTD, d_ytd + query->h_amount); /*====================================================+ EXEC SQL UPDATE warehouse SET w_ytd = w_ytd + :h_amount WHERE w_id=:w_id; +====================================================*/ /*===================================================================+ EXEC SQL SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name INTO :w_street_1, :w_street_2, :w_city, :w_state, :w_zip, :w_name FROM warehouse WHERE w_id=:w_id; +===================================================================*/ key = query->w_id; INDEX * index = _wl->i_warehouse; item = index_read(index, key, wh_to_part(w_id)); assert(item != NULL); // rc = index->index_read(key, item, wh_to_part(w_id)); // assert(rc == RCOK); row_t * r_wh = ((row_t *)item->location); row_t * r_wh_local; uint64_t t5 = get_sys_clock(); if (g_wh_update) r_wh_local = get_row(r_wh, WR); else r_wh_local = get_row(r_wh, RD); uint64_t tt5 = get_sys_clock() - t5; INC_STATS(get_thd_id(), debug5, tt5); if (r_wh_local == NULL) { return finish(Abort); } double w_ytd; uint64_t t1 = get_sys_clock(); r_wh_local->get_value(W_YTD, w_ytd); /*=============================================================================+ EXEC SQL INSERT INTO history (h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) VALUES (:c_d_id, :c_w_id, :c_id, :d_id, :w_id, :datetime, :h_amount, :h_data); +=============================================================================*/ row_t * r_hist; uint64_t row_id; _wl->t_history->get_new_row(r_hist, 0, row_id); r_hist->set_value(H_C_ID, c_id); r_hist->set_value(H_C_D_ID, c_d_id); r_hist->set_value(H_C_W_ID, c_w_id); r_hist->set_value(H_D_ID, d_id); r_hist->set_value(H_W_ID, w_id); int64_t date = 2013; r_hist->set_value(H_DATE, date); r_hist->set_value(H_AMOUNT, h_amount); insert_row(r_hist, _wl->t_history); if (g_wh_update) { r_wh_local->set_value(W_YTD, w_ytd + query->h_amount); } uint64_t tt1 = get_sys_clock() - t1; INC_STATS(get_thd_id(), debug1, tt1); assert( rc == RCOK ); return finish(rc); }
bool TPCCTxnManager::is_local_item(uint64_t idx) { TPCCQuery* tpcc_query = (TPCCQuery*) query; uint64_t ol_supply_w_id = tpcc_query->items[idx]->ol_supply_w_id; uint64_t part_id_ol_supply_w = wh_to_part(ol_supply_w_id); return GET_NODE_ID(part_id_ol_supply_w) == g_node_id; }
RC TPCCTxnManager::acquire_locks() { uint64_t starttime = get_sys_clock(); assert(CC_ALG == CALVIN); locking_done = false; RC rc = RCOK; RC rc2; INDEX * index; itemid_t * item; row_t* row; uint64_t key; incr_lr(); TPCCQuery* tpcc_query = (TPCCQuery*) query; uint64_t w_id = tpcc_query->w_id; uint64_t d_id = tpcc_query->d_id; uint64_t c_id = tpcc_query->c_id; uint64_t d_w_id = tpcc_query->d_w_id; uint64_t c_w_id = tpcc_query->c_w_id; uint64_t c_d_id = tpcc_query->c_d_id; char * c_last = tpcc_query->c_last; uint64_t part_id_w = wh_to_part(w_id); uint64_t part_id_c_w = wh_to_part(c_w_id); switch(tpcc_query->txn_type) { case TPCC_PAYMENT: if(GET_NODE_ID(part_id_w) == g_node_id) { // WH index = _wl->i_warehouse; item = index_read(index, w_id, part_id_w); row_t * row = ((row_t *)item->location); rc2 = get_lock(row,g_wh_update? WR:RD); if(rc2 != RCOK) rc = rc2; // Dist key = distKey(d_id, d_w_id); item = index_read(_wl->i_district, key, part_id_w); row = ((row_t *)item->location); rc2 = get_lock(row, WR); if(rc2 != RCOK) rc = rc2; } if(GET_NODE_ID(part_id_c_w) == g_node_id) { // Cust if (tpcc_query->by_last_name) { key = custNPKey(c_last, c_d_id, c_w_id); index = _wl->i_customer_last; item = index_read(index, key, part_id_c_w); int cnt = 0; itemid_t * it = item; itemid_t * mid = item; while (it != NULL) { cnt ++; it = it->next; if (cnt % 2 == 0) mid = mid->next; } row = ((row_t *)mid->location); } else { key = custKey(c_id, c_d_id, c_w_id); index = _wl->i_customer_id; item = index_read(index, key, part_id_c_w); row = (row_t *) item->location; } rc2 = get_lock(row, WR); if(rc2 != RCOK) rc = rc2; } break; case TPCC_NEW_ORDER: if(GET_NODE_ID(part_id_w) == g_node_id) { // WH index = _wl->i_warehouse; item = index_read(index, w_id, part_id_w); row_t * row = ((row_t *)item->location); rc2 = get_lock(row,RD); if(rc2 != RCOK) rc = rc2; // Cust index = _wl->i_customer_id; key = custKey(c_id, d_id, w_id); item = index_read(index, key, wh_to_part(w_id)); row = (row_t *) item->location; rc2 = get_lock(row, RD); if(rc2 != RCOK) rc = rc2; // Dist key = distKey(d_id, w_id); item = index_read(_wl->i_district, key, wh_to_part(w_id)); row = ((row_t *)item->location); rc2 = get_lock(row, WR); if(rc2 != RCOK) rc = rc2; } // Items for(uint64_t i = 0; i < tpcc_query->ol_cnt; i++) { if(GET_NODE_ID(wh_to_part(tpcc_query->items[i]->ol_supply_w_id)) != g_node_id) continue; key = tpcc_query->items[i]->ol_i_id; item = index_read(_wl->i_item, key, 0); row = ((row_t *)item->location); rc2 = get_lock(row, RD); if(rc2 != RCOK) rc = rc2; key = stockKey(tpcc_query->items[i]->ol_i_id, tpcc_query->items[i]->ol_supply_w_id); index = _wl->i_stock; item = index_read(index, key, wh_to_part(tpcc_query->items[i]->ol_supply_w_id)); row = ((row_t *)item->location); rc2 = get_lock(row, WR); if(rc2 != RCOK) rc = rc2; } break; default: assert(false); } if(decr_lr() == 0) { if(ATOM_CAS(lock_ready,false,true)) rc = RCOK; } txn_stats.wait_starttime = get_sys_clock(); locking_done = true; INC_STATS(get_thd_id(),calvin_sched_time,get_sys_clock() - starttime); return rc; }
void tpcc_wl::init_tab_cust(uint64_t did, uint64_t wid) { assert(g_cust_per_dist >= 1000); for (UInt32 cid = 1; cid <= g_cust_per_dist; cid++) { row_t * row; uint64_t row_id; t_customer->get_new_row(row, 0, row_id); row->set_primary_key(cid); row->set_value(C_ID, cid); row->set_value(C_D_ID, did); row->set_value(C_W_ID, wid); char c_last[LASTNAME_LEN]; if (cid <= 1000) Lastname(cid - 1, c_last); else Lastname(NURand(255,0,999), c_last); row->set_value(C_LAST, c_last); #if !TPCC_SMALL char * tmp = "OE"; row->set_value(C_MIDDLE, tmp); char c_first[FIRSTNAME_LEN]; MakeAlphaString(FIRSTNAME_MINLEN, sizeof(c_first), c_first); row->set_value(C_FIRST, c_first); char street[20]; MakeAlphaString(10, 20, street); row->set_value(C_STREET_1, street); MakeAlphaString(10, 20, street); row->set_value(C_STREET_2, street); MakeAlphaString(10, 20, street); row->set_value(C_CITY, street); char state[2]; MakeAlphaString(2, 2, state); /* State */ row->set_value(C_STATE, state); char zip[9]; MakeNumberString(9, 9, zip); /* Zip */ row->set_value(C_ZIP, zip); char phone[16]; MakeNumberString(16, 16, phone); /* Zip */ row->set_value(C_PHONE, phone); row->set_value(C_SINCE, 0); row->set_value(C_CREDIT_LIM, 50000); row->set_value(C_DELIVERY_CNT, 0); char c_data[500]; MakeAlphaString(300, 500, c_data); row->set_value(C_DATA, c_data); #endif if (RAND(10) == 0) { char tmp[] = "GC"; row->set_value(C_CREDIT, tmp); } else { char tmp[] = "BC"; row->set_value(C_CREDIT, tmp); } row->set_value(C_DISCOUNT, (double)RAND(5000) / 10000); row->set_value(C_BALANCE, -10.0); row->set_value(C_YTD_PAYMENT, 10.0); row->set_value(C_PAYMENT_CNT, 1); uint64_t key; key = custNPKey(c_last, did, wid); index_insert(i_customer_last, key, row, wh_to_part(wid)); key = custKey(cid, did, wid); index_insert(i_customer_id, key, row, wh_to_part(wid)); } }