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