From 1743ad05c026417500443736821f24210cd99c8d Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 14 Aug 2021 21:59:28 +0300 Subject: [PATCH] v.util: add a small cache for util.read_file, so reading individual source files is done just once --- vlib/v/builder/compile.v | 3 +++ vlib/v/util/util.v | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index 2c2c02050c..3d99b6779a 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -83,9 +83,12 @@ fn (mut b Builder) myfree() { // for file in b.parsed_files { // } unsafe { b.parsed_files.free() } + unsafe { util.cached_read_source_file('') or {} } } fn (b &Builder) exit_on_invalid_syntax() { + // clear the source file cache, since it will not be needed anymore + unsafe { util.cached_read_source_file('') or {} } // V should exit with an exit code of 1, when there are errors, // even when -silent is passed in combination to -check-syntax: if b.pref.only_check_syntax { diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index 5052ef8d25..593b545bd8 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -267,9 +267,38 @@ pub fn path_of_executable(path string) string { return path } +[heap] +struct SourceCache { +mut: + sources map[string]string +} + +[unsafe] +pub fn cached_read_source_file(path string) ?string { + mut static cache := &SourceCache(0) + if isnil(cache) { + cache = &SourceCache{} + } + if path.len == 0 { + unsafe { cache.sources.free() } + unsafe { free(cache) } + cache = &SourceCache(0) + return error('memory source file cache cleared') + } + // eprintln('>> cached_read_source_file path: $path') + if res := cache.sources[path] { + // eprintln('>> cached') + return res + } + // eprintln('>> not cached | cache.sources.len: $cache.sources.len') + raw_text := os.read_file(path) or { return error('failed to open $path') } + res := skip_bom(raw_text) + cache.sources[path] = res + return res +} + pub fn read_file(file_path string) ?string { - raw_text := os.read_file(file_path) or { return error('failed to open $file_path') } - return skip_bom(raw_text) + return unsafe { cached_read_source_file(file_path) } } pub fn skip_bom(file_content string) string {