From dd0487e834c5e328db06f4f3143c796431baba7a Mon Sep 17 00:00:00 2001 From: happyZYM Date: Fri, 24 May 2024 15:09:34 +0000 Subject: [PATCH] write buy_ticket --- src/include/stop_register.hpp | 13 ++++--- src/include/transaction_mainenance.hpp | 29 ++++++++++++++-- src/train_system.cpp | 1 + src/transaction_system.cpp | 47 +++++++++++++++++++++++++- src/user_system.cpp | 1 + 5 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/include/stop_register.hpp b/src/include/stop_register.hpp index ed62e06..3aa23bf 100644 --- a/src/include/stop_register.hpp +++ b/src/include/stop_register.hpp @@ -156,14 +156,14 @@ class StopRegister : public DataDriverBase { ++it_from; } } - inline StopRegister::DirectTrainInfo RequestSingleTrain(hash_t train_ID_hash, int date, hash_t from_station_hash, - hash_t to_station_hash, bool &success) { + inline void RequestSingleTrain(hash_t train_ID_hash, int date, hash_t from_station_hash, hash_t to_station_hash, + bool &success, StopRegister::DirectTrainInfo &entry) { const static int June_1st_2024 = 152; auto it_from = bpt_indexer->lower_bound_const({from_station_hash, train_ID_hash, 1}); auto it_to = bpt_indexer->lower_bound_const({to_station_hash, train_ID_hash, 0}); if (it_from == bpt_indexer->end_const() || it_to == bpt_indexer->end_const()) { success = false; - return {}; + return; } const auto &key_from = it_from.GetKey(); const auto &key_to = it_to.GetKey(); @@ -171,7 +171,7 @@ class StopRegister : public DataDriverBase { key_from.station_ID_hash != from_station_hash || key_to.station_ID_hash != to_station_hash || key_from.type != 1 || key_to.type != 0) { success = false; - return {}; + return; } const auto &value_from = it_from.GetValue(); const auto &value_to = it_to.GetValue(); @@ -183,9 +183,8 @@ class StopRegister : public DataDriverBase { int delta_days = actual_time / 1440; if (date - delta_days < true_saleDate_beg || date - delta_days > true_saleDate_end) { success = false; - return {}; + return; } - StopRegister::DirectTrainInfo entry; entry.train_ID_hash = key_from.train_ID_hash; entry.actual_start_date = date - delta_days; entry.leave_time_stamp = entry.actual_start_date * 1440 + actual_time; @@ -194,7 +193,7 @@ class StopRegister : public DataDriverBase { entry.arrive_time_stamp = entry.actual_start_date * 1440 + startTime + (*reinterpret_cast(&value_to)).vis_time_offset; entry.to_stop_id = key_to.stop_id; - return entry; + success = true; } }; diff --git a/src/include/transaction_mainenance.hpp b/src/include/transaction_mainenance.hpp index cee21e7..b399e7c 100644 --- a/src/include/transaction_mainenance.hpp +++ b/src/include/transaction_mainenance.hpp @@ -128,6 +128,22 @@ class TransactionManager : public DataDriverBase { queue_indexer->Flush(); order_history_indexer->Flush(); } + inline void PrepareTrainInfo(hash_t train_ID_hash, int total_days) { + queue_index_t queue_index_for_query; + queue_index_for_query.train_ID_hash = train_ID_hash; + queue_index_for_query.running_offset = 0; + queue_index_for_query.id = queue_index_specai_id; + for (int i = 0; i < total_days; i++) { + queue_index_for_query.running_offset = i; + queue_indexer->Put(queue_index_for_query, 0); + } + } + inline void PrepareUserInfo(hash_t user_ID_hash) { + order_history_index_t order_history_index_for_query; + order_history_index_for_query.user_ID_hash = user_ID_hash; + order_history_index_for_query.id = order_history_index_special_id; + order_history_indexer->Put(order_history_index_for_query, 0); + } 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) { @@ -174,7 +190,7 @@ class TransactionManager : public DataDriverBase { order_history_indexer->Put(order_history_index, data_id); } inline void FetchQueue(hash_t train_ID_hash, uint8_t running_date_offset, - std::vector &res) { + std::vector> &res) { // warning: the validity of train_ID_hash is not checked queue_index_t queue_index_for_query; queue_index_for_query.train_ID_hash = train_ID_hash; @@ -185,9 +201,18 @@ class TransactionManager : public DataDriverBase { res.resize(total_num); for (int i = 0; i < total_num; i++) { ++it; - res[i] = it.GetValue(); + res[i].first = it.GetValue(); + res[i].second = it.GetKey().id; } } + inline void RemoveOrderFromQueue(hash_t train_ID_hash, uint8_t running_date_offset, uint32_t id) { + // warning: the validity of train_ID_hash is not checked + queue_index_t queue_index_for_query; + queue_index_for_query.train_ID_hash = train_ID_hash; + queue_index_for_query.running_offset = running_date_offset; + queue_index_for_query.id = id; + queue_indexer->Remove(queue_index_for_query); + } inline void FetchFullUserOrderHistory(hash_t user_ID_hash, std::vector &res) { // warning: the validity of user_ID_hash is not checked order_history_index_t order_history_index_for_query; diff --git a/src/train_system.cpp b/src/train_system.cpp index c5dbea1..75b4099 100644 --- a/src/train_system.cpp +++ b/src/train_system.cpp @@ -273,6 +273,7 @@ std::string TicketSystemEngine::ReleaseTrain(const std::string &command) { core_train_data.saleDate_end, core_train_data.startTime, arrive_time_offset, leave_time_offset, i); } + transaction_manager.PrepareTrainInfo(train_id_hash, core_train_data.saleDate_end - core_train_data.saleDate_beg + 1); response_stream << '[' << command_id << "] 0"; return response_stream.str(); } diff --git a/src/transaction_system.cpp b/src/transaction_system.cpp index 89ac959..6293857 100644 --- a/src/transaction_system.cpp +++ b/src/transaction_system.cpp @@ -219,11 +219,56 @@ std::string TicketSystemEngine::BuyTicket(const std::string &command) { date, RetrieveReadableDate(date).first, RetrieveReadableDate(date).second, from, to, ticket_num, accept_queue); hash_t user_ID_hash = SplitMix64Hash(user_name); + hash_t train_ID_hash = SplitMix64Hash(train_id); if (online_users.find(user_ID_hash) == online_users.end()) { + LOG->debug("user {} not online", user_name); response_stream << "[" << command_id << "] -1"; return response_stream.str(); } - response_stream << "[" << command_id << "] BuyTicket"; + bool success = false; + StopRegister::DirectTrainInfo info; + hash_t from_station_hash = SplitMix64Hash(from), to_station_hash = SplitMix64Hash(to); + stop_register.RequestSingleTrain(train_ID_hash, date, from_station_hash, to_station_hash, success, info); + if (!success) { + LOG->debug("no train available"); + response_stream << "[" << command_id << "] -1"; + return response_stream.str(); + } + TicketPriceData ticket_price_data; + SeatsData seats_data; + int from_station_id = info.from_stop_id; + int to_station_id = info.to_stop_id; + int total_price = 0; + int available_seats = 0; + ticket_price_data_storage.Get(train_ID_hash, ticket_price_data); + seats_data_storage.Get({train_ID_hash, info.actual_start_date - info.saleDate_beg}, seats_data); + for (int j = from_station_id; j < to_station_id; j++) { + total_price += ticket_price_data.price[j]; + } + available_seats = seats_data.seat[from_station_id]; + for (int j = from_station_id + 1; j < to_station_id; j++) { + available_seats = std::min(available_seats, (int)seats_data.seat[j]); + } + if (ticket_num > available_seats) { + if (accept_queue == "false") { + LOG->debug("no enough seats"); + response_stream << "[" << command_id << "] -1"; + return response_stream.str(); + } + 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); + 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); + for (int j = from_station_id; j < to_station_id; j++) { + seats_data.seat[j] -= ticket_num; + } + seats_data_storage.Put({train_ID_hash, info.actual_start_date - info.saleDate_beg}, seats_data); + response_stream << "[" << command_id << "] " << total_price * (unsigned long long)ticket_num; return response_stream.str(); } diff --git a/src/user_system.cpp b/src/user_system.cpp index be327f3..e572bf7 100644 --- a/src/user_system.cpp +++ b/src/user_system.cpp @@ -58,6 +58,7 @@ std::string TicketSystemEngine::AddUser(const std::string &command) { strcpy(dat.name, name.c_str()); strcpy(dat.mailAddr, mailAddr.c_str()); user_data.Put(SplitMix64Hash(username), dat); + transaction_manager.PrepareUserInfo(SplitMix64Hash(username)); LOG->debug("stored user_name hash: {}", SplitMix64Hash(username)); LOG->debug("stored user_name: {}", dat.username); LOG->debug("stored password hash: {}", dat.password_hash);