1 #include <msp/core/maputils.h>
2 #include <msp/fs/stat.h>
3 #include <msp/io/file.h>
4 #include <msp/io/print.h>
5 #include <msp/strings/utils.h>
8 #include "sourcepackage.h"
16 unsigned read_count(IO::Base &in)
18 unsigned char head = in.get();
21 unsigned char tail = in.get();
22 return (head&0x3F)<<8 | tail;
28 string read_string(IO::Base &in)
30 unsigned len = read_count(in);
32 len = in.read(buf, len);
33 return string(buf, len);
36 void write_count(IO::Base &out, unsigned count)
42 out.put(0xC0 | (count>>8));
46 throw invalid_argument("write_count");
49 void write_string(IO::Base &out, const string &str)
51 write_count(out, str.size());
58 Cache::Cache(SourcePackage &p):
60 filename(package.get_temp_dir()/"../cache"),
64 void Cache::set_value(const Target *tgt, const string &k, const string &v)
68 set_values(tgt, k, vl);
71 void Cache::append_value(const Target *tgt, const string &k, const string &v)
73 Key key(tgt->get_name(), k);
74 DataMap::iterator i = data.find(key);
76 i = data.insert(DataMap::value_type(key, ValueList())).first;
77 i->second.push_back(v);
79 package.get_builder().get_logger().log("cache", format("Updated key %s %s+ %s", tgt->get_name(), k, v));
82 void Cache::set_values(const Target *tgt, const string &k, const ValueList &v)
84 data[Key(tgt->get_name(), k)] = v;
86 package.get_builder().get_logger().log("cache", format("Updated key %s %s: %s", tgt->get_name(), k, join(v.begin(), v.end())));
89 const string &Cache::get_value(const Target *tgt, const string &k)
91 const ValueList &values = get_values(tgt, k);
93 throw logic_error("values.empty()");
94 return values.front();
97 const Cache::ValueList &Cache::get_values(const Target *tgt, const string &k)
99 return get_item(data, Key(tgt->get_name(), k));
102 bool Cache::has_key(const Target *tgt, const string &k)
104 return data.count(Key(tgt->get_name(), k));
109 if(FS::Stat st = FS::stat(filename))
111 package.get_builder().get_logger().log("files", format("Reading %s", filename));
112 IO::BufferedFile in(filename.str());
117 key.first = read_string(in);
118 key.second = read_string(in);
119 if(key.first.empty() || key.second.empty())
121 ValueList &values = data[key];
122 for(unsigned count = read_count(in); count; --count)
123 values.push_back(read_string(in));
124 package.get_builder().get_logger().log("cache", format("Loaded key %s %s: %s", key.first, key.second, join(values.begin(), values.end())));
127 mtime = st.get_modify_time();
131 void Cache::save() const
133 if(data.empty() || !changed)
136 package.get_builder().get_logger().log("files", format("Writing %s", filename));
137 IO::BufferedFile out(filename.str(), IO::M_WRITE);
139 for(DataMap::const_iterator i=data.begin(); i!=data.end(); ++i)
141 write_string(out, i->first.first);
142 write_string(out, i->first.second);
143 write_count(out, i->second.size());
144 for(ValueList::const_iterator j=i->second.begin(); j!=i->second.end(); ++j)
145 write_string(out, *j);