hoshi-lang dev
Yet another programming language
Loading...
Searching...
No Matches
codegenObjectCache.cpp
Go to the documentation of this file.
1//
2// Created by XIaokang00010 on 2026/2/7.
3//
4
6#include "share/def.hpp"
7#include <cstdio>
8#include <filesystem>
9
10namespace yoi {
11 namespace serialization {
12 template <> void write(FILE *fp, const yoi::wstr &value) {
13 // general serialization helper for wstr
14 // read length first
15 std::string s = wstring2string(value);
16 write<uint64_t>(fp, s.size());
17 fwrite(s.data(), sizeof(std::string::value_type), s.size(), fp);
18 }
19
20 template <> void read(FILE *fp, yoi::wstr &value) {
21 // general deserialization helper for wstr
22 // read length first
23 uint64_t len;
24 read<uint64_t>(fp, len);
25 std::string s;
26 s.resize(len);
27 fread(s.data(), sizeof(std::string::value_type), len, fp);
28 value = string2wstring(s);
29 }
30
31 template <> void write(FILE *fp, const CodegenObjectCacheEntry &value) {
32 write(fp, value.abs_path_on_disk);
33 write(fp, value.object_filename);
34 write(fp, value.hash);
35 write(fp, value.last_modification);
36 write(fp, value.depend_by);
37 }
38
39 template <> void read(FILE *fp, CodegenObjectCacheEntry &value) {
40 read(fp, value.abs_path_on_disk);
41 read(fp, value.object_filename);
42 read(fp, value.hash);
43 read(fp, value.last_modification);
44 read(fp, value.depend_by);
45 }
46
47 template <> void write(FILE *fp, const CodegenObjectCache &value) {
48 write<uint64_t>(fp, value.cache.size());
49 for (auto &item : value.cache) {
50 write(fp, item.first);
51 write(fp, item.second);
52 }
53 write<uint64_t>(fp, value.free_list.size());
54 for (auto &item : value.free_list) {
55 write(fp, item);
56 }
57 write<yoi::indexT>(fp, value.next_hash);
58 }
59
60 template <> void read(FILE *fp, CodegenObjectCache &value) {
61 uint64_t len;
62 read<uint64_t>(fp, len);
63 for (auto i = 0; i < len; i++) {
64 yoi::wstr key;
66 read(fp, key);
67 read(fp, entry);
68 value.cache.insert({key, entry});
69 }
70 read<uint64_t>(fp, len);
71 for (auto i = 0; i < len; i++) {
72 yoi::indexT item;
73 read(fp, item);
74 value.free_list.insert(item);
75 }
76 read<yoi::indexT>(fp, value.next_hash);
77 }
78
79 template <> void write(FILE *fp, const std::set<yoi::indexT> &value) {
80 write<uint64_t>(fp, value.size());
81 for (auto &item : value) {
82 write(fp, item);
83 }
84 }
85
86 template <> void read(FILE *fp, std::set<yoi::indexT> &value) {
87 uint64_t len;
88 read<uint64_t>(fp, len);
89 for (auto i = 0; i < len; i++) {
90 yoi::indexT item;
91 read(fp, item);
92 value.insert(item);
93 }
94 }
95 } // namespace serialization
96
98 this->abs_path_on_disk = abs_path_on_disk;
99 return *this;
100 }
101
103 this->object_filename = object_filename;
104 return *this;
105 }
106
108 this->hash = hash;
109 return *this;
110 }
111
115
119
123
125 std::lock_guard<std::mutex> lock(cacheMutex);
126 std::set<yoi::wstr> source_set(source_files.begin(), source_files.end());
127 std::set<yoi::wstr> to_be_removed, to_be_added;
128 for (auto &item : cache) {
129 if (source_set.find(item.first) == source_set.end()) {
130 to_be_removed.insert(item.first);
131 }
132 }
133 for (auto &item : source_files) {
134 if (cache.find(item) == cache.end()) {
135 to_be_added.insert(item);
136 }
137 }
138 for (auto &item : to_be_removed) {
139 if (std::filesystem::exists(cache[item].object_filename)) {
140 std::filesystem::remove(cache[item].object_filename);
141 }
142 free_list.insert(cache[item].hash);
143 cache.erase(item);
144 }
145 for (auto &item : to_be_added) {
147 }
148 }
149
151 // check if the entry is already in the cache
152 if (cache.find(abs_path_on_disk) != cache.end()) {
153 return cache[abs_path_on_disk].hash;
154 }
155 yoi::indexT hash = 0;
156 if (free_list.empty()) {
157 hash = next_hash++;
158 } else {
159 hash = *free_list.begin();
160 free_list.erase(free_list.begin());
161 }
162 if (!std::filesystem::exists(compilerCtx->getBuildConfig()->buildCachePath)) {
163 std::filesystem::create_directories(compilerCtx->getBuildConfig()->buildCachePath);
164 }
165 yoi::wstr object_filename = compilerCtx->getBuildConfig()->buildCachePath + L"/" + std::to_wstring(hash) + L".o";
166 {
167 std::lock_guard<std::mutex> lock(consoleMutex);
168 printf("Creating cache for file: %s\n", yoi::wstring2string(abs_path_on_disk).c_str());
169 }
170 cache[abs_path_on_disk] = CodegenObjectCacheEntry().setAbsPathOnDisk(abs_path_on_disk).setObjectFilename(object_filename).setHash(hash).setLastModification(0);
171 return hash;
172 }
173
175 std::lock_guard<std::mutex> lock(cacheMutex);
176 return register_entry_unlocked(abs_path_on_disk);
177 }
178
180 std::lock_guard<std::mutex> lock(cacheMutex);
181 if (cache.find(abs_path_on_disk) == cache.end()) {
182 return -1;
183 }
184 return cache[abs_path_on_disk].hash;
185 }
186
188 std::lock_guard<std::mutex> lock(cacheMutex);
189 if (cache.find(abs_path_on_disk) == cache.end()) {
190 register_entry_unlocked(abs_path_on_disk);
191 }
192 return cache.at(abs_path_on_disk);
193 }
194
195 void CodegenObjectCache::remove_entry(const yoi::wstr &abs_path_on_disk) {
196 std::lock_guard<std::mutex> lock(cacheMutex);
197 free_list.insert(cache.at(abs_path_on_disk).hash);
198 cache.erase(abs_path_on_disk);
199 }
200
201 void CodegenObjectCache::update_last_modification(const yoi::wstr &abs_path_on_disk, yoi::indexT last_modification) {
202 std::lock_guard<std::mutex> lock(cacheMutex);
203 if (cache.find(abs_path_on_disk) != cache.end()) {
204 cache[abs_path_on_disk].last_modification = last_modification;
205 }
206 }
207
209 this->last_modification = last_modification;
210 return *this;
211 }
212
216
217 CodegenObjectCache &CodegenObjectCache::setCompilerCtx(const std::shared_ptr<compilerContext> &compilerCtx) {
218 this->compilerCtx = compilerCtx;
219 return *this;
220 }
221} // namespace yoi
void purge_and_update(const yoi::vec< yoi::wstr > &source_files)
purge the cache, add the entries that previously not in the cache, remove the entries that are not in...
CodegenObjectCacheEntry get_entry(const yoi::wstr &abs_path_on_disk)
get the entry from the cache
yoi::indexT register_entry(const yoi::wstr &abs_path_on_disk)
register a new entry to the cache
yoi::indexT register_entry_unlocked(const yoi::wstr &abs_path_on_disk)
CodegenObjectCache & setCompilerCtx(const std::shared_ptr< compilerContext > &compilerCtx)
set the build config
void remove_entry(const yoi::wstr &abs_path_on_disk)
remove the entry from the cache
std::set< yoi::indexT > free_list
std::shared_ptr< compilerContext > compilerCtx
yoi::indexT get_entry_index(const yoi::wstr &abs_path_on_disk)
get the entry from the cache
void update_last_modification(const yoi::wstr &abs_path_on_disk, yoi::indexT last_modification)
update the last modification time of an entry
std::map< yoi::wstr, CodegenObjectCacheEntry > cache
void write(FILE *fp, const yoi::wstr &value)
void read(FILE *fp, yoi::wstr &value)
std::string wstring2string(const std::wstring &v)
Definition def.cpp:184
std::mutex consoleMutex
Definition def.cpp:15
std::vector< t > vec
Definition def.hpp:53
std::wstring string2wstring(const std::string &v)
Definition def.cpp:178
std::wstring wstr
Definition def.hpp:48
uint64_t indexT
Definition def.hpp:51
CodegenObjectCacheEntry setAbsPathOnDisk(const yoi::wstr &abs_path_on_disk)
const yoi::wstr & getObjectFilename() const
CodegenObjectCacheEntry setHash(yoi::indexT hash)
CodegenObjectCacheEntry setLastModification(yoi::indexT last_modification)
const yoi::wstr & getAbsPathOnDisk() const
CodegenObjectCacheEntry setObjectFilename(const yoi::wstr &object_filename)
yoi::indexT getLastModification() const