write create snap shot

This commit is contained in:
2024-05-04 14:33:12 +00:00
parent 6af4d88535
commit c59775c184
6 changed files with 152 additions and 2 deletions

View File

@ -2,6 +2,8 @@
#include <sys/stat.h>
#include <zstd.h>
#include <cstdint>
#include <fstream>
#include "map.hpp"
#include "storage/config.h"
#include "vector.hpp"
@ -13,6 +15,21 @@ default_numeric_index_t GetFileSize(const std::string &file) {
}
return stat_buf.st_size;
}
void CopyFile(const std::string &src, const std::string &dst) {
FILE *f1 = fopen(src.c_str(), "rb");
FILE *f2 = fopen(dst.c_str(), "wb");
if (f1 == nullptr || f2 == nullptr) {
throw std::runtime_error("fopen failed");
}
uint8_t buf[1 << 12];
size_t read_size;
while ((read_size = fread(buf, 1, 1 << 12, f1)) > 0) {
fwrite(buf, 1, read_size, f2);
}
fclose(f1);
fclose(f2);
}
struct uint8_t_reader {
FILE *f;
uint8_t *buf, *p1, *p2;
@ -138,6 +155,7 @@ void GenerateDiff(const std::string &old_file, const std::string &new_file, cons
buf.push_back(new_reader());
}
}
if (buf.size() == 0) buf.push_back(3);
// Step 2
size_t compressed_size_bound = ZSTD_compressBound(buf.size());
uint8_t *compressed_buf = new uint8_t[compressed_size_bound];
@ -181,6 +199,7 @@ void ApplyPatch(const std::string &old_file, const std::string &diff_file, const
while (diff_buf_cnt < decompressed_size) {
uint8_t flag;
flag = decompressed_buf[diff_buf_cnt++];
if (flag == 3) goto just_copy;
if (flag == 0) {
default_numeric_index_t current_diff_len = 0, current_diff_pos = 0, tmp = 0;
tmp = decompressed_buf[diff_buf_cnt++];
@ -266,6 +285,7 @@ void ApplyPatch(const std::string &old_file, const std::string &diff_file, const
}
}
}
just_copy:;
if (reader_cursor < old_file_size) {
while (reader_cursor < old_file_size) {
writer(reader());
@ -277,4 +297,66 @@ ed:;
fclose(fp);
fclose(fp2);
delete[] decompressed_buf;
}
void SnapShotManager::InitializeRepository() {
FILE *f = fopen(meta_file.c_str(), "w");
if (f == nullptr) {
throw std::runtime_error("fopen failed");
}
fprintf(f, "INIT\n");
fclose(f);
for (size_t i = 0; i < drivers.size(); i++) {
sjtu::vector<DataDriverBase::FileEntry> files = drivers[i]->ListFiles();
for (size_t j = 0; j < files.size(); j++) {
std::string frontier_file = files[j].path + ".frontier";
// generate an empty file
FILE *f = fopen(frontier_file.c_str(), "w");
if (f == nullptr) {
throw std::runtime_error("fopen failed");
}
fclose(f);
}
}
}
void SnapShotManager::CreateSnapShot(const std::string &snap_shot_ID) {
if (!has_set_meta_file) {
throw std::runtime_error("SnapShotManager has not set the meta file");
}
if (!has_connected) {
throw std::runtime_error("SnapShotManager has not connected to the data drivers");
}
std::fstream fs(meta_file, std::ios::in | std::ios::out);
std::string HEAD;
fs >> HEAD;
sjtu::vector<std::pair<std::string, std::string>> snapshot_relationship;
std::string cur, anc;
sjtu::map<std::string, sjtu::vector<std::string>> son_list;
while (fs >> cur >> anc) {
snapshot_relationship.push_back({cur, anc});
son_list[anc].push_back(cur);
}
if (son_list.find(snap_shot_ID) != son_list.end()) {
throw std::runtime_error("Snapshot already exists");
}
// TODO
fs.close();
fs.open(meta_file, std::ios::in | std::ios::out);
fs << snap_shot_ID << '\n';
for (size_t i = 0; i < snapshot_relationship.size(); i++) {
fs << snapshot_relationship[i].first << ' ' << snapshot_relationship[i].second << '\n';
}
fs << snap_shot_ID << " " << HEAD << std::endl;
for (size_t i = 0; i < drivers.size(); i++) {
drivers[i]->Flush();
sjtu::vector<DataDriverBase::FileEntry> files = drivers[i]->ListFiles();
for (size_t j = 0; j < files.size(); j++) {
std::string frontier_file = files[j].path + ".frontier";
std::string diff_file = files[j].path + "." + snap_shot_ID + ".diff";
GenerateDiff(frontier_file, files[j].path, diff_file);
// then overwrite the frontier file
CopyFile(files[j].path, frontier_file);
}
}
}