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)); } }
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; }
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; }
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); }
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); }