write refund

This commit is contained in:
2024-05-24 16:35:43 +00:00
parent 109afd5bcf
commit 8167b76765
2 changed files with 71 additions and 3 deletions

View File

@ -20,6 +20,9 @@ struct TransactionData {
uint32_t arrive_time_stamp; uint32_t arrive_time_stamp;
uint32_t num; uint32_t num;
uint64_t total_price; uint64_t total_price;
uint8_t running_date_offset;
uint8_t from_stop_id;
uint8_t to_stop_id;
}; };
class TransactionManager : public DataDriverBase { class TransactionManager : public DataDriverBase {
struct queue_index_t { 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, 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, 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; TransactionData tmp;
strcpy(tmp.trainID, trainID.c_str()); strcpy(tmp.trainID, trainID.c_str());
strcpy(tmp.from_station_name, from_station_name.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.arrive_time_stamp = arrive_time_stamp;
tmp.num = num; tmp.num = num;
tmp.total_price = total_price; 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); b_plus_tree_value_index_t data_id = data_storage->write(tmp);
hash_t train_ID_hash = SplitMix64Hash(trainID); hash_t train_ID_hash = SplitMix64Hash(trainID);
hash_t user_ID_hash = SplitMix64Hash(username); hash_t user_ID_hash = SplitMix64Hash(username);
@ -248,5 +254,10 @@ class TransactionManager : public DataDriverBase {
LOG->debug("fetching transaction data with idx {}", idx); LOG->debug("fetching transaction data with idx {}", idx);
data_storage->read(data, 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 #endif

View File

@ -1,4 +1,5 @@
#include <algorithm> #include <algorithm>
#include <cstddef>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
@ -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, 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, 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"; response_stream << "[" << command_id << "] queue";
return response_stream.str(); return response_stream.str();
} }
transaction_manager.AddOrder(train_id, from, to, 1, info.leave_time_stamp, info.arrive_time_stamp, ticket_num, 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, 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++) { for (int j = from_station_id; j < to_station_id; j++) {
seats_data.seat[j] -= ticket_num; seats_data.seat[j] -= ticket_num;
} }
@ -351,6 +353,61 @@ std::string TicketSystemEngine::RefundTicket(const std::string &command) {
response_stream << "[" << command_id << "] -1"; response_stream << "[" << command_id << "] -1";
return response_stream.str(); 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<std::pair<b_plus_tree_value_index_t, uint32_t>> 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"; response_stream << "[" << command_id << "] 0";
return response_stream.str(); return response_stream.str();
} }