ready to write transaction manager

This commit is contained in:
2024-05-24 13:27:09 +00:00
parent 698ff4069c
commit 4a9c47e03d
4 changed files with 181 additions and 3 deletions

View File

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

View File

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

View 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

View File

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