Memoize read-only source graph stats
This commit is contained in:
parent
7e0b8337ab
commit
9beec0dd03
@ -3,6 +3,7 @@
|
||||
#include "hash.h"
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
@ -50,6 +51,7 @@ struct SharedUnitCompileCheck
|
||||
|
||||
struct UnitSourceSignatureEntry
|
||||
{
|
||||
std::chrono::steady_clock::time_point checked_at;
|
||||
u64 modified_ns = 0;
|
||||
u64 changed_ns = 0;
|
||||
u64 size = 0;
|
||||
@ -144,12 +146,22 @@ bool compiler_source_readable(String file_name, const struct stat& info, int* re
|
||||
return(error == 0);
|
||||
}
|
||||
|
||||
UnitSourceSignatureEntry compiler_unit_source_entry(String file_name)
|
||||
UnitSourceSignatureEntry compiler_unit_source_entry(String file_name, bool allow_recent_stat)
|
||||
{
|
||||
auto checked_at = std::chrono::steady_clock::now();
|
||||
if(allow_recent_stat)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(unit_source_signature_cache_mutex);
|
||||
auto cached = unit_source_signature_cache.find(file_name);
|
||||
if(cached != unit_source_signature_cache.end() &&
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(checked_at - cached->second.checked_at).count() < 1000)
|
||||
return(cached->second);
|
||||
}
|
||||
struct stat info;
|
||||
UnitSourceSignatureEntry entry;
|
||||
if(stat(file_name.c_str(), &info) != 0)
|
||||
return(entry);
|
||||
entry.checked_at = checked_at;
|
||||
entry.modified_ns = (u64)info.st_mtim.tv_sec * 1000000000ull + (u64)info.st_mtim.tv_nsec;
|
||||
entry.changed_ns = (u64)info.st_ctim.tv_sec * 1000000000ull + (u64)info.st_ctim.tv_nsec;
|
||||
entry.size = (u64)info.st_size;
|
||||
@ -158,7 +170,10 @@ UnitSourceSignatureEntry compiler_unit_source_entry(String file_name)
|
||||
std::lock_guard<std::mutex> lock(unit_source_signature_cache_mutex);
|
||||
auto cached = unit_source_signature_cache.find(file_name);
|
||||
if(cached != unit_source_signature_cache.end() && cached->second.modified_ns == entry.modified_ns && cached->second.changed_ns == entry.changed_ns && cached->second.size == entry.size && cached->second.readable == entry.readable)
|
||||
{
|
||||
cached->second.checked_at = checked_at;
|
||||
return(cached->second);
|
||||
}
|
||||
}
|
||||
String content = file_get_contents(file_name);
|
||||
entry.content_hash = gen_sha1(content);
|
||||
@ -172,7 +187,7 @@ UnitSourceSignatureEntry compiler_unit_source_entry(String file_name)
|
||||
return(entry);
|
||||
}
|
||||
|
||||
void compiler_append_unit_source_signature(String file_name, std::set<String>& visited, String& signature)
|
||||
void compiler_append_unit_source_signature(String file_name, std::set<String>& visited, String& signature, bool allow_recent_stat)
|
||||
{
|
||||
String normalized = path_real(file_name);
|
||||
if(normalized == "")
|
||||
@ -181,28 +196,28 @@ void compiler_append_unit_source_signature(String file_name, std::set<String>& v
|
||||
return;
|
||||
visited.insert(normalized);
|
||||
|
||||
UnitSourceSignatureEntry entry = compiler_unit_source_entry(normalized);
|
||||
UnitSourceSignatureEntry entry = compiler_unit_source_entry(normalized, allow_recent_stat);
|
||||
signature += normalized + ":" + entry.content_hash + (entry.readable ? String("") : String(":unreadable")) + "\n";
|
||||
for(String loaded : entry.loaded_paths)
|
||||
compiler_append_unit_source_signature(loaded, visited, signature);
|
||||
compiler_append_unit_source_signature(loaded, visited, signature, allow_recent_stat);
|
||||
}
|
||||
|
||||
String compiler_unit_source_signature(String file_name)
|
||||
String compiler_unit_source_signature(String file_name, bool allow_recent_stat = false)
|
||||
{
|
||||
std::set<String> visited;
|
||||
String signature = "uce-load-graph-v1\n";
|
||||
compiler_append_unit_source_signature(file_name, visited, signature);
|
||||
compiler_append_unit_source_signature(file_name, visited, signature, allow_recent_stat);
|
||||
return(gen_sha1(signature));
|
||||
}
|
||||
|
||||
String compiler_unit_input_signature(Request* context, SharedUnit* su)
|
||||
String compiler_unit_input_signature(Request* context, SharedUnit* su, bool allow_recent_source_stat = false)
|
||||
{
|
||||
if(!context || !su || !file_exists(su->file_name))
|
||||
return("");
|
||||
|
||||
String setup_template = context->server->config["COMPILER_SYS_PATH"] + "/" + context->server->config["SETUP_TEMPLATE"];
|
||||
return(
|
||||
compiler_unit_source_signature(su->file_name) + ":" +
|
||||
compiler_unit_source_signature(su->file_name, allow_recent_source_stat) + ":" +
|
||||
gen_sha1(file_get_contents(setup_template)) + ":" +
|
||||
std::to_string(UCE_UNIT_ABI_VERSION)
|
||||
);
|
||||
@ -452,7 +467,7 @@ bool compiler_has_known_unit_cached(Request* context, String file_name)
|
||||
}));
|
||||
}
|
||||
|
||||
SharedUnitFilesystemState inspect_shared_unit_filesystem(Request* context, SharedUnit* su)
|
||||
SharedUnitFilesystemState inspect_shared_unit_filesystem(Request* context, SharedUnit* su, bool allow_recent_source_stat = false)
|
||||
{
|
||||
SharedUnitFilesystemState state;
|
||||
state.source_exists = file_exists(su->file_name);
|
||||
@ -465,7 +480,7 @@ SharedUnitFilesystemState inspect_shared_unit_filesystem(Request* context, Share
|
||||
state.compiler_abi_time = compiler_runtime_abi_time(context);
|
||||
state.metadata_time = file_mtime(su->meta_file_name);
|
||||
state.compile_output_time = file_mtime(su->compile_output_file_name);
|
||||
state.current_input_signature = compiler_unit_input_signature(context, su);
|
||||
state.current_input_signature = compiler_unit_input_signature(context, su, allow_recent_source_stat);
|
||||
state.metadata_exists = (state.metadata_time != 0);
|
||||
state.compile_output_exists = (state.compile_output_time != 0);
|
||||
if(state.metadata_exists)
|
||||
@ -1301,12 +1316,12 @@ void compiler_untrack_known_unit(Request* context, String file_name)
|
||||
});
|
||||
}
|
||||
|
||||
bool compiler_unit_needs_recompile(Request* context, String file_name, bool* source_missing)
|
||||
bool compiler_unit_needs_recompile(Request* context, String file_name, bool* source_missing, bool allow_recent_source_stat)
|
||||
{
|
||||
file_name = compiler_normalize_unit_path(context, file_name);
|
||||
SharedUnit su;
|
||||
setup_unit_paths(context, &su, file_name);
|
||||
auto state = inspect_shared_unit_filesystem(context, &su);
|
||||
auto state = inspect_shared_unit_filesystem(context, &su, allow_recent_source_stat);
|
||||
auto compile_check = shared_unit_compile_check(state);
|
||||
if(source_missing)
|
||||
*source_missing = compile_check.source_missing;
|
||||
|
||||
@ -27,7 +27,7 @@ StringList compiler_list_known_units(Request* context);
|
||||
void compiler_set_known_units(Request* context, StringList files);
|
||||
void compiler_track_known_unit(Request* context, String file_name);
|
||||
void compiler_untrack_known_unit(Request* context, String file_name);
|
||||
bool compiler_unit_needs_recompile(Request* context, String file_name, bool* source_missing = 0);
|
||||
bool compiler_unit_needs_recompile(Request* context, String file_name, bool* source_missing = 0, bool allow_recent_source_stat = false);
|
||||
DValue unit_info(String path = "");
|
||||
StringList units_list();
|
||||
bool unit_compile(String path = "");
|
||||
|
||||
@ -2210,7 +2210,7 @@ private:
|
||||
now - cached_freshness->second.checked_at).count() >= 1000;
|
||||
if(check_freshness)
|
||||
{
|
||||
stale = compiler_unit_needs_recompile(context, resolved, 0);
|
||||
stale = compiler_unit_needs_recompile(context, resolved, 0, can_serve_stale && read_request);
|
||||
worker.component_freshness[resolved] = { now, stale };
|
||||
}
|
||||
else
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user