Files
bed/src/internal/vase/storage/append.cc
T
syedm b8eac7b2da Major updates:
- A lotta cleanup
- BEd command parser rewrite
- Vase class removed
- Proper IO system.
- A lot more.
2026-08-29 22:30:01 +01:00

73 lines
2.0 KiB
C++

#include "internal/vase/vase.h"
namespace bed::internal::vase {
AppendStorage::AppendStorage(std::filesystem::path base_dir) {
base_dir /= "tapp.XXXXXX";
char *s = strdup(base_dir.c_str());
fd = mkstemp(s);
if (fd == -1)
throw std::runtime_error("mkstemp failed");
unlink(s);
free(s);
allocated_capacity = 1ull << 30;
if (ftruncate(fd, allocated_capacity) == -1)
throw std::runtime_error("ftruncate failed");
buf = (char *)mmap(nullptr, allocated_capacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED)
throw std::runtime_error("mmap failed");
}
AppendStorage::~AppendStorage() {
if (buf && buf != MAP_FAILED)
munmap(buf, allocated_capacity);
if (fd != -1)
close(fd);
}
void AppendStorage::grow(uint64_t len) {
if (current_size + len > allocated_capacity) {
uint64_t new_capacity = allocated_capacity * 2;
if (new_capacity < current_size + len)
new_capacity = current_size + len + (1ull << 30);
if (ftruncate(fd, new_capacity) == -1)
throw std::runtime_error("ftruncate failed");
#if defined(__linux__)
void *new_buf = mremap(buf, allocated_capacity, new_capacity, MREMAP_MAYMOVE);
if (new_buf == MAP_FAILED)
throw std::runtime_error("mremap failed");
#else
munmap(buf, allocated_capacity);
void *new_buf = mmap(nullptr, new_capacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (new_buf == MAP_FAILED)
throw std::runtime_error("mmap failed");
#endif
allocated_capacity = new_capacity;
buf = (char *)new_buf;
}
}
uint64_t AppendStorage::append(const char c) {
grow(1);
buf[current_size++] = c;
return current_size - 1;
}
uint64_t AppendStorage::append(const char *text, uint64_t len) {
grow(len);
memcpy(buf + current_size, text, len);
uint64_t old_pos = current_size;
current_size += len;
return old_pos;
}
const char *AppendStorage::read(uint64_t pos) {
if (pos >= current_size)
return nullptr;
return buf + pos;
}
uint64_t AppendStorage::length() {
return current_size;
}
} // namespace bed::internal::vase