Cleanup namespace and api.
This commit is contained in:
@@ -8,7 +8,7 @@ struct OriginalBuffer : Buffer {
|
|||||||
uint64_t len;
|
uint64_t len;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
|
||||||
OriginalBuffer();
|
OriginalBuffer(std::filesystem::path base_dir);
|
||||||
~OriginalBuffer();
|
~OriginalBuffer();
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|||||||
+11
-10
@@ -24,6 +24,17 @@ struct Shard {
|
|||||||
|
|
||||||
static void retain(Shard *n);
|
static void retain(Shard *n);
|
||||||
static void release(Shard *n);
|
static void release(Shard *n);
|
||||||
|
|
||||||
|
static Shard *from_file(std::filesystem::path path, OriginalBuffer *b);
|
||||||
|
static std::vector<Shard *> from_swap(std::filesystem::path path, OriginalBuffer *b);
|
||||||
|
static Shard *new_empty(OriginalBuffer *b);
|
||||||
|
|
||||||
|
static std::pair<Shard *, Shard *> split(Shard *n, uint64_t offset);
|
||||||
|
static Shard *concat(Shard *left, Shard *right);
|
||||||
|
static Shard *merge(Shard *a, Shard *b);
|
||||||
|
static Shard *merge_leaves(Shard *a, Shard *b);
|
||||||
|
static Shard *append_leaf(Shard *root, Shard *leaf);
|
||||||
|
static Shard *build_balanced(Shard **pieces, uint64_t lo, uint64_t hi);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Branch : Shard {
|
struct Branch : Shard {
|
||||||
@@ -52,13 +63,3 @@ struct Petal : Shard {
|
|||||||
: Shard(ShardKind::Petal, length, lines, 1),
|
: Shard(ShardKind::Petal, length, lines, 1),
|
||||||
source(source), pos(pos) {};
|
source(source), pos(pos) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
Shard *create_file_shards(std::string &path, OriginalBuffer *b);
|
|
||||||
Shard *create_swap_shards(std::string &path, OriginalBuffer *b);
|
|
||||||
|
|
||||||
std::pair<Shard *, Shard *> split_shard(Shard *n, uint64_t offset);
|
|
||||||
Shard *concat_shard(Shard *left, Shard *right);
|
|
||||||
Shard *merge(Shard *a, Shard *b);
|
|
||||||
Shard *merge_leaves(Shard *a, Shard *b);
|
|
||||||
Shard *append_leaf(Shard *root, Shard *leaf);
|
|
||||||
Shard *build_balanced(Shard **pieces, uint64_t lo, uint64_t hi);
|
|
||||||
|
|||||||
+5
-3
@@ -44,8 +44,10 @@ struct Vase {
|
|||||||
OriginalBuffer *original;
|
OriginalBuffer *original;
|
||||||
AppendBuffer *append;
|
AppendBuffer *append;
|
||||||
Shard *root;
|
Shard *root;
|
||||||
|
std::filesystem::path path;
|
||||||
|
std::filesystem::path swapdir;
|
||||||
|
|
||||||
Vase(std::string path);
|
Vase(std::filesystem::path path, std::filesystem::path swapdir);
|
||||||
|
|
||||||
~Vase();
|
~Vase();
|
||||||
|
|
||||||
@@ -82,8 +84,8 @@ struct Vase {
|
|||||||
void snapshot();
|
void snapshot();
|
||||||
void prune_history(uint64_t n);
|
void prune_history(uint64_t n);
|
||||||
|
|
||||||
bool save(std::string path);
|
bool save();
|
||||||
bool save_swap(std::string path);
|
bool save_swap();
|
||||||
|
|
||||||
uint64_t offset_of(Point point);
|
uint64_t offset_of(Point point);
|
||||||
Point point_of(uint64_t offset);
|
Point point_of(uint64_t offset);
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ int main(int argc, char *argv[]) {
|
|||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
throw std::runtime_error("Please give filename.");
|
throw std::runtime_error("Please give filename.");
|
||||||
|
|
||||||
Vase vase = Vase(std::string(argv[1]));
|
Vase vase = Vase(argv[1], "/tmp");
|
||||||
|
|
||||||
Point p = {500, 1000};
|
Point p = {500, 1000};
|
||||||
vase.insert(&p, 'x');
|
vase.insert(&p, 'x');
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ AppendBuffer::~AppendBuffer() {
|
|||||||
uint64_t AppendBuffer::append(char c) {
|
uint64_t AppendBuffer::append(char c) {
|
||||||
if (t_offset == APPEND_CHUNK_SIZE) {
|
if (t_offset == APPEND_CHUNK_SIZE) {
|
||||||
t_current = (TChunk *)malloc(sizeof(TChunk));
|
t_current = (TChunk *)malloc(sizeof(TChunk));
|
||||||
|
if (!t_current)
|
||||||
|
throw std::runtime_error("malloc failed");
|
||||||
buf.push_back(t_current);
|
buf.push_back(t_current);
|
||||||
t_offset = 0;
|
t_offset = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
#include "vase/buffer/original.h"
|
#include "vase/buffer/original.h"
|
||||||
#include "io/file.h"
|
#include "io/file.h"
|
||||||
|
|
||||||
OriginalBuffer::OriginalBuffer() {
|
OriginalBuffer::OriginalBuffer(std::filesystem::path base_dir) {
|
||||||
char tmp_path[] = "/tmp/tbuf.XXXXXX";
|
if (!std::filesystem::exists(base_dir) || !std::filesystem::is_directory(base_dir))
|
||||||
fd = mkstemp(tmp_path);
|
throw std::runtime_error("Swap directory does not exist or is not a directory.");
|
||||||
|
base_dir /= "tbuf.XXXXXX";
|
||||||
|
auto s = base_dir.string();
|
||||||
|
std::vector<char> mutable_path(s.begin(), s.end());
|
||||||
|
mutable_path.push_back('\0');
|
||||||
|
fd = mkstemp(mutable_path.data());
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
exit(1);
|
throw std::runtime_error("mkstemp failed");
|
||||||
unlink(tmp_path);
|
unlink(mutable_path.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
OriginalBuffer::~OriginalBuffer() {
|
OriginalBuffer::~OriginalBuffer() {
|
||||||
|
|||||||
+10
-13
@@ -87,7 +87,7 @@ Shard *balance(Shard *node) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shard *merge(Shard *a, Shard *b) {
|
Shard *Shard::merge(Shard *a, Shard *b) {
|
||||||
if (!a)
|
if (!a)
|
||||||
return b ? (Shard::retain(b), b) : nullptr;
|
return b ? (Shard::retain(b), b) : nullptr;
|
||||||
if (!b)
|
if (!b)
|
||||||
@@ -112,7 +112,7 @@ Shard *merge(Shard *a, Shard *b) {
|
|||||||
return balance(new Branch(a, b));
|
return balance(new Branch(a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Shard *, Shard *> split_shard(Shard *n, uint64_t offset) {
|
std::pair<Shard *, Shard *> Shard::split(Shard *n, uint64_t offset) {
|
||||||
if (!n)
|
if (!n)
|
||||||
return {nullptr, nullptr};
|
return {nullptr, nullptr};
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
@@ -127,12 +127,12 @@ std::pair<Shard *, Shard *> split_shard(Shard *n, uint64_t offset) {
|
|||||||
if (n->kind == Shard::ShardKind::Branch) {
|
if (n->kind == Shard::ShardKind::Branch) {
|
||||||
Branch *b = (Branch *)n;
|
Branch *b = (Branch *)n;
|
||||||
if (offset < b->left->length) {
|
if (offset < b->left->length) {
|
||||||
auto [a, b2] = split_shard(b->left, offset);
|
auto [a, b2] = split(b->left, offset);
|
||||||
Shard *right = merge(b2, b->right);
|
Shard *right = merge(b2, b->right);
|
||||||
Shard::release(b2);
|
Shard::release(b2);
|
||||||
return {a, right};
|
return {a, right};
|
||||||
} else {
|
} else {
|
||||||
auto [a, b2] = split_shard(b->right, offset - b->left->length);
|
auto [a, b2] = split(b->right, offset - b->left->length);
|
||||||
Shard *left = merge(b->left, a);
|
Shard *left = merge(b->left, a);
|
||||||
Shard::release(a);
|
Shard::release(a);
|
||||||
return {left, b2};
|
return {left, b2};
|
||||||
@@ -177,7 +177,7 @@ std::pair<Shard *, Shard *> split_shard(Shard *n, uint64_t offset) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shard *merge_leaves(Shard *a, Shard *b) {
|
Shard *Shard::merge_leaves(Shard *a, Shard *b) {
|
||||||
if (a->kind != Shard::ShardKind::Petal || b->kind != Shard::ShardKind::Petal)
|
if (a->kind != Shard::ShardKind::Petal || b->kind != Shard::ShardKind::Petal)
|
||||||
return merge(a, b);
|
return merge(a, b);
|
||||||
Petal *pa = (Petal *)a;
|
Petal *pa = (Petal *)a;
|
||||||
@@ -192,7 +192,7 @@ Shard *merge_leaves(Shard *a, Shard *b) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Shard *append_leaf(Shard *root, Shard *leaf) {
|
Shard *Shard::append_leaf(Shard *root, Shard *leaf) {
|
||||||
if (!root)
|
if (!root)
|
||||||
return leaf;
|
return leaf;
|
||||||
if (root->kind == Shard::ShardKind::Petal && root->length < PETAL_SIZE_MAX)
|
if (root->kind == Shard::ShardKind::Petal && root->length < PETAL_SIZE_MAX)
|
||||||
@@ -204,11 +204,11 @@ Shard *append_leaf(Shard *root, Shard *leaf) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shard *concat_shard(Shard *left, Shard *right) {
|
Shard *Shard::concat(Shard *left, Shard *right) {
|
||||||
return merge(left, right);
|
return merge(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
Shard *build_balanced(Shard **pieces, uint64_t lo, uint64_t hi) {
|
Shard *Shard::build_balanced(Shard **pieces, uint64_t lo, uint64_t hi) {
|
||||||
if (hi - lo == 1)
|
if (hi - lo == 1)
|
||||||
return pieces[lo];
|
return pieces[lo];
|
||||||
size_t mid = lo + (hi - lo) / 2;
|
size_t mid = lo + (hi - lo) / 2;
|
||||||
@@ -220,18 +220,15 @@ Shard *build_balanced(Shard **pieces, uint64_t lo, uint64_t hi) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shard *create_file_shards(std::string &path, OriginalBuffer *o) {
|
Shard *Shard::from_file(std::filesystem::path path, OriginalBuffer *o) {
|
||||||
int dest_fd = o->fd;
|
int dest_fd = o->fd;
|
||||||
if (dest_fd == -1)
|
if (dest_fd == -1)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
int src_fd = open(path.c_str(), O_RDONLY);
|
int src_fd = open(path.c_str(), O_RDONLY);
|
||||||
if (src_fd == -1)
|
if (src_fd == -1)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
struct stat st;
|
|
||||||
if (fstat(src_fd, &st) == -1)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
uint64_t total = (uint64_t)st.st_size;
|
uint64_t total = std::filesystem::file_size(path);
|
||||||
std::vector<Shard *> pieces;
|
std::vector<Shard *> pieces;
|
||||||
uint64_t pos = 0;
|
uint64_t pos = 0;
|
||||||
pieces.reserve((total + PETAL_SIZE_MAX - 1) / PETAL_SIZE_MAX);
|
pieces.reserve((total + PETAL_SIZE_MAX - 1) / PETAL_SIZE_MAX);
|
||||||
|
|||||||
+23
-17
@@ -2,10 +2,16 @@
|
|||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include "vase/iterators/line.h"
|
#include "vase/iterators/line.h"
|
||||||
|
|
||||||
Vase::Vase(std::string path) {
|
Vase::Vase(std::filesystem::path path, std::filesystem::path swapdir)
|
||||||
|
: path(path), swapdir(swapdir) {
|
||||||
|
if (!std::filesystem::exists(swapdir) || !std::filesystem::is_directory(swapdir))
|
||||||
|
throw std::runtime_error("Swap directory does not exist or is not a directory.");
|
||||||
append = new AppendBuffer();
|
append = new AppendBuffer();
|
||||||
original = new OriginalBuffer();
|
original = new OriginalBuffer(swapdir);
|
||||||
root = create_file_shards(path, original);
|
if (std::filesystem::is_regular_file(path))
|
||||||
|
root = Shard::from_file(path, original);
|
||||||
|
else
|
||||||
|
root = Shard::new_empty(original);
|
||||||
history.push_back(root);
|
history.push_back(root);
|
||||||
Shard::retain(root);
|
Shard::retain(root);
|
||||||
history_top = 0;
|
history_top = 0;
|
||||||
@@ -94,7 +100,7 @@ void Vase::prune_history(uint64_t n) {
|
|||||||
history_top -= n;
|
history_top -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vase::save(std::string path) {
|
bool Vase::save() {
|
||||||
std::ofstream file(path, std::ios::binary);
|
std::ofstream file(path, std::ios::binary);
|
||||||
if (!file)
|
if (!file)
|
||||||
return false;
|
return false;
|
||||||
@@ -110,7 +116,7 @@ bool Vase::save(std::string path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vase::save_swap(std::string path) {
|
bool Vase::save_swap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vase::insert(Point *point, char key) {
|
void Vase::insert(Point *point, char key) {
|
||||||
@@ -120,9 +126,9 @@ void Vase::insert(Point *point, char key) {
|
|||||||
point->col++;
|
point->col++;
|
||||||
uint64_t pos = append->append(key);
|
uint64_t pos = append->append(key);
|
||||||
Shard *inserted = new Petal(1, key == '\n', append, pos);
|
Shard *inserted = new Petal(1, key == '\n', append, pos);
|
||||||
auto [left, right] = split_shard(root, offset_of(*point));
|
auto [left, right] = Shard::split(root, offset_of(*point));
|
||||||
Shard *left2 = append_leaf(left, inserted);
|
Shard *left2 = Shard::append_leaf(left, inserted);
|
||||||
Shard *new_root = concat_shard(left2, right);
|
Shard *new_root = Shard::concat(left2, right);
|
||||||
Shard::release(left);
|
Shard::release(left);
|
||||||
Shard::release(right);
|
Shard::release(right);
|
||||||
Shard::release(left2);
|
Shard::release(left2);
|
||||||
@@ -168,9 +174,9 @@ void Vase::_insert(Point *point, const char *data, uint64_t len) {
|
|||||||
point->col += col;
|
point->col += col;
|
||||||
}
|
}
|
||||||
Shard *inserted = new Petal(len, lines, append, pos);
|
Shard *inserted = new Petal(len, lines, append, pos);
|
||||||
auto [left, right] = split_shard(root, offset);
|
auto [left, right] = Shard::split(root, offset);
|
||||||
Shard *left2 = append_leaf(left, inserted);
|
Shard *left2 = Shard::append_leaf(left, inserted);
|
||||||
Shard *new_root = concat_shard(left2, right);
|
Shard *new_root = Shard::concat(left2, right);
|
||||||
Shard::release(left);
|
Shard::release(left);
|
||||||
Shard::release(right);
|
Shard::release(right);
|
||||||
Shard::release(left2);
|
Shard::release(left2);
|
||||||
@@ -193,9 +199,9 @@ void Vase::erase(Point *point, uint64_t amount, Direction dir) {
|
|||||||
if (start_offset > end_offset)
|
if (start_offset > end_offset)
|
||||||
std::swap(start_offset, end_offset);
|
std::swap(start_offset, end_offset);
|
||||||
uint64_t count = end_offset - start_offset;
|
uint64_t count = end_offset - start_offset;
|
||||||
auto [a, b] = split_shard(root, start_offset);
|
auto [a, b] = Shard::split(root, start_offset);
|
||||||
auto [d, c] = split_shard(b, count);
|
auto [d, c] = Shard::split(b, count);
|
||||||
Shard *new_root = concat_shard(a, c);
|
Shard *new_root = Shard::concat(a, c);
|
||||||
Shard::release(a);
|
Shard::release(a);
|
||||||
Shard::release(b);
|
Shard::release(b);
|
||||||
Shard::release(c);
|
Shard::release(c);
|
||||||
@@ -212,9 +218,9 @@ void Vase::erase(Range range) {
|
|||||||
uint64_t start_offset = offset_of(start);
|
uint64_t start_offset = offset_of(start);
|
||||||
uint64_t end_offset = offset_of(end);
|
uint64_t end_offset = offset_of(end);
|
||||||
uint64_t count = end_offset - start_offset;
|
uint64_t count = end_offset - start_offset;
|
||||||
auto [a, b] = split_shard(root, start_offset);
|
auto [a, b] = Shard::split(root, start_offset);
|
||||||
auto [d, c] = split_shard(b, count);
|
auto [d, c] = Shard::split(b, count);
|
||||||
Shard *new_root = concat_shard(a, c);
|
Shard *new_root = Shard::concat(a, c);
|
||||||
Shard::release(a);
|
Shard::release(a);
|
||||||
Shard::release(b);
|
Shard::release(b);
|
||||||
Shard::release(c);
|
Shard::release(c);
|
||||||
|
|||||||
Reference in New Issue
Block a user