7 #include <nlohmann/json.hpp>
15 namespace fs = std::filesystem;
19 return std::chrono::duration_cast<std::chrono::nanoseconds>(
20 std::chrono::system_clock::now().time_since_epoch())
26 return fmt::format(
"{0:x}", l);
32 : m_cache_dir(
std::move(o.m_cache_dir))
33 , m_file_paths(
std::move(o.m_file_paths))
34 , m_multimeshes(
std::move(o.m_multimeshes))
35 , m_delete_cache(o.m_delete_cache)
38 o.m_delete_cache =
false;
47 o.m_delete_cache =
false;
52 const std::string& prefix,
53 const std::filesystem::path& location,
56 const fs::path tmp = location.empty() ? std::filesystem::temp_directory_path() : location;
61 for (
size_t i = 0; i < max_tries; ++i) {
62 unique_dir = tmp / (prefix +
"_" + timestamp +
"_" +
number_to_hex(i));
64 if (std::filesystem::create_directory(unique_dir)) {
69 throw std::runtime_error(
"Could not generate a unique directory.");
72 Cache::Cache(
const std::string& prefix,
const std::filesystem::path location,
bool delete_cache)
73 : m_cache_dir(location)
74 , m_delete_cache(delete_cache)
82 const size_t max_tries = 1000;
83 for (
size_t i = 0; fs::exists(
m_cache_dir) && i < max_tries; ++i) {
88 const std::string path = fs::absolute(
m_cache_dir).string();
89 wmtk::logger().warn(
"Could not remove cache folder {}", path);
95 const std::string& filename,
96 const std::string& extension,
101 for (
size_t i = 0; i < max_tries; ++i) {
110 std::ofstream ofs(p);
119 throw std::runtime_error(
"Could not generate a unique file.");
140 throw std::runtime_error(
"File with name '" + filename +
"' does not exist in cache");
152 auto mm_name = name.substr(0, name.find(
'.'));
158 auto mm_name = name.substr(0, name.find(
'.'));
162 CachedMultiMesh(mm_name, std::map<std::string, std::vector<int64_t>>{}));
165 if (!
bool(cmm.get_root())) {
173 auto mm_name = name.substr(0, name.find(
'.'));
186 std::vector<std::string> names;
188 names.emplace_back(fp.first);
196 const std::string& name,
197 const std::map<std::string, std::vector<int64_t>>& multimesh_names)
211 std::map<std::string, std::vector<int64_t>> mm_names = multimesh_names;
214 mm_names.insert(multimesh_names.begin(), multimesh_names.end());
218 const_cast<Mesh&
>(m).get_multi_mesh_root().shared_from_this());
225 const_cast<Mesh&
>(m).get_multi_mesh_root().shared_from_this()));
234 if (fs::exists(export_location)) {
238 fs::path cache_content_path;
244 cache_content[first] = fs::relative(second,
m_cache_dir).string();
248 std::ofstream o(cache_content_path);
249 o << std::setw(4) << cache_content << std::endl;
254 fs::copy(
m_cache_dir, export_location, fs::copy_options::recursive);
257 fs::remove(cache_content_path);
265 if (!fs::exists(import_location)) {
275 fs::copy(import_location,
m_cache_dir, fs::copy_options::recursive);
278 fs::path cache_content_path;
279 for (
const auto& f : fs::directory_iterator(
m_cache_dir)) {
280 const fs::path p = f.path();
282 cache_content_path = p;
287 if (cache_content_path.empty()) {
293 std::ifstream i(cache_content_path);
296 std::map<std::string, std::string> map_paths =
297 cache_content.get<std::map<std::string, std::string>>();
300 for (
auto& [first, second] : map_paths) {
306 fs::remove(cache_content_path);
319 [](
const auto& a,
const auto& b) { return a.first == b.first; })) {
331 if (!(*mesh_ptr_1 == *mesh_ptr_2)) {
int64_t nanoseconds_timestamp()
std::string number_to_hex(int64_t l)
void serialize(MeshWriter &writer, const Mesh *local_root=nullptr) const
void flush_multimeshes()
Unsets the mesh held by each cached mm - useful for debugging whether cache loading works.
std::vector< std::string > mesh_names()
Get all names of the meshes stored in cache.
const std::filesystem::path & get_file_path(const std::string &filename)
Get the path where the file with the given name is stored.
void write_mesh(const Mesh &m, const std::string &name, const std::map< std::string, std::vector< int64_t >> &multimesh_names={})
Write a mesh to cache.
std::filesystem::path get_cache_path() const
Get the path of the cache folder.
const std::filesystem::path & create_unique_file(const std::string &filename, const std::string &extension, size_t max_tries=10000)
Create a file with the given name in the cache without overwriting any file with the same name.
bool equals(const Cache &o)
Compare two caches for equality.
std::map< std::string, std::filesystem::path > m_file_paths
std::map< std::string, CachedMultiMesh > m_multimeshes
static std::filesystem::path create_unique_directory(const std::string &prefix, const std::filesystem::path &location="", size_t max_tries=10000)
Create a unique directory in the given location.
Cache & operator=(Cache &&)
void load_multimesh(const std::string &name) const
bool import_cache(const std::filesystem::path &import_location)
Import a cache from the given location.
static const std::string m_cache_content_name
Cache(const std::string &prefix, const std::filesystem::path directory="", bool delete_cache=true)
This class creates and maintains a cache folder for storing temporary data.
std::vector< int64_t > absolute_multi_mesh_id(const std::string &name) const
bool export_cache(const std::filesystem::path &export_location)
Export the cache to the given location.
std::shared_ptr< Mesh > read_mesh(const std::string &name) const
Load a mesh from cache.
std::filesystem::path m_cache_dir
spdlog::logger & logger()
Retrieves the current logger.
std::shared_ptr< Mesh > read_mesh(const std::filesystem::path &filename, const bool ignore_z_if_zero, const std::vector< std::string > &tetrahedron_attributes)