half way of query_transfer

This commit is contained in:
2024-05-25 05:33:07 +00:00
parent 8cc179a0c2
commit 140d0fb0ec
4 changed files with 217 additions and 3 deletions

View File

@ -162,11 +162,165 @@ std::string TicketSystemEngine::QueryTransfer(const std::string &command) {
}
LOG->debug("date {}={}-{}, from {}, to {}, order by {}", date, RetrieveReadableDate(date).first,
RetrieveReadableDate(date).second, from, to, order_by);
// TODO
response_stream << "[" << command_id << "] 0";
bool has_solution = false;
std::vector<hash_t> trains_leaving_from_from;
std::vector<hash_t> trains_arriving_at_dest;
hash_t from_station_hash = SplitMix64Hash(from), to_station_hash = SplitMix64Hash(to);
stop_register.FetchTrainLeavingFrom(date, from_station_hash, trains_leaving_from_from);
stop_register.FetchTrainArriavingAt(date, to_station_hash, trains_arriving_at_dest);
LOG->debug("now we need to check {} * {} possible solutions", trains_leaving_from_from.size(),
trains_arriving_at_dest.size());
std::string train1_id, train2_id;
std::string transfer_station_id;
int train1_leaving_time_stamp, train1_arriving_time_stamp;
int train2_leaving_time_stamp, train2_arriving_time_stamp;
int train1_price, train1_seats;
int train2_price, train2_seats;
const size_t len_1 = trains_leaving_from_from.size(), len_2 = trains_arriving_at_dest.size();
for (size_t i = 0; i < len_1; i++) {
for (size_t j = 0; j < len_2; j++) {
CheckTransfer(trains_leaving_from_from[i], trains_arriving_at_dest[j], from, to, date, has_solution, train1_id,
train2_id, train1_leaving_time_stamp, train1_arriving_time_stamp, train2_leaving_time_stamp,
train2_arriving_time_stamp, train1_price, train1_seats, train2_price, train2_seats,
transfer_station_id);
}
}
if (!has_solution) {
response_stream << "[" << command_id << "] 0";
return response_stream.str();
}
response_stream << '[' << command_id << "] ";
response_stream << train1_id << " " << from << " ";
PrintFullTimeStamp(train1_leaving_time_stamp, response_stream);
response_stream << " -> " << transfer_station_id << " ";
PrintFullTimeStamp(train1_arriving_time_stamp, response_stream);
response_stream << " " << train1_price << " " << train1_seats << '\n';
response_stream << train2_id << " " << transfer_station_id << " ";
PrintFullTimeStamp(train2_leaving_time_stamp, response_stream);
response_stream << " -> " << to << " ";
PrintFullTimeStamp(train2_arriving_time_stamp, response_stream);
response_stream << " " << train2_price << " " << train2_seats;
return response_stream.str();
}
void TicketSystemEngine::CheckTransfer(hash_t train1_ID_hash, hash_t train2_ID_hash, const std::string &from_station,
const std::string &to_station, int date, bool &has_solution,
std::string &res_train1_id, std::string &res_train2_id,
int &res_train1_leaving_time_stamp, int &res_train1_arriving_time_stamp,
int &res_train2_leaving_time_stamp, int &res_train2_arriving_time_stamp,
int &res_train1_price, int &res_train1_seat, int &res_train2_price,
int &res_train2_seat, std::string &res_transfer_station_name) {
std::map<hash_t, int> transfer_mp;
hash_t from_station_hash = SplitMix64Hash(from_station), to_station_hash = SplitMix64Hash(to_station);
CoreTrainData train1_core_data, train2_core_data;
core_train_data_storage.Get(train1_ID_hash, train1_core_data);
core_train_data_storage.Get(train2_ID_hash, train2_core_data);
TicketPriceData train1_price_data, train2_price_data;
ticket_price_data_storage.Get(train1_ID_hash, train1_price_data);
ticket_price_data_storage.Get(train2_ID_hash, train2_price_data);
int train1_price_sum[100] = {0}, train2_price_sum[100] = {0};
for (int i = 1; i < train1_core_data.stationNum; i++) {
train1_price_sum[i] = train1_price_sum[i - 1] + train1_price_data.price[i - 1];
}
for (int i = 1; i < train2_core_data.stationNum; i++) {
train2_price_sum[i] = train2_price_sum[i - 1] + train2_price_data.price[i - 1];
}
int train1_arrive_time_offeset[100] = {0}, train1_leave_time_offset[100] = {0};
int train2_arrive_time_offeset[100] = {0}, train2_leave_time_offset[100] = {0};
for (int i = 1; i < train1_core_data.stationNum; i++) {
train1_arrive_time_offeset[i] = train1_leave_time_offset[i - 1] + train1_core_data.travelTime[i - 1];
train1_leave_time_offset[i] = train1_arrive_time_offeset[i] + train1_core_data.stopoverTime[i];
}
for (int i = 1; i < train2_core_data.stationNum; i++) {
train2_arrive_time_offeset[i] = train2_leave_time_offset[i - 1] + train2_core_data.travelTime[i - 1];
train2_leave_time_offset[i] = train2_arrive_time_offeset[i] + train2_core_data.stopoverTime[i];
}
bool has_meet_begin_station = false;
int start_station_offset = 0;
for (int i = 0; i < train1_core_data.stationNum; i++) {
if (train1_core_data.stations_hash[i] == from_station_hash) {
has_meet_begin_station = true;
start_station_offset = i;
continue;
}
if (has_meet_begin_station) {
transfer_mp[train1_core_data.stations_hash[i]] = i;
}
}
bool has_meet_end_station = false;
int dest_station_offset = 0;
for (int i = train2_core_data.stationNum - 1; i >= 0; i--) {
if (train2_core_data.stations_hash[i] == to_station_hash) {
has_meet_end_station = true;
dest_station_offset = i;
continue;
}
LOG->debug("start_station_offset {} dest_station_offset {}", start_station_offset, dest_station_offset);
if (has_meet_end_station && transfer_mp.find(train2_core_data.stations_hash[i]) != transfer_mp.end()) {
int transfer_station_offset = transfer_mp[train2_core_data.stations_hash[i]];
int train1_actual_time = train1_core_data.startTime + train1_leave_time_offset[start_station_offset];
int train1_delta_days = train1_actual_time / 1440;
int train1_actual_start_date = date - train1_delta_days;
if (train1_actual_start_date < train1_core_data.saleDate_beg ||
train1_actual_start_date > train1_core_data.saleDate_end) {
throw std::runtime_error("there are mistakes in StopRegister::FetchTrainLeavingFrom");
}
int cur_train1_leaving_time_stamp = train1_actual_start_date * 1440 + train1_actual_time;
int cur_train1_arriving_time_stamp = train1_actual_start_date * 1440 + train1_core_data.startTime +
train1_arrive_time_offeset[transfer_station_offset];
int train2_earliest_leaving_time_stamp =
train2_core_data.saleDate_beg * 1440 + train2_core_data.startTime + train2_leave_time_offset[i];
int train2_latest_leaving_time_stamp =
train2_core_data.saleDate_end * 1440 + train2_core_data.startTime + train2_leave_time_offset[i];
if (cur_train1_arriving_time_stamp > train2_latest_leaving_time_stamp) {
continue;
}
std::stringstream test_buf;
PrintFullTimeStamp(train2_earliest_leaving_time_stamp, test_buf);
LOG->debug("train2_earliest_leaving_time_stamp: {}", test_buf.str());
int cur_train2_leaving_time_stamp = train2_earliest_leaving_time_stamp;
if (cur_train2_leaving_time_stamp < cur_train1_arriving_time_stamp) {
int delta_count = (cur_train1_arriving_time_stamp - cur_train2_leaving_time_stamp + 1440 - 1) / 1440;
cur_train2_leaving_time_stamp += delta_count * 1440;
}
int cur_train2_arriving_time_stamp =
cur_train2_leaving_time_stamp + train2_arrive_time_offeset[dest_station_offset] - train2_leave_time_offset[i];
if (!has_solution) {
// just copy the first solution
has_solution = true;
res_train1_id = train1_price_data.trainID;
res_train2_id = train2_price_data.trainID;
res_train1_leaving_time_stamp = cur_train1_leaving_time_stamp;
res_train1_arriving_time_stamp = cur_train1_arriving_time_stamp;
res_train2_leaving_time_stamp = cur_train2_leaving_time_stamp;
res_train2_arriving_time_stamp = cur_train2_arriving_time_stamp;
res_train1_price = train1_price_sum[transfer_station_offset] - train1_price_sum[start_station_offset];
res_train2_price = train2_price_sum[dest_station_offset] - train2_price_sum[i];
StationNameData station_name_data;
station_name_data_storage.Get(train1_ID_hash, station_name_data);
auto &str = station_name_data.name[transfer_station_offset];
res_transfer_station_name = "";
for (int i = 0; i < 40 && str[i] != '\0'; i++) res_transfer_station_name.push_back(str[i]);
SeatsData train1_seats_data, train2_seats_data;
seats_data_storage.Get({train1_ID_hash, train1_actual_start_date - train1_core_data.saleDate_beg},
train1_seats_data);
int train2_actual_start_date = cur_train2_leaving_time_stamp / 1440;
seats_data_storage.Get({train2_ID_hash, train2_actual_start_date - train2_core_data.saleDate_beg},
train2_seats_data);
res_train1_seat = train1_seats_data.seat[start_station_offset];
for (int j = start_station_offset + 1; j < transfer_station_offset; j++) {
res_train1_seat = std::min(res_train1_seat, (int)train1_seats_data.seat[j]);
}
res_train2_seat = train2_seats_data.seat[i];
for (int j = i + 1; j < dest_station_offset; j++) {
res_train2_seat = std::min(res_train2_seat, (int)train2_seats_data.seat[j]);
}
return;
}
}
}
}
std::string TicketSystemEngine::BuyTicket(const std::string &command) {
command_id_t command_id;
sscanf(command.c_str(), "[%llu]", &command_id);