This repository has been archived by the owner on Jul 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 162
/
Copy pathcache_manager.cc
154 lines (123 loc) · 4.19 KB
/
cache_manager.cc
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "cache_manager.h"
#include "config.h"
#include "indexer.h"
#include "lsp.h"
#include "platform.h"
#include <loguru/loguru.hpp>
#include <algorithm>
#include <unordered_map>
namespace {
// Manages loading caches from file paths for the indexer process.
struct RealCacheManager : ICacheManager {
explicit RealCacheManager() {}
~RealCacheManager() override = default;
void WriteToCache(IndexFile& file) override {
std::string cache_path = GetCachePath(file.path);
WriteToFile(cache_path, file.file_contents);
std::string indexed_content = Serialize(g_config->cacheFormat, file);
WriteToFile(AppendSerializationFormat(cache_path), indexed_content);
}
optional<std::string> LoadCachedFileContents(
const std::string& path) override {
return ReadContent(GetCachePath(path));
}
std::unique_ptr<IndexFile> RawCacheLoad(const std::string& path) override {
std::string cache_path = GetCachePath(path);
optional<std::string> file_content = ReadContent(cache_path);
optional<std::string> serialized_indexed_content =
ReadContent(AppendSerializationFormat(cache_path));
if (!file_content || !serialized_indexed_content)
return nullptr;
return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content,
*file_content, IndexFile::kMajorVersion);
}
std::string GetCachePath(const std::string& source_file) {
assert(!g_config->cacheDirectory.empty());
std::string cache_file;
size_t len = g_config->projectRoot.size();
if (StartsWith(source_file, g_config->projectRoot)) {
cache_file = EscapeFileName(g_config->projectRoot) + '/' +
EscapeFileName(source_file.substr(len));
} else {
cache_file = '@' + EscapeFileName(g_config->projectRoot) + '/' +
EscapeFileName(source_file);
}
return g_config->cacheDirectory + cache_file;
}
std::string AppendSerializationFormat(const std::string& base) {
switch (g_config->cacheFormat) {
case SerializeFormat::Json:
return base + ".json";
case SerializeFormat::MessagePack:
return base + ".mpack";
}
assert(false);
return ".json";
}
};
struct FakeCacheManager : ICacheManager {
explicit FakeCacheManager(const std::vector<FakeCacheEntry>& entries)
: entries_(entries) {}
void WriteToCache(IndexFile& file) override { assert(false); }
optional<std::string> LoadCachedFileContents(
const std::string& path) override {
for (const FakeCacheEntry& entry : entries_) {
if (entry.path == path) {
return entry.content;
}
}
return nullopt;
}
std::unique_ptr<IndexFile> RawCacheLoad(const std::string& path) override {
for (const FakeCacheEntry& entry : entries_) {
if (entry.path == path) {
return Deserialize(SerializeFormat::Json, path, entry.json, "<empty>",
nullopt);
}
}
return nullptr;
}
std::vector<FakeCacheEntry> entries_;
};
} // namespace
// static
std::shared_ptr<ICacheManager> ICacheManager::Make() {
return std::make_shared<RealCacheManager>();
}
// static
std::shared_ptr<ICacheManager> ICacheManager::MakeFake(
const std::vector<FakeCacheEntry>& entries) {
return std::make_shared<FakeCacheManager>(entries);
}
ICacheManager::~ICacheManager() = default;
IndexFile* ICacheManager::TryLoad(const std::string& path) {
auto it = caches_.find(path);
if (it != caches_.end())
return it->second.get();
std::unique_ptr<IndexFile> cache = RawCacheLoad(path);
if (!cache)
return nullptr;
caches_[path] = std::move(cache);
return caches_[path].get();
}
std::unique_ptr<IndexFile> ICacheManager::TryTakeOrLoad(
const std::string& path) {
auto it = caches_.find(path);
if (it != caches_.end()) {
auto result = std::move(it->second);
caches_.erase(it);
return result;
}
return RawCacheLoad(path);
}
std::unique_ptr<IndexFile> ICacheManager::TakeOrLoad(const std::string& path) {
auto result = TryTakeOrLoad(path);
assert(result);
return result;
}
void ICacheManager::IterateLoadedCaches(std::function<void(IndexFile*)> fn) {
for (const auto& cache : caches_) {
assert(cache.second);
fn(cache.second.get());
}
}