From 5ae88e33120005709e51c0022d2e6719465d5260 Mon Sep 17 00:00:00 2001 From: happyZYM Date: Tue, 21 May 2024 06:35:55 +0000 Subject: [PATCH] setting up structure --- src/CMakeLists.txt | 2 +- src/data.cpp | 1 + src/engine.cpp | 130 +++++++++++++++++++++++++++++++++++++++ src/include/basic_defs.h | 6 +- src/include/data.h | 4 ++ src/include/engine.h | 47 ++++++++++++++ src/include/utils.h | 59 ++++++++++++++++++ src/main.cpp | 24 ++++++-- src/utils.cpp | 1 + test/ojtest.py | 9 ++- 10 files changed, 274 insertions(+), 9 deletions(-) create mode 100644 src/data.cpp create mode 100644 src/engine.cpp create mode 100644 src/include/data.h create mode 100644 src/include/engine.h create mode 100644 src/include/utils.h create mode 100644 src/utils.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5bd4765..b6da90d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ set(BACKEND_EXETUABLE_NAME "zts-core") if(OJ_TEST_BACKEND) set(BACKEND_EXETUABLE_NAME "code") endif() -add_executable(${BACKEND_EXETUABLE_NAME} main.cpp) +add_executable(${BACKEND_EXETUABLE_NAME} main.cpp engine.cpp utils.cpp data.cpp) target_link_libraries(${BACKEND_EXETUABLE_NAME} argparse) target_link_libraries(${BACKEND_EXETUABLE_NAME} spdlog::spdlog) target_link_libraries(${BACKEND_EXETUABLE_NAME} sockpp) diff --git a/src/data.cpp b/src/data.cpp new file mode 100644 index 0000000..16e183e --- /dev/null +++ b/src/data.cpp @@ -0,0 +1 @@ +#include "data.h" \ No newline at end of file diff --git a/src/engine.cpp b/src/engine.cpp new file mode 100644 index 0000000..52e83a1 --- /dev/null +++ b/src/engine.cpp @@ -0,0 +1,130 @@ +#include "engine.h" +#include +#include +#include +#include +#include "basic_defs.h" +#include "utils.h" +const hash_t add_user_hash = 1294763820278197867ull; // SplitMix64Hash(std::string_view("add_user")); +const hash_t login_hash = 2711532776857333909ull; // SplitMix64Hash(std::string_view("login")); +const hash_t logout_hash = 654844766916416630ull; // SplitMix64Hash(std::string_view("logout")); +const hash_t query_profile_hash = 2497292575416072607ull; // SplitMix64Hash(std::string_view("query_profile")); +const hash_t modify_profile_hash = 11664297803074461165ull; // SplitMix64Hash(std::string_view("modify_profile")); +const hash_t add_train_hash = 4928024213250587878ull; // SplitMix64Hash(std::string_view("add_train")); +const hash_t delete_train_hash = 13574898832952622188ull; // SplitMix64Hash(std::string_view("delete_train")); +const hash_t release_train_hash = 3024733565973464225ull; // SplitMix64Hash(std::string_view("release_train")); +const hash_t query_train_hash = 8200860784912964124ull; // SplitMix64Hash(std::string_view("query_train")); +const hash_t query_ticket_hash = 11565392281772224130ull; // SplitMix64Hash(std::string_view("query_ticket")); +const hash_t query_transfer_hash = 17604853834584868005ull; // SplitMix64Hash(std::string_view("query_transfer")); +const hash_t buy_ticket_hash = 16906761384093040506ull; // SplitMix64Hash(std::string_view("buy_ticket")); +const hash_t query_order_hash = 8097745745927766409ull; // SplitMix64Hash(std::string_view("query_order")); +const hash_t refund_ticket_hash = 14136625827132030759ull; // SplitMix64Hash(std::string_view("refund_ticket")); +const hash_t clean_hash = 13563833734274431010ull; // SplitMix64Hash(std::string_view("clean")); +const hash_t exit_hash = 5825494509148032335ull; // SplitMix64Hash(std::string_view("exit")); +std::string TicketSystemEngine::Execute(const std::string &command) { + // LOG->debug("add_user_hash: {}", add_user_hash); + // LOG->debug("login_hash: {}", login_hash); + // LOG->debug("logout_hash: {}", logout_hash); + // LOG->debug("query_profile_hash: {}", query_profile_hash); + // LOG->debug("modify_profile_hash: {}", modify_profile_hash); + // LOG->debug("add_train_hash: {}", add_train_hash); + // LOG->debug("delete_train_hash: {}", delete_train_hash); + // LOG->debug("release_train_hash: {}", release_train_hash); + // LOG->debug("query_train_hash: {}", query_train_hash); + // LOG->debug("query_ticket_hash: {}", query_ticket_hash); + // LOG->debug("query_transfer_hash: {}", query_transfer_hash); + // LOG->debug("buy_ticket_hash: {}", buy_ticket_hash); + // LOG->debug("query_order_hash: {}", query_order_hash); + // LOG->debug("refund_ticket_hash: {}", refund_ticket_hash); + // LOG->debug("clean_hash: {}", clean_hash); + // LOG->debug("exit_hash: {}", exit_hash); + char command_name[20]; + sscanf(command.c_str(), "%s", command_name); + hash_t command_name_hash = SplitMix64Hash(std::string_view(command_name)); + switch (command_name_hash) { + case add_user_hash: + LOG->debug("match add_user"); + return std::move(AddUser(command)); + case login_hash: + LOG->debug("match login"); + return std::move(LoginUser(command)); + case logout_hash: + LOG->debug("match logout"); + return std::move(LogoutUser(command)); + case query_profile_hash: + LOG->debug("match query_profile"); + return std::move(QueryProfile(command)); + case modify_profile_hash: + LOG->debug("match modify_profile"); + return std::move(ModifyProfile(command)); + case add_train_hash: + LOG->debug("match add_train"); + return std::move(AddTrain(command)); + case delete_train_hash: + LOG->debug("match delete_train"); + return std::move(DeleteTrain(command)); + case release_train_hash: + LOG->debug("match release_train"); + return std::move(ReleaseTrain(command)); + case query_train_hash: + LOG->debug("match query_train"); + return std::move(QueryTrain(command)); + case query_ticket_hash: + LOG->debug("match query_ticket"); + return std::move(QueryTicket(command)); + case query_transfer_hash: + LOG->debug("match query_transfer"); + return std::move(QueryTransfer(command)); + case buy_ticket_hash: + LOG->debug("match buy_ticket"); + return std::move(BuyTicket(command)); + case query_order_hash: + LOG->debug("match query_order"); + return std::move(QueryOrder(command)); + case refund_ticket_hash: + LOG->debug("match refund_ticket_hash"); + return std::move(RefundTicket(command)); + case clean_hash: + LOG->debug("match clean"); + return std::move(Clean()); + case exit_hash: + LOG->debug("match exit"); + PrepareExit(); + return std::move(Exit()); + } + throw std::invalid_argument("Invalid command."); +} + +std::string TicketSystemEngine::AddUser(const std::string &command) { return "AddUser"; } + +std::string TicketSystemEngine::LoginUser(const std::string &command) { return "LoginUser"; } + +std::string TicketSystemEngine::LogoutUser(const std::string &command) { return "LogoutUser"; } + +std::string TicketSystemEngine::QueryProfile(const std::string &command) { return "QueryProfile"; } + +std::string TicketSystemEngine::ModifyProfile(const std::string &command) { return "ModifyProfile"; } + +std::string TicketSystemEngine::AddTrain(const std::string &command) { return "AddTrain"; } + +std::string TicketSystemEngine::DeleteTrain(const std::string &command) { return "DeleteTrain"; } + +std::string TicketSystemEngine::ReleaseTrain(const std::string &command) { return "ReleaseTrain"; } + +std::string TicketSystemEngine::QueryTrain(const std::string &command) { return "QueryTrain"; } + +std::string TicketSystemEngine::BuyTicket(const std::string &command) { return "BuyTicket"; } + +std::string TicketSystemEngine::QueryOrder(const std::string &command) { return "QueryOrder"; } + +std::string TicketSystemEngine::RefundTicket(const std::string &command) { return "RefundTicket"; } + +std::string TicketSystemEngine::QueryTransfer(const std::string &command) { return "QueryTransfer"; } + +std::string TicketSystemEngine::QueryTicket(const std::string &command) { return "QueryTicket"; } + +std::string TicketSystemEngine::Clean() { return "Clean"; } + +std::string TicketSystemEngine::Exit() { return "bye"; } + +void TicketSystemEngine::PrepareExit() { LOG->info("Preparing exit"); } \ No newline at end of file diff --git a/src/include/basic_defs.h b/src/include/basic_defs.h index f84797e..977c360 100644 --- a/src/include/basic_defs.h +++ b/src/include/basic_defs.h @@ -10,7 +10,11 @@ extern const std::string main_version; extern const std::string build_version; extern std::shared_ptr logger_ptr; -extern const bool global_log_enabled; +#ifndef ENABLE_ADVANCED_FEATURE +constexpr bool global_log_enabled = false; +#else +constexpr bool global_log_enabled = true; +#endif extern const bool optimize_enabled; #define LOG if constexpr (global_log_enabled) if (logger_ptr) logger_ptr #endif \ No newline at end of file diff --git a/src/include/data.h b/src/include/data.h new file mode 100644 index 0000000..9f55c6e --- /dev/null +++ b/src/include/data.h @@ -0,0 +1,4 @@ +#ifndef DATA_H +#define DATA_H + +#endif \ No newline at end of file diff --git a/src/include/engine.h b/src/include/engine.h new file mode 100644 index 0000000..d311c0b --- /dev/null +++ b/src/include/engine.h @@ -0,0 +1,47 @@ +#ifndef ENGINE_H +#define ENGINE_H +#include +#include +#ifdef ENABLE_ADVANCED_FEATURE +#include "dataguard/dataguard.h" +#include "dataguard/snapshot.h" +#endif +#include +#include "utils.h" +class TicketSystemEngine { +#ifdef ENABLE_ADVANCED_FEATURE + SnapShotManager snapshot_manager; +#endif + std::string data_directory; + std::map online_users; + void PrepareExit(); + + public: + inline TicketSystemEngine(std::string data_directory) : data_directory(data_directory) {} + std::string Execute(const std::string &command); + + // 用户相关函数 + std::string AddUser(const std::string &command); + std::string LoginUser(const std::string &command); + std::string LogoutUser(const std::string &command); + std::string QueryProfile(const std::string &command); + std::string ModifyProfile(const std::string &command); + + // 车次相关函数 + std::string AddTrain(const std::string &command); + std::string DeleteTrain(const std::string &command); + std::string ReleaseTrain(const std::string &command); + std::string QueryTrain(const std::string &command); + + // 订单相关函数 + std::string BuyTicket(const std::string &command); + std::string QueryOrder(const std::string &command); + std::string RefundTicket(const std::string &command); + + // 其他函数 + std::string QueryTransfer(const std::string &command); + std::string QueryTicket(const std::string &command); + std::string Clean(); + std::string Exit(); +}; +#endif \ No newline at end of file diff --git a/src/include/utils.h b/src/include/utils.h new file mode 100644 index 0000000..4c21022 --- /dev/null +++ b/src/include/utils.h @@ -0,0 +1,59 @@ +#ifndef UTILS_H +#define UTILS_H +#include +#include +#include +typedef uint64_t hash_t; +inline hash_t SplitMix64Hash(const std::string &str) noexcept { + // constexpr static char salt1[10] = "mL;]-=eT"; + // constexpr static char salt2[10] = "9B(str.c_str() + i); + ret ^= *reinterpret_cast(inner_salt + (i & 15)); + ret += 0x9e3779b97f4a7c15; + ret = (ret ^ (ret >> 30)) * 0xbf58476d1ce4e5b9; + ret = (ret ^ (ret >> 27)) * 0x94d049bb133111eb; + ret ^= ret >> 31; + } + for (; i < str.length(); ++i) { + ret ^= str[i]; + ret ^= inner_salt[i & 15]; + ret += 0x9e3779b97f4a7c15; + ret = (ret ^ (ret >> 30)) * 0xbf58476d1ce4e5b9; + ret = (ret ^ (ret >> 27)) * 0x94d049bb133111eb; + ret ^= ret >> 31; + } + return ret; +} +inline hash_t SplitMix64Hash(const std::string_view &str) noexcept { + // constexpr static char salt1[10] = "mL;]-=eT"; + // constexpr static char salt2[10] = "9B(str.data() + i); + ret ^= *reinterpret_cast(inner_salt + (i & 15)); + ret += 0x9e3779b97f4a7c15; + ret = (ret ^ (ret >> 30)) * 0xbf58476d1ce4e5b9; + ret = (ret ^ (ret >> 27)) * 0x94d049bb133111eb; + ret ^= ret >> 31; + } + for (; i < str.length(); ++i) { + ret ^= str[i]; + ret ^= inner_salt[i & 15]; + ret += 0x9e3779b97f4a7c15; + ret = (ret ^ (ret >> 30)) * 0xbf58476d1ce4e5b9; + ret = (ret ^ (ret >> 27)) * 0x94d049bb133111eb; + ret ^= ret >> 31; + } + return ret; +} +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 58cd14f..677ceef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,8 @@ #include #include "basic_defs.h" -#include "storage/bpt.hpp" #include "dataguard/dataguard.h" +#include "engine.h" +#include "storage/bpt.hpp" const std::string main_version = "0.0.1"; const std::string build_version = GIT_COMMIT_HASH; std::shared_ptr logger_ptr; @@ -10,11 +11,11 @@ const bool optimize_enabled = __OPTIMIZE__; #else const bool optimize_enabled = false; #endif -#ifndef ENABLE_ADVANCED_FEATURE -const bool global_log_enabled = false; -#else -const bool global_log_enabled = true; -#endif +// #ifndef ENABLE_ADVANCED_FEATURE +// const bool global_log_enabled = false; +// #else +// const bool global_log_enabled = true; +// #endif int main(int argc, char *argv[]) { argparse::ArgumentParser program("core-cli", main_version + "-" + build_version); argparse::ArgumentParser fsck_command("fsck"); @@ -92,6 +93,17 @@ int main(int argc, char *argv[]) { return 1; } else LOG->info("successfully bind to address {} port {}", address, port); + throw std::runtime_error("Server mode not implemented"); + } else { + std::ios::sync_with_stdio(false); + std::cin.tie(nullptr); + std::cout.tie(nullptr); + TicketSystemEngine engine(data_directory); + std::string cmd; + while (std::getline(std::cin, cmd)) { + std::cout << engine.Execute(cmd) << '\n'; + std::cout.flush(); + } } return 0; } \ No newline at end of file diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..cab9269 --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1 @@ +#include "utils.h" \ No newline at end of file diff --git a/test/ojtest.py b/test/ojtest.py index 0387adb..61dd407 100755 --- a/test/ojtest.py +++ b/test/ojtest.py @@ -40,11 +40,14 @@ elif argc>=2: skip_check=False ignore_first_dependency=False +enable_tested_program_logging=False for i in range(argc): if argv[i]=="--skip-check": skip_check=True if argv[i]=="--ignore-first-dependency": ignore_first_dependency=True + if argv[i]=="--enable-tested-program-logging": + enable_tested_program_logging=True if not skip_check: command = 'cat ticket.sum | sha256sum -c' @@ -102,13 +105,17 @@ def RunTestGroup(name): answer_file=data_dir+str(test_point_id)+".out" stderr_file=playground_dir+"/"+str(test_point_id)+".err" diff_file=playground_dir+"/"+str(test_point_id)+".diff" + log_file=playground_dir+"/"+str(test_point_id)+".log" time_limit = int(time_limit / 1000) # convert to seconds memory_limit = int(memory_limit / 1024) # convert to KB disk_limit = int(disk_limit / 512) # convert to 512B print("input_file {}, output_file {}, answer_file {}".format(input_file, output_file, answer_file)) print("time limit {}, disk limit {}, file number limit {}".format(time_limit, disk_limit, file_number_limit)) # run the path_to_exec_file with input_file and output_file with cwd=playground_dir - command = f'ulimit -t {time_limit} && ulimit -m {memory_limit} && ulimit -f {disk_limit} && ulimit -n {file_number_limit} && {path_to_exec_file} < {input_file} > {output_file} 2> {stderr_file}' + if not enable_tested_program_logging: + command = f'ulimit -t {time_limit} && ulimit -m {memory_limit} && ulimit -f {disk_limit} && ulimit -n {file_number_limit} && {path_to_exec_file} < {input_file} > {output_file} 2> {stderr_file}' + else: + command = f'ulimit -t {time_limit} && ulimit -m {memory_limit} && ulimit -f {disk_limit} && ulimit -n {file_number_limit} && {path_to_exec_file} -l {log_file} < {input_file} > {output_file} 2> {stderr_file}' print("the test command is: ", command) process = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=playground_dir) # Check the exit status of the command