Caching of files is done : not tested yet.
This commit is contained in:
parent
3391f6f4c2
commit
b71a49cfbe
@ -1,13 +1,38 @@
|
|||||||
#ifndef GEMINISERVER_CACHE_FILES_HPP
|
#ifndef GEMINISERVER_CACHE_FILES_HPP
|
||||||
#define GEMINISERVER_CACHE_FILES_HPP
|
#define GEMINISERVER_CACHE_FILES_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
namespace gemini {
|
namespace gemini {
|
||||||
|
struct Information;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This class is used to store the files in cache.
|
* \brief This class is used to store the files in cache.
|
||||||
*/
|
*/
|
||||||
class CacheFiles {
|
class CacheFiles final {
|
||||||
|
private:
|
||||||
|
std::unordered_set<std::string> files;
|
||||||
|
std::unordered_map<std::string, std::string> content;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const Information &information;
|
||||||
|
|
||||||
|
CacheFiles() = delete;
|
||||||
|
|
||||||
|
CacheFiles(const std::filesystem::path &folder, const Information &infos);
|
||||||
|
|
||||||
|
~CacheFiles() noexcept = default;
|
||||||
|
|
||||||
|
[[nodiscard, gnu::always_inline]] inline const std::unordered_set<std::string> &get_files() const {
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard, gnu::always_inline]] inline const std::unordered_map<std::string, std::string> &get_content() const {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1,44 @@
|
|||||||
#include "../include/cache_files.hpp"
|
#include "../include/cache_files.hpp"
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include "../include/information.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
gemini::CacheFiles::CacheFiles(const std::filesystem::path &folder, const Information &infos) : information(infos) {
|
||||||
|
if (!fs::is_directory(folder)) {
|
||||||
|
spdlog::error("Path {} is not a folder", folder.string());
|
||||||
|
throw std::runtime_error("Stopped in cache files constructor, see log.");
|
||||||
|
}
|
||||||
|
std::size_t global_cache = 0;
|
||||||
|
for (const auto &iterator : fs::directory_iterator(folder, fs::directory_options::follow_directory_symlink)) {
|
||||||
|
// Each time it finds a file, it is going to load it in memory and check if infos.cache_size is reached in terms of size.
|
||||||
|
if (!iterator.is_regular_file())
|
||||||
|
continue;
|
||||||
|
const std::size_t file_size = [&]() -> std::size_t {
|
||||||
|
std::ifstream in(iterator.path());
|
||||||
|
const std::size_t begin = in.tellg();
|
||||||
|
in.seekg(0, std::ios::end);
|
||||||
|
return static_cast<std::size_t>(in.tellg()) - begin;
|
||||||
|
}();
|
||||||
|
global_cache += file_size;
|
||||||
|
|
||||||
|
if (global_cache > infos.cache_size)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// I want to have the filename and not the whole path to be stored (less characters, less memory used).
|
||||||
|
const std::string filename = [&]() -> std::string {
|
||||||
|
const std::string_view path = iterator.path().string();
|
||||||
|
const std::size_t pos = path.rfind('/');
|
||||||
|
return iterator.path().string().substr(pos != std::string::npos ? pos + 1 : pos);
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (files.insert(filename.empty() ? iterator.path().string() : filename).second)
|
||||||
|
spdlog::warn("File {} could not be registered", iterator.path().string());
|
||||||
|
|
||||||
|
std::ifstream file{ iterator.path() };
|
||||||
|
if (!content.emplace(filename.empty() ? iterator.path().string() : filename,
|
||||||
|
std::string{ std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>() }).second)
|
||||||
|
spdlog::warn("File {} could not be loaded in cache", iterator.path().string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user