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 FILE*
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;
142 size_t read(FILE*
f,
const size_t offset,
const size_t size, int8_t* buf) {
144 CHECK_EQ(fseek(f, static_cast<long>(offset), SEEK_SET), 0);
145 size_t bytesRead = fread(buf,
sizeof(int8_t), size, f);
146 CHECK_EQ(bytesRead,
sizeof(int8_t) * size);
150 size_t write(FILE*
f,
const size_t offset,
const size_t size,
const int8_t* buf) {
152 LOG(
FATAL) <<
"Error trying to write file '" << f <<
"', running readonly";
155 if (fseek(f, static_cast<long>(offset), SEEK_SET) != 0) {
157 <<
"Error trying to write to file (during positioning seek) the error was: "
158 << std::strerror(errno);
160 size_t bytesWritten = fwrite(buf,
sizeof(int8_t), size, f);
161 if (bytesWritten !=
sizeof(int8_t) * size) {
162 LOG(
FATAL) <<
"Error trying to write to file (during fwrite) the error was: "
163 << std::strerror(errno);
168 size_t append(FILE*
f,
const size_t size,
const int8_t* buf) {
170 LOG(
FATAL) <<
"Error trying to append file '" << f <<
"', running readonly";
175 size_t readPage(FILE*
f,
const size_t pageSize,
const size_t pageNum, int8_t* buf) {
176 return read(f, pageNum * pageSize, pageSize, buf);
180 const size_t pageSize,
182 const size_t readSize,
183 const size_t pageNum,
185 return read(f, pageNum * pageSize + offset, readSize, buf);
188 size_t writePage(FILE*
f,
const size_t pageSize,
const size_t pageNum, int8_t* buf) {
190 LOG(
FATAL) <<
"Error trying to writePage file '" << f <<
"', running readonly";
192 return write(f, pageNum * pageSize, pageSize, buf);
196 const size_t pageSize,
198 const size_t writeSize,
199 const size_t pageNum,
202 LOG(
FATAL) <<
"Error trying to writePartialPage file '" << f <<
"', running readonly";
204 return write(f, pageNum * pageSize + offset, writeSize, buf);
209 LOG(
FATAL) <<
"Error trying to appendPage file '" << f <<
"', running readonly";
216 fseek(f, 0, SEEK_END);
217 size_t size = (size_t)ftell(f);
218 fseek(f, 0, SEEK_SET);
228 boost::system::error_code ec;
229 boost::filesystem::path directoryPath(directoryName);
230 using namespace std::chrono;
231 milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
233 if (boost::filesystem::exists(directoryPath) &&
234 boost::filesystem::is_directory(directoryPath)) {
235 boost::filesystem::path newDirectoryPath(directoryName +
"_" +
237 boost::filesystem::rename(directoryPath, newDirectoryPath, ec);
247 while (ec.value() != boost::system::errc::success && tries) {
248 LOG(
ERROR) <<
"Failed to rename directory " << directoryPath <<
" error was " << ec
249 <<
" (" << tries <<
" attempts left)";
250 std::this_thread::sleep_for(std::chrono::milliseconds(100 / tries));
252 boost::filesystem::rename(directoryPath, newDirectoryPath, ec);
256 if (ec.value() == boost::system::errc::success) {
257 std::thread th([newDirectoryPath]() {
258 boost::system::error_code ec;
259 boost::filesystem::remove_all(newDirectoryPath, ec);
272 LOG(
FATAL) <<
"Failed to rename file " << directoryName <<
" to "
273 << directoryName +
"_" +
std::to_string(ms.count()) +
"_DELETE_ME Error: "
284 #include <boost/algorithm/string/predicate.hpp>
285 #include <boost/filesystem.hpp>
290 const unsigned int wait_interval_seconds,
291 const std::string base_path) {
292 const auto wait_duration = std::chrono::seconds(wait_interval_seconds);
293 const boost::filesystem::path path(base_path);
294 while (program_is_running) {
295 using vec = std::vector<boost::filesystem::path>;
297 boost::system::error_code ec;
301 copy(boost::filesystem::directory_iterator(path),
302 boost::filesystem::directory_iterator(),
304 for (vec::const_iterator it(v.begin()); it != v.end(); ++it) {
305 std::string object_name(it->string());
307 if (boost::algorithm::ends_with(object_name,
"DELETE_ME")) {
308 LOG(
INFO) <<
" removing object " << object_name;
309 boost::filesystem::remove_all(*it, ec);
310 if (ec.value() != boost::system::errc::success) {
311 LOG(
ERROR) <<
"Failed to remove object " << object_name <<
" error was " << ec;
316 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 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.
FILE * 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.
size_t read(FILE *f, const size_t offset, const size_t size, int8_t *buf)
Reads the specified number of bytes from the offset position in file f into buf.
DEVICE auto copy(ARGS &&...args)
::FILE * fopen(const char *filename, const char *mode)
size_t readPage(FILE *f, const size_t pageSize, const size_t pageNum, int8_t *buf)
Reads the specified page from the file f into buf.
size_t fileSize(FILE *f)
Returns the size of the specified file.
size_t readPartialPage(FILE *f, const size_t pageSize, const size_t offset, const size_t readSize, const size_t pageNum, int8_t *buf)
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.