m8
/
src
/
m8
/
cache.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#ifndef M8_CACHE_HH
#define M8_CACHE_HH
#include <boost/serialization/map.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <map>
#include <filesystem>
class Cache
{
namespace fs = std::filesystem;
public:
Cache(std::string file_name {}) :
file_name_ {file_name}
{
fs::path path {file_name_};
std::string filename {path.filename()};
if (filename.empty())
{
filename = "readline";
}
if (filename.at(0) == '.')
{
file_lock_ = "./.m8/" + filename + ".lock.m8";
file_cache_ = "./.m8/" + filename + ".cache.m8";
}
else
{
file_lock_ = "./.m8/." + filename + ".lock.m8";
file_cache_ = "./.m8/." + filename + ".cache.m8";
}
lock();
load();
}
~Cache()
{
save();
unlock();
}
bool get(std::string const& key, std::string& val)
{
if (db_.find(key) == db_.end())
{
return false;
}
val = db_[key];
return true;
}
void set(std::string const& key, std::string const& val)
{
db_[key] = val;
}
private:
void lock()
{
if (fs::exists(file_lock_))
{
throw std::runtime_error("cache lock file already in use");
}
std::ofstream file_lock {file_lock_};
file_lock.close();
}
void unlock()
{
fs::remove(file_lock_);
}
void load()
{
if (! fs::exists(file_cache_)) return;
std::ifstream icache {file_cache_, std::ios::binary};
boost::archive::binary_iarchive iarch(icache);
iarch >> db_;
}
void save()
{
std::ofstream ocache {file_cache_, std::ios::binary};
boost::archive::binary_oarchive oarch(ocache);
oarch << db_;
}
std::string const file_name_;
std::string file_lock_;
std::string file_cache_;
std::map<std::string, std::string> db_;
}; // class Cache
#endif // M8_CACHE_HH