jvr/inc/common.h

108 lines
2.8 KiB
C++

#pragma once
#include <shared_mutex>
#include <string>
#include <vector>
#include <mutex>
#include <iostream>
#include <map>
/* 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<WriteEntry *> 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<std::string, WriteLog *> 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::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
}
};