write buy_ticket

This commit is contained in:
2024-05-24 15:09:34 +00:00
parent fc5a66eed7
commit dd0487e834
5 changed files with 81 additions and 10 deletions

View File

@ -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<const MinimalTrainRecord *>(&value_to)).vis_time_offset;
entry.to_stop_id = key_to.stop_id;
return entry;
success = true;
}
};

View File

@ -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<b_plus_tree_value_index_t> &res) {
std::vector<std::pair<b_plus_tree_value_index_t, uint32_t>> &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<b_plus_tree_value_index_t> &res) {
// warning: the validity of user_ID_hash is not checked
order_history_index_t order_history_index_for_query;

View File

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

View File

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

View File

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