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