From 8167b767655c75253fae0c85af6e7a513e050e11 Mon Sep 17 00:00:00 2001 From: happyZYM Date: Fri, 24 May 2024 16:35:43 +0000 Subject: [PATCH] write refund --- src/include/transaction_mainenance.hpp | 13 +++++- src/transaction_system.cpp | 61 +++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/include/transaction_mainenance.hpp b/src/include/transaction_mainenance.hpp index 83499d0..306a57c 100644 --- a/src/include/transaction_mainenance.hpp +++ b/src/include/transaction_mainenance.hpp @@ -20,6 +20,9 @@ struct TransactionData { uint32_t arrive_time_stamp; uint32_t num; uint64_t total_price; + uint8_t running_date_offset; + uint8_t from_stop_id; + uint8_t to_stop_id; }; class TransactionManager : public DataDriverBase { struct queue_index_t { @@ -146,7 +149,7 @@ class TransactionManager : public DataDriverBase { } inline void AddOrder(std::string trainID, std::string from_station_name, std::string to_station_name, uint8_t status, uint32_t leave_time_stamp, uint32_t arrive_time_stamp, uint32_t num, uint64_t total_price, - uint8_t running_date_offset, std::string username) { + uint8_t running_date_offset, std::string username, uint8_t from_stop_id, uint8_t to_stop_id) { TransactionData tmp; strcpy(tmp.trainID, trainID.c_str()); strcpy(tmp.from_station_name, from_station_name.c_str()); @@ -156,6 +159,9 @@ class TransactionManager : public DataDriverBase { tmp.arrive_time_stamp = arrive_time_stamp; tmp.num = num; tmp.total_price = total_price; + tmp.running_date_offset = running_date_offset; + tmp.from_stop_id = from_stop_id; + tmp.to_stop_id = to_stop_id; b_plus_tree_value_index_t data_id = data_storage->write(tmp); hash_t train_ID_hash = SplitMix64Hash(trainID); hash_t user_ID_hash = SplitMix64Hash(username); @@ -248,5 +254,10 @@ class TransactionManager : public DataDriverBase { LOG->debug("fetching transaction data with idx {}", idx); data_storage->read(data, idx); } + inline void UpdateTransactionData(b_plus_tree_value_index_t idx, TransactionData &data) { + // warning: the validity of idx is not checked + LOG->debug("updating transaction data with idx {}", idx); + data_storage->update(data, idx); + } }; #endif \ No newline at end of file diff --git a/src/transaction_system.cpp b/src/transaction_system.cpp index 8e79eca..d649572 100644 --- a/src/transaction_system.cpp +++ b/src/transaction_system.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -257,13 +258,14 @@ std::string TicketSystemEngine::BuyTicket(const std::string &command) { } transaction_manager.AddOrder(train_id, from, to, 0, info.leave_time_stamp, info.arrive_time_stamp, ticket_num, total_price * (unsigned long long)ticket_num, - info.actual_start_date - info.saleDate_beg, user_name); + info.actual_start_date - info.saleDate_beg, user_name, info.from_stop_id, + info.to_stop_id); response_stream << "[" << command_id << "] queue"; return response_stream.str(); } transaction_manager.AddOrder(train_id, from, to, 1, info.leave_time_stamp, info.arrive_time_stamp, ticket_num, total_price * (unsigned long long)ticket_num, info.actual_start_date - info.saleDate_beg, - user_name); + user_name, info.from_stop_id, info.to_stop_id); for (int j = from_station_id; j < to_station_id; j++) { seats_data.seat[j] -= ticket_num; } @@ -351,6 +353,61 @@ std::string TicketSystemEngine::RefundTicket(const std::string &command) { response_stream << "[" << command_id << "] -1"; return response_stream.str(); } + b_plus_tree_value_index_t idx; + bool success = false; + idx = transaction_manager.FetchSingleUserOrderHistory(user_ID_hash, order, success); + if (!success) { + response_stream << "[" << command_id << "] -1"; + return response_stream.str(); + } + TransactionData txn_data; + transaction_manager.FetchTransactionData(idx, txn_data); + if (txn_data.status == 2) { + response_stream << "[" << command_id << "] -1"; + return response_stream.str(); + } + if (txn_data.status == 0) { + txn_data.status = 2; + transaction_manager.UpdateTransactionData(idx, txn_data); + // warning: the record in the queue is not deleted + response_stream << "[" << command_id << "] 0"; + return response_stream.str(); + } + txn_data.status = 2; + transaction_manager.UpdateTransactionData(idx, txn_data); + hash_t train_ID_hash = SplitMix64Hash(std::string_view(txn_data.trainID)); + hash_t from_station_hash = SplitMix64Hash(std::string_view(txn_data.from_station_name)); + hash_t to_station_hash = SplitMix64Hash(std::string_view(txn_data.to_station_name)); + SeatsData seats_data; + seats_data_storage.Get({train_ID_hash, txn_data.running_date_offset}, seats_data); + for (int i = txn_data.from_stop_id; i < txn_data.to_stop_id; i++) { + seats_data.seat[i] += txn_data.num; + } + seats_data_storage.Put({train_ID_hash, txn_data.running_date_offset}, seats_data); + std::vector> queue_idxs; + transaction_manager.FetchQueue(train_ID_hash, txn_data.running_date_offset, queue_idxs); + size_t len = queue_idxs.size(); + for (size_t i = 0; i < len; i++) { + TransactionData cur_txn_data; + transaction_manager.FetchTransactionData(queue_idxs[i].first, cur_txn_data); + if (cur_txn_data.status != 0) { + transaction_manager.RemoveOrderFromQueue(train_ID_hash, txn_data.running_date_offset, queue_idxs[i].second); + continue; + } + int available_seats = seats_data.seat[cur_txn_data.from_stop_id]; + for (size_t j = cur_txn_data.from_stop_id + 1; j < cur_txn_data.to_stop_id; j++) { + available_seats = std::min(available_seats, (int)seats_data.seat[j]); + } + if (available_seats >= cur_txn_data.num) { + cur_txn_data.status = 1; + transaction_manager.UpdateTransactionData(queue_idxs[i].first, cur_txn_data); + for (int j = cur_txn_data.from_stop_id; j < cur_txn_data.to_stop_id; j++) { + seats_data.seat[j] -= cur_txn_data.num; + } + seats_data_storage.Put({train_ID_hash, txn_data.running_date_offset}, seats_data); + transaction_manager.RemoveOrderFromQueue(train_ID_hash, txn_data.running_date_offset, queue_idxs[i].second); + } + } response_stream << "[" << command_id << "] 0"; return response_stream.str(); } \ No newline at end of file