Bridges-C++  3.1.1
Bridges(C++API)
Cache.h
Go to the documentation of this file.
1 #ifndef CACHE_H
2 #define CACHE_H
3 
4 #ifndef _WIN32
5 #include <unistd.h>
6 #endif
7 #ifdef _WIN32
8 #include <direct.h>
9 #endif
10 
11 namespace bridges {
12 
13 
14  class CacheException : std::exception {
15  };
16 
17  class Cache {
18  public:
19  virtual bool inCache(const std::string & docName) noexcept(false) = 0;
20  virtual std::string getDoc (const std::string & docName) noexcept(false) = 0;
21  //store content under docname
22  virtual void putDoc (const std::string & docName,
23  const std::string & content) noexcept(false) = 0;
24  };
25 
26  class SimpleCache : public Cache {
27  private:
28  std::string cacheDir;
29 
30  std::string getFilename(const std::string & docName) {
31  return cacheDir + "/" + docName; //TODO: bad things can happen if docName contains / or .. or stuff like that
32 
33  }
34 
35  //return whether s is a directory (true) or does not exist (false). all other cases are exception
36  bool directoryExist(const std::string &s) {
37  struct stat buffer;
38  int ret = stat (s.c_str(), &buffer);
39 
40  if (ret == 0) { //file exist
41  if ((buffer.st_mode & S_IFMT) == S_IFDIR) { //Not using S_ISDIR because VS2017 does not support it.
42  return true;
43  }
44  else {
45  throw CacheException(); //s exist but is not a directory
46  }
47  }
48 
49  return false;
50  }
51 
52  //make a directory called s or throw an exception
53  void makeDirectory (const std::string &s) {
54 #ifndef _WIN32
55  int ret = mkdir(s.c_str(), 0700);
56 #endif
57 #ifdef _WIN32
58  int ret = _mkdir(s.c_str());
59 #endif
60 
61 
62  if (ret != 0)
63  throw CacheException();
64  }
65 
66  public:
68  char * home = getenv("HOME"); // a reasonable location on unixes
69  if (home == nullptr)
70  home = getenv("LOCALAPPDATA"); // a reasonnable location on windowses
71 
72  if (home != nullptr)
73  cacheDir += std::string(home) + "/";
74 
75  cacheDir += "cache/";
76  //probably should check directory existence here, but exception in constructors are weird.
77  }
78 
79  //is docName in the cache
80  virtual bool inCache(const std::string & docName) noexcept(false) override {
81  std::string filename = getFilename(docName);
82 
83  std::ifstream in(filename);
84 
85  return in.is_open();
86  }
87 
88  //return the content of docName which is in the cache
89  virtual std::string getDoc (const std::string & docName) noexcept(false) override {
90  std::string filename = getFilename(docName);
91 
92  std::ifstream in(filename);
93 
94  if (!in.good() || !(in.is_open()))
95  throw CacheException();
96 
97 
98  std::string contents;
99  in.seekg(0, std::ios::end);
100  contents.resize(in.tellg());
101  in.seekg(0, std::ios::beg);
102  in.read(&contents[0], contents.size());
103  if (! (in.good()))
104  throw CacheException();
105  in.close();
106  return (contents);
107 
108  }
109 
110  //store content under docname
111  virtual void putDoc (const std::string & docName,
112  const std::string & content) noexcept(false) override {
113  if (!directoryExist(cacheDir))
114  makeDirectory(cacheDir);
115 
116  std::string filename = getFilename(docName);
117 
118 
119  std::ofstream out(filename);
120  if (!out.good() || !(out.is_open()))
121  throw CacheException();
122 
123  out << content.c_str(); //this assumes string isn't binary
124  if (!out.good() || !(out.is_open()))
125  throw CacheException();
126 
127  }
128 
133  bool evict(const std::string& docName) {
134  string f = cacheDir;
135  f.append(docName);
136 
137  return std::remove(f.c_str()) == 0;
138  }
139  };
140 
141 
142  class lruCache : public Cache {
143 
144  int maxCache;
145  std::vector<std::string> v;
146  SimpleCache ca;
147  public:
148  lruCache(int maxFileNumber = 30)
149  : maxCache(maxFileNumber) {
150  }
151 
152  virtual std::string getDoc (const std::string& hash_value) override { //returns LRU vector from cache file
153  string content;
154  getLRU();
155  content = ca.getDoc(hash_value);
156  updateLRU(hash_value);
157  saveLRU();
158  return content;
159  }
160 
161  virtual bool inCache(const std::string& hash_value) override {
162  if (ca.inCache(hash_value)) {
163  return true;
164  }
165  return false;
166  }
167 
168  virtual void putDoc(const std::string& hash_value, const std::string& content) override { //puts hash value at front of LRU vector
169  getLRU();
170  ca.putDoc(hash_value, content);
171  updateLRU(hash_value);
172 
173  //checks size of vector and pops lru off
174  if (v.size() >= maxCache + 1) { // keeps maxCache local maps
175  if (ca.evict(v[v.size() - 1]))
176  v.pop_back();
177  }
178  saveLRU();
179  return;
180  }
181 
182 
183 
184  private:
185  void updateLRU(std::string hash_value) {
186  for (auto it = v.begin(); it != v.end(); ) {
187  if (*it == hash_value) {
188  v.erase(it); //removes old hash vlaue location in vector
189  break;
190  }
191  else {
192  ++it;
193  }
194  }
195  v.insert(v.begin(), hash_value); //puts hash value in the front of the vector
196  return;
197  }
198  void getLRU() {
199  v.clear();
200  if (ca.inCache("lru")) {
201  string vector_string = ca.getDoc("lru"); //Imported LRU
202  std::istringstream ss(vector_string);
203  std::string token;
204  //Parses string and turns it into vector
205  while (std::getline(ss, token, ',')) {
206  v.push_back(token);
207  }
208  }
209  return;
210  }
211 
212  void saveLRU() {
213  //Saves the vector to file
214  string out_vector;
215  int x = 0;
216  for (auto s : v) {
217  if (x == 0) { //prevents , from being first character
218  out_vector = s;
219  x++;
220  }
221  else {
222  out_vector = out_vector + "," + s;
223  }
224  }
225  ca.putDoc("lru", out_vector);
226  }
227  };
228 }
229 
230 #endif
Definition: Cache.h:14
virtual void putDoc(const std::string &hash_value, const std::string &content) override
Definition: Cache.h:168
Definition: Cache.h:142
Definition: Cache.h:26
virtual std::string getDoc(const std::string &docName) noexcept(false) override
Definition: Cache.h:89
virtual void putDoc(const std::string &docName, const std::string &content) noexcept(false) override
Definition: Cache.h:111
SimpleCache()
Definition: Cache.h:67
virtual std::string getDoc(const std::string &hash_value) override
Definition: Cache.h:152
bool evict(const std::string &docName)
evicts a document from the cache
Definition: Cache.h:133
lruCache(int maxFileNumber=30)
Definition: Cache.h:148
virtual bool inCache(const std::string &docName) noexcept(false) override
Definition: Cache.h:80
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
Definition: alltypes.h:4
Definition: Cache.h:17
virtual bool inCache(const std::string &hash_value) override
Definition: Cache.h:161