#pragma once #include #include #include #include #include #include /* Max read size is 3MB every time */ #define MAX_READ_SIZE (3*1024*1024) /* Max write size is 3MB every time */ #define MAX_WRITE_SIZE (3*1024*1024) /* Port number for target URL */ #define SERVER_PORT (12344) #define COMMIT_NUM_INVALID (0) #define DUM_FD_START (0xDEADBEEF) #define RPC_TIMEOUT_MS (5000) #define FILE_NAME_DELIMITER (':') struct WriteEntry { uint64_t offset; uint32_t size; uint32_t commit_num; char *buffer; }; struct WriteLog { std::mutex lock; std::vector entries; /* The commit number is to signal clients up to what commit it can safely delete * This is because in case of commit IO failure, client would know what are committed and * what are not so client doesn't resend already-committed writes */ uint32_t latest_commit; WriteLog() { latest_commit = 1; } }; struct WSessionInfo { /* global map from client to filename to commit history */ std::shared_mutex log_lk; std::map log_map; WriteLog* get_write_log(const std::string& path) { WriteLog* log = nullptr; bool free = false; log_lk.lock_shared(); if (log_map.count(path) != 0) { log = log_map[path]; } log_lk.unlock_shared(); if (log == nullptr) { std::cout << "Creating new WriteLog for " << path << std::endl; log = new WriteLog; log_lk.lock(); if (log_map.count(path) == 0) { log_map[path] = log; } else { free = true; log = log_map[path]; } log_lk.unlock(); if (free) { delete log; } } else { std::cout << "Found existing WriteLog for " << path << std::endl; } return log; } /* Wsession is used to identify whether the server has failed. * wsession is generated every time the server starts, and it's supposed to be unique * for distinct server instances. Clients query for this session number upon init * If a server has failed and restarted then it acknowledges commits even when there * is nothing to commit. After receiving invalid wsession a client is expected to update * its stored wsession number resent all writes stored for the file */ uint64_t wsession; WSessionInfo() { wsession = (uint64_t) std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); } };