m8

A general-purpose preprocessor for metaprogramming.


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
Back to Top