Caching of files is done : not tested yet.
This commit is contained in:
		
					parent
					
						
							
								3391f6f4c2
							
						
					
				
			
			
				commit
				
					
						b71a49cfbe
					
				
			
		
					 2 changed files with 69 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -1,13 +1,38 @@
 | 
			
		|||
#ifndef GEMINISERVER_CACHE_FILES_HPP
 | 
			
		||||
#define GEMINISERVER_CACHE_FILES_HPP
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <unordered_set>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
#include <filesystem>
 | 
			
		||||
 | 
			
		||||
namespace gemini {
 | 
			
		||||
	struct Information;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * \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 <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…
	
	Add table
		Add a link
		
	
		Reference in a new issue