38 #include <boost/filesystem.hpp>
42 namespace File_Namespace {
52 auto legacy_path = boost::filesystem::canonical(new_data_file_path);
54 return legacy_path.string();
57 std::pair<FILE*, std::string>
create(
const std::string& basePath,
59 const size_t pageSize,
60 const size_t numPages) {
62 if (numPages < 1 || pageSize < 1) {
63 LOG(
FATAL) <<
"Error trying to create file '" << path
64 <<
"', Number of pages and page size must be positive integers. numPages "
65 << numPages <<
" pageSize " << pageSize;
69 LOG(
FATAL) <<
"Error trying to create file '" << path
70 <<
"', the error was: " << std::strerror(errno);
72 fseek(f, static_cast<long>((pageSize * numPages) - 1), SEEK_SET);
74 fseek(f, 0, SEEK_SET);
75 if (
fileSize(f) != pageSize * numPages) {
76 LOG(
FATAL) <<
"Error trying to create file '" << path <<
"', file size "
77 <<
fileSize(f) <<
" does not equal pageSize * numPages "
78 << pageSize * numPages;
80 boost::filesystem::create_symlink(boost::filesystem::canonical(path).
filename(),
85 FILE*
create(
const std::string& fullPath,
const size_t requestedFileSize) {
87 LOG(
FATAL) <<
"Error trying to create file '" << fullPath
88 <<
"', not allowed read only ";
92 LOG(
FATAL) <<
"Error trying to create file '" << fullPath
93 <<
"', the error was: " << std::strerror(errno);
96 fseek(f, static_cast<long>(requestedFileSize - 1), SEEK_SET);
98 fseek(f, 0, SEEK_SET);
99 if (
fileSize(f) != requestedFileSize) {
100 LOG(
FATAL) <<
"Error trying to create file '" << fullPath <<
"', file size "
101 <<
fileSize(f) <<
" does not equal requestedFileSize "
102 << requestedFileSize;
112 LOG(
FATAL) <<
"Error trying to open file '" << s
113 <<
"', the error was: " << std::strerror(errno);
118 FILE*
open(
const std::string& path) {
122 LOG(
FATAL) <<
"Error trying to open file '" << path
123 <<
"', the errno was: " << std::strerror(errno);
136 LOG(
FATAL) <<
"Error trying to remove file '" << filename <<
"', running readonly";
138 const std::string filePath = basePath +
filename;
139 return remove(filePath.c_str()) == 0;
146 const std::string& file_path) {
148 CHECK_EQ(fseek(f, static_cast<long>(offset), SEEK_SET), 0);
149 size_t bytesRead = fread(buf,
sizeof(int8_t), size, f);
150 auto expected_bytes_read =
sizeof(int8_t) * size;
151 CHECK_EQ(bytesRead, expected_bytes_read)
152 <<
"Unexpected number of bytes read from file: " << file_path
153 <<
". Expected bytes read: " << expected_bytes_read
154 <<
", actual bytes read: " << bytesRead <<
", offset: " << offset
155 <<
", file stream error set: " << (std::ferror(f) ?
"true" :
"false")
156 <<
", EOF reached: " << (std::feof(f) ?
"true" :
"false");
160 size_t write(FILE*
f,
const size_t offset,
const size_t size,
const int8_t* buf) {
162 LOG(
FATAL) <<
"Error trying to write file '" << f <<
"', running readonly";
165 if (fseek(f, static_cast<long>(offset), SEEK_SET) != 0) {
167 <<
"Error trying to write to file (during positioning seek) the error was: "
168 << std::strerror(errno);
170 size_t bytesWritten = fwrite(buf,
sizeof(int8_t), size, f);
171 if (bytesWritten !=
sizeof(int8_t) * size) {
172 LOG(
FATAL) <<
"Error trying to write to file (during fwrite) the error was: "
173 << std::strerror(errno);
178 size_t append(FILE*
f,
const size_t size,
const int8_t* buf) {
180 LOG(
FATAL) <<
"Error trying to append file '" << f <<
"', running readonly";
186 const size_t pageSize,
187 const size_t pageNum,
189 const std::string& file_path) {
190 return read(f, pageNum * pageSize, pageSize, buf, file_path);
194 const size_t pageSize,
196 const size_t readSize,
197 const size_t pageNum,
199 const std::string& file_path) {
200 return read(f, pageNum * pageSize + offset, readSize, buf, file_path);
203 size_t writePage(FILE*
f,
const size_t pageSize,
const size_t pageNum, int8_t* buf) {
205 LOG(
FATAL) <<
"Error trying to writePage file '" << f <<
"', running readonly";
207 return write(f, pageNum * pageSize, pageSize, buf);
211 const size_t pageSize,
213 const size_t writeSize,
214 const size_t pageNum,
217 LOG(
FATAL) <<
"Error trying to writePartialPage file '" << f <<
"', running readonly";
219 return write(f, pageNum * pageSize + offset, writeSize, buf);
224 LOG(
FATAL) <<
"Error trying to appendPage file '" << f <<
"', running readonly";
231 fseek(f, 0, SEEK_END);
232 size_t size = (size_t)ftell(f);
233 fseek(f, 0, SEEK_SET);
243 boost::system::error_code ec;
244 boost::filesystem::path directoryPath(directoryName);
245 using namespace std::chrono;
246 milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
248 if (boost::filesystem::exists(directoryPath) &&
249 boost::filesystem::is_directory(directoryPath)) {
250 boost::filesystem::path newDirectoryPath(directoryName +
"_" +
252 boost::filesystem::rename(directoryPath, newDirectoryPath, ec);
262 while (ec.value() != boost::system::errc::success && tries) {
263 LOG(
ERROR) <<
"Failed to rename directory " << directoryPath <<
" error was " << ec
264 <<
" (" << tries <<
" attempts left)";
265 std::this_thread::sleep_for(std::chrono::milliseconds(100 / tries));
267 boost::filesystem::rename(directoryPath, newDirectoryPath, ec);
271 if (ec.value() == boost::system::errc::success) {
272 std::thread th([newDirectoryPath]() {
273 boost::system::error_code ec;
274 boost::filesystem::remove_all(newDirectoryPath, ec);
287 LOG(
FATAL) <<
"Failed to rename file " << directoryName <<
" to "
288 << directoryName +
"_" +
std::to_string(ms.count()) +
"_DELETE_ME Error: "
299 #include <boost/algorithm/string/predicate.hpp>
300 #include <boost/filesystem.hpp>
305 const unsigned int wait_interval_seconds,
306 const std::string base_path) {
307 const auto wait_duration = std::chrono::seconds(wait_interval_seconds);
308 const boost::filesystem::path path(base_path);
309 while (program_is_running) {
310 using vec = std::vector<boost::filesystem::path>;
312 boost::system::error_code ec;
316 copy(boost::filesystem::directory_iterator(path),
317 boost::filesystem::directory_iterator(),
319 for (vec::const_iterator it(v.begin()); it != v.end(); ++it) {
320 std::string object_name(it->string());
322 if (boost::algorithm::ends_with(object_name,
"DELETE_ME")) {
323 LOG(
INFO) <<
" removing object " << object_name;
324 boost::filesystem::remove_all(*it, ec);
325 if (ec.value() != boost::system::errc::success) {
326 LOG(
ERROR) <<
"Failed to remove object " << object_name <<
" error was " << ec;
331 std::this_thread::sleep_for(wait_duration);
size_t appendPage(FILE *f, const size_t pageSize, int8_t *buf)
Appends a page from buf to the file.
size_t append(FILE *f, const size_t size, const int8_t *buf)
Appends the specified number of bytes to the end of the file f from buf.
std::string get_legacy_data_file_path(const std::string &new_data_file_path)
size_t readPartialPage(FILE *f, const size_t pageSize, const size_t offset, const size_t readSize, const size_t pageNum, int8_t *buf, const std::string &file_path)
size_t writePartialPage(FILE *f, const size_t pageSize, const size_t offset, const size_t writeSize, const size_t pageNum, int8_t *buf)
size_t writePage(FILE *f, const size_t pageSize, const size_t pageNum, int8_t *buf)
Writes a page from buf to the file.
std::pair< FILE *, std::string > create(const std::string &basePath, const int fileId, const size_t pageSize, const size_t numPages)
size_t write(FILE *f, const size_t offset, const size_t size, const int8_t *buf)
Writes the specified number of bytes to the offset position in file f from buf.
DEVICE auto copy(ARGS &&...args)
::FILE * fopen(const char *filename, const char *mode)
size_t read(FILE *f, const size_t offset, const size_t size, int8_t *buf, const std::string &file_path)
Reads the specified number of bytes from the offset position in file f into buf.
size_t fileSize(FILE *f)
Returns the size of the specified file.
std::string filename(char const *path)
FILE * open(int fileId)
Opens/creates the file with the given id; returns NULL on error.
void close(FILE *f)
Closes the file pointed to by the FILE pointer.
bool removeFile(const std::string basePath, const std::string filename)
Deletes the file pointed to by the FILE pointer.
void file_delete(std::atomic< bool > &program_is_running, const unsigned int wait_interval_seconds, const std::string base_path)
std::string get_data_file_path(const std::string &base_path, int file_id, size_t page_size)
void renameForDelete(const std::string directoryName)
Renames a directory to DELETE_ME_<EPOCH>_<oldname>.
constexpr auto kLegacyDataFileExtension
A selection of helper methods for File I/O.
size_t readPage(FILE *f, const size_t pageSize, const size_t pageNum, int8_t *buf, const std::string &file_path)
Reads the specified page from the file f into buf.