ready to write transaction manager
This commit is contained in:
@ -10,6 +10,7 @@
|
|||||||
#include "data.h"
|
#include "data.h"
|
||||||
#include "stop_register.hpp"
|
#include "stop_register.hpp"
|
||||||
#include "storage/disk_map.hpp"
|
#include "storage/disk_map.hpp"
|
||||||
|
#include "transaction_mainenance.hpp"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
class TicketSystemEngine {
|
class TicketSystemEngine {
|
||||||
#ifdef ENABLE_ADVANCED_FEATURE
|
#ifdef ENABLE_ADVANCED_FEATURE
|
||||||
@ -47,6 +48,7 @@ class TicketSystemEngine {
|
|||||||
* optimization, storing IDs pointing to order information
|
* optimization, storing IDs pointing to order information
|
||||||
*/
|
*/
|
||||||
StopRegister stop_register;
|
StopRegister stop_register;
|
||||||
|
TransactionManager transaction_manager;
|
||||||
|
|
||||||
void PrepareExit();
|
void PrepareExit();
|
||||||
|
|
||||||
@ -63,7 +65,9 @@ class TicketSystemEngine {
|
|||||||
core_train_data_storage("core_train.idx", data_directory + "/core_train.idx", "core_train.val",
|
core_train_data_storage("core_train.idx", data_directory + "/core_train.idx", "core_train.val",
|
||||||
data_directory + "/core_train.val"),
|
data_directory + "/core_train.val"),
|
||||||
seats_data_storage("seats.idx", data_directory + "/seats.idx", "seats.val", data_directory + "/seats.val"),
|
seats_data_storage("seats.idx", data_directory + "/seats.idx", "seats.val", data_directory + "/seats.val"),
|
||||||
stop_register("stop_register.idx", data_directory + "/stop_register.idx") {}
|
stop_register("stop_register.idx", data_directory + "/stop_register.idx"),
|
||||||
|
transaction_manager("txn.data", data_directory + "/txn.data", "queue.idx", data_directory + "/queue.idx",
|
||||||
|
"order.idx", data_directory + "/order.idx") {}
|
||||||
std::string Execute(const std::string &command);
|
std::string Execute(const std::string &command);
|
||||||
|
|
||||||
// User system
|
// User system
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "storage/bpt.hpp"
|
#include "storage/bpt.hpp"
|
||||||
#include "storage/buffer_pool_manager.h"
|
#include "storage/buffer_pool_manager.h"
|
||||||
#include "storage/driver.h"
|
#include "storage/driver.h"
|
||||||
|
#include "utils.h"
|
||||||
struct stop_register_t {
|
struct stop_register_t {
|
||||||
hash_t station_ID_hash;
|
hash_t station_ID_hash;
|
||||||
hash_t train_ID_hash;
|
hash_t train_ID_hash;
|
||||||
@ -155,6 +156,46 @@ class StopRegister : public DataDriverBase {
|
|||||||
++it_from;
|
++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) {
|
||||||
|
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 {};
|
||||||
|
}
|
||||||
|
const auto &key_from = it_from.GetKey();
|
||||||
|
const auto &key_to = it_to.GetKey();
|
||||||
|
if (key_from.train_ID_hash != train_ID_hash || key_to.train_ID_hash != train_ID_hash ||
|
||||||
|
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 {};
|
||||||
|
}
|
||||||
|
const auto &value_from = it_from.GetValue();
|
||||||
|
const auto &value_to = it_to.GetValue();
|
||||||
|
int true_saleDate_beg = (*reinterpret_cast<const MinimalTrainRecord *>(&value_from)).saleDate_beg + June_1st_2024;
|
||||||
|
int true_saleDate_end = (*reinterpret_cast<const MinimalTrainRecord *>(&value_from)).saleDate_end + June_1st_2024;
|
||||||
|
int leave_time_offset = (*reinterpret_cast<const MinimalTrainRecord *>(&value_from)).vis_time_offset;
|
||||||
|
int startTime = key_from.startTime;
|
||||||
|
int actual_time = startTime + leave_time_offset;
|
||||||
|
int delta_days = actual_time / 1440;
|
||||||
|
if (date - delta_days < true_saleDate_beg || date - delta_days > true_saleDate_end) {
|
||||||
|
success = false;
|
||||||
|
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;
|
||||||
|
entry.from_stop_id = key_from.stop_id;
|
||||||
|
entry.saleDate_beg = true_saleDate_beg;
|
||||||
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
130
src/include/transaction_mainenance.hpp
Normal file
130
src/include/transaction_mainenance.hpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#ifndef TRANSACTION_MAINTENANCE_HPP
|
||||||
|
#define TRANSACTION_MAINTENANCE_HPP
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
#include "basic_defs.h"
|
||||||
|
#include "data.h"
|
||||||
|
#include "storage/bpt.hpp"
|
||||||
|
#include "storage/buffer_pool_manager.h"
|
||||||
|
#include "storage/disk_manager.h"
|
||||||
|
#include "storage/driver.h"
|
||||||
|
#include "storage/single_value_storage.hpp"
|
||||||
|
struct TransactionData {
|
||||||
|
char trainID[21];
|
||||||
|
char from_station_name[41];
|
||||||
|
char to_station_name[41];
|
||||||
|
uint8_t status;
|
||||||
|
uint32_t leave_time_stamp;
|
||||||
|
uint32_t arrive_time_stamp;
|
||||||
|
uint32_t num;
|
||||||
|
uint64_t total_price;
|
||||||
|
};
|
||||||
|
class TransactionManager : public DataDriverBase {
|
||||||
|
struct queue_index_t {
|
||||||
|
hash_t train_ID_hash;
|
||||||
|
uint8_t running_offset;
|
||||||
|
uint32_t id;
|
||||||
|
inline bool operator<(const queue_index_t &rhs) const {
|
||||||
|
if (train_ID_hash != rhs.train_ID_hash) return train_ID_hash < rhs.train_ID_hash;
|
||||||
|
if (running_offset != rhs.running_offset) return running_offset < rhs.running_offset;
|
||||||
|
return id < rhs.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct order_history_index_t {
|
||||||
|
hash_t user_ID_hash;
|
||||||
|
uint32_t id;
|
||||||
|
inline bool operator<(const order_history_index_t &rhs) const {
|
||||||
|
if (user_ID_hash != rhs.user_ID_hash) return user_ID_hash < rhs.user_ID_hash;
|
||||||
|
return id > rhs.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static const uint32_t queue_index_specai_id = 0;
|
||||||
|
static const uint32_t order_history_index_special_id = -1;
|
||||||
|
std::string data_file_identifier;
|
||||||
|
std::string data_file_path;
|
||||||
|
DiskManager *data_disk_manager;
|
||||||
|
BufferPoolManager *data_bpm;
|
||||||
|
SingleValueStorage<TransactionData> *data_storage;
|
||||||
|
std::string queue_file_identifier;
|
||||||
|
std::string queue_file_path;
|
||||||
|
DiskManager *queue_disk_manager;
|
||||||
|
BufferPoolManager *queue_bpm;
|
||||||
|
BPlusTreeIndexer<queue_index_t, std::less<queue_index_t>> *queue_indexer;
|
||||||
|
std::string order_history_file_identifier;
|
||||||
|
std::string order_history_file_path;
|
||||||
|
DiskManager *order_history_disk_manager;
|
||||||
|
BufferPoolManager *order_history_bpm;
|
||||||
|
BPlusTreeIndexer<order_history_index_t, std::less<order_history_index_t>> *order_history_indexer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// for satety, all the copy/move operations are deleted, please manage it using pointer
|
||||||
|
inline TransactionManager(TransactionManager &&) = delete;
|
||||||
|
inline TransactionManager &operator=(TransactionManager &&) = delete;
|
||||||
|
inline TransactionManager(const TransactionManager &) = delete;
|
||||||
|
inline TransactionManager &operator=(const TransactionManager &) = delete;
|
||||||
|
inline TransactionManager(std::string data_file_identifier_, std::string data_file_path_,
|
||||||
|
std::string queue_file_identifier_, std::string queue_file_path_,
|
||||||
|
std::string order_history_file_identifier_, std::string order_history_file_path_)
|
||||||
|
: data_file_identifier(std::move(data_file_identifier_)),
|
||||||
|
data_file_path(std::move(data_file_path_)),
|
||||||
|
queue_file_identifier(std::move(queue_file_identifier_)),
|
||||||
|
queue_file_path(std::move(queue_file_path_)),
|
||||||
|
order_history_file_identifier(std::move(order_history_file_identifier_)),
|
||||||
|
order_history_file_path(std::move(order_history_file_path_)) {
|
||||||
|
data_disk_manager = new DiskManager(data_file_path);
|
||||||
|
data_bpm = new BufferPoolManager(100, 5, data_disk_manager);
|
||||||
|
data_storage = new SingleValueStorage<TransactionData>(data_bpm);
|
||||||
|
queue_disk_manager = new DiskManager(queue_file_path);
|
||||||
|
queue_bpm = new BufferPoolManager(100, 5, queue_disk_manager);
|
||||||
|
queue_indexer = new BPlusTreeIndexer<queue_index_t, std::less<queue_index_t>>(queue_bpm);
|
||||||
|
order_history_disk_manager = new DiskManager(order_history_file_path);
|
||||||
|
order_history_bpm = new BufferPoolManager(100, 5, order_history_disk_manager);
|
||||||
|
order_history_indexer =
|
||||||
|
new BPlusTreeIndexer<order_history_index_t, std::less<order_history_index_t>>(order_history_bpm);
|
||||||
|
}
|
||||||
|
inline ~TransactionManager() {
|
||||||
|
delete data_storage;
|
||||||
|
delete data_bpm;
|
||||||
|
delete data_disk_manager;
|
||||||
|
delete queue_indexer;
|
||||||
|
delete queue_bpm;
|
||||||
|
delete queue_disk_manager;
|
||||||
|
delete order_history_indexer;
|
||||||
|
delete order_history_bpm;
|
||||||
|
delete order_history_disk_manager;
|
||||||
|
}
|
||||||
|
inline virtual sjtu::vector<FileEntry> ListFiles() override {
|
||||||
|
sjtu::vector<FileEntry> res;
|
||||||
|
res.push_back({data_file_identifier, data_file_path, data_disk_manager});
|
||||||
|
res.push_back({queue_file_identifier, queue_file_path, queue_disk_manager});
|
||||||
|
res.push_back({order_history_file_identifier, order_history_file_path, order_history_disk_manager});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
inline virtual void LockDownForCheckOut() override {
|
||||||
|
delete data_storage;
|
||||||
|
delete data_bpm;
|
||||||
|
delete data_disk_manager;
|
||||||
|
data_storage = nullptr;
|
||||||
|
data_bpm = nullptr;
|
||||||
|
data_disk_manager = nullptr;
|
||||||
|
delete queue_indexer;
|
||||||
|
delete queue_bpm;
|
||||||
|
delete queue_disk_manager;
|
||||||
|
queue_indexer = nullptr;
|
||||||
|
queue_bpm = nullptr;
|
||||||
|
queue_disk_manager = nullptr;
|
||||||
|
delete order_history_indexer;
|
||||||
|
delete order_history_bpm;
|
||||||
|
delete order_history_disk_manager;
|
||||||
|
order_history_indexer = nullptr;
|
||||||
|
order_history_bpm = nullptr;
|
||||||
|
order_history_disk_manager = nullptr;
|
||||||
|
}
|
||||||
|
inline virtual void Flush() override {
|
||||||
|
if (data_storage == nullptr) return;
|
||||||
|
data_storage->Flush();
|
||||||
|
queue_indexer->Flush();
|
||||||
|
order_history_indexer->Flush();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
@ -48,7 +48,6 @@ std::string TicketSystemEngine::QueryTicket(const std::string &command) {
|
|||||||
}
|
}
|
||||||
LOG->debug("date {}={}-{}, from {}, to {}, order by {}", date, RetrieveReadableDate(date).first,
|
LOG->debug("date {}={}-{}, from {}, to {}, order by {}", date, RetrieveReadableDate(date).first,
|
||||||
RetrieveReadableDate(date).second, from, to, order_by);
|
RetrieveReadableDate(date).second, from, to, order_by);
|
||||||
// TODO
|
|
||||||
hash_t from_hash = SplitMix64Hash(from), to_hash = SplitMix64Hash(to);
|
hash_t from_hash = SplitMix64Hash(from), to_hash = SplitMix64Hash(to);
|
||||||
std::vector<StopRegister::DirectTrainInfo> valid_trains;
|
std::vector<StopRegister::DirectTrainInfo> valid_trains;
|
||||||
stop_register.QueryDirectTrains(date, from_hash, to_hash, valid_trains);
|
stop_register.QueryDirectTrains(date, from_hash, to_hash, valid_trains);
|
||||||
@ -219,7 +218,11 @@ std::string TicketSystemEngine::BuyTicket(const std::string &command) {
|
|||||||
LOG->debug("user {}, train {}, date {}={}-{}, from {}, to {}, ticket num {}, accept queue {}", user_name, train_id,
|
LOG->debug("user {}, train {}, date {}={}-{}, from {}, to {}, ticket num {}, accept queue {}", user_name, train_id,
|
||||||
date, RetrieveReadableDate(date).first, RetrieveReadableDate(date).second, from, to, ticket_num,
|
date, RetrieveReadableDate(date).first, RetrieveReadableDate(date).second, from, to, ticket_num,
|
||||||
accept_queue);
|
accept_queue);
|
||||||
// TODO
|
hash_t user_ID_hash = SplitMix64Hash(user_name);
|
||||||
|
if (online_users.find(user_ID_hash) == online_users.end()) {
|
||||||
|
response_stream << "[" << command_id << "] -1";
|
||||||
|
return response_stream.str();
|
||||||
|
}
|
||||||
response_stream << "[" << command_id << "] BuyTicket";
|
response_stream << "[" << command_id << "] BuyTicket";
|
||||||
return response_stream.str();
|
return response_stream.str();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user