Bridges-C++  3.2.0
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  virtual ~SimpleCache()=default;
80 
81  //is docName in the cache
82  virtual bool inCache(const std::string & docName) noexcept(false) override {
83  std::string filename = getFilename(docName);
84 
85  std::ifstream in(filename);
86 
87  return in.is_open();
88  }
89 
90  //return the content of docName which is in the cache
91  virtual std::string getDoc (const std::string & docName) noexcept(false) override {
92  std::string filename = getFilename(docName);
93 
94  std::ifstream in(filename);
95 
96  if (!in.good() || !(in.is_open()))
97  throw CacheException();
98 
99 
100  std::string contents;
101  in.seekg(0, std::ios::end);
102  contents.resize(in.tellg());
103  in.seekg(0, std::ios::beg);
104  in.read(&contents[0], contents.size());
105  if (! (in.good()))
106  throw CacheException();
107  in.close();
108  return (contents);
109 
110  }
111 
112  //store content under docname
113  virtual void putDoc (const std::string & docName,
114  const std::string & content) noexcept(false) override {
115  if (!directoryExist(cacheDir))
116  makeDirectory(cacheDir);
117 
118  std::string filename = getFilename(docName);
119 
120 
121  std::ofstream out(filename);
122  if (!out.good() || !(out.is_open()))
123  throw CacheException();
124 
125  out << content.c_str(); //this assumes string isn't binary
126  if (!out.good() || !(out.is_open()))
127  throw CacheException();
128 
129  }
130 
135  bool evict(const std::string& docName) {
136  string f = cacheDir;
137  f.append(docName);
138 
139  return std::remove(f.c_str()) == 0;
140  }
141  };
142 
143 
144  class lruCache : public Cache {
145 
146  int maxCache;
147  std::vector<std::string> v;
148  SimpleCache ca;
149  public:
150  lruCache(int maxFileNumber = 30)
151  : maxCache(maxFileNumber) {
152  }
153 
154  virtual ~lruCache()=default;
155 
156  virtual std::string getDoc (const std::string& hash_value) override { //returns LRU vector from cache file
157  string content;
158  getLRU();
159  content = ca.getDoc(hash_value);
160  updateLRU(hash_value);
161  saveLRU();
162  return content;
163  }
164 
165  virtual bool inCache(const std::string& hash_value) override {
166  if (ca.inCache(hash_value)) {
167  return true;
168  }
169  return false;
170  }
171 
172  virtual void putDoc(const std::string& hash_value, const std::string& content) override { //puts hash value at front of LRU vector
173  getLRU();
174  ca.putDoc(hash_value, content);
175  updateLRU(hash_value);
176 
177  //checks size of vector and pops lru off
178  if (v.size() >= maxCache + 1) { // keeps maxCache local maps
179  if (ca.evict(v[v.size() - 1]))
180  v.pop_back();
181  }
182  saveLRU();
183  return;
184  }
185 
186 
187 
188  private:
189  void updateLRU(std::string hash_value) {
190  for (auto it = v.begin(); it != v.end(); ) {
191  if (*it == hash_value) {
192  v.erase(it); //removes old hash vlaue location in vector
193  break;
194  }
195  else {
196  ++it;
197  }
198  }
199  v.insert(v.begin(), hash_value); //puts hash value in the front of the vector
200  return;
201  }
202  void getLRU() {
203  v.clear();
204  if (ca.inCache("lru")) {
205  string vector_string = ca.getDoc("lru"); //Imported LRU
206  std::istringstream ss(vector_string);
207  std::string token;
208  //Parses string and turns it into vector
209  while (std::getline(ss, token, ',')) {
210  v.push_back(token);
211  }
212  }
213  return;
214  }
215 
216  void saveLRU() {
217  //Saves the vector to file
218  string out_vector;
219  int x = 0;
220  for (auto s : v) {
221  if (x == 0) { //prevents , from being first character
222  out_vector = s;
223  x++;
224  }
225  else {
226  out_vector = out_vector + "," + s;
227  }
228  }
229  ca.putDoc("lru", out_vector);
230  }
231  };
232 }
233 
234 #endif
Definition: Cache.h:14
virtual void putDoc(const std::string &hash_value, const std::string &content) override
Definition: Cache.h:172
Definition: Cache.h:144
Definition: Cache.h:26
virtual std::string getDoc(const std::string &docName) noexcept(false) override
Definition: Cache.h:91
virtual void putDoc(const std::string &docName, const std::string &content) noexcept(false) override
Definition: Cache.h:113
SimpleCache()
Definition: Cache.h:67
virtual std::string getDoc(const std::string &hash_value) override
Definition: Cache.h:156
bool evict(const std::string &docName)
evicts a document from the cache
Definition: Cache.h:135
lruCache(int maxFileNumber=30)
Definition: Cache.h:150
virtual bool inCache(const std::string &docName) noexcept(false) override
Definition: Cache.h:82
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:165