From da3089e5b775a79a860c182378b5c4c6653811b7 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Wed, 9 Aug 2017 13:06:18 +0000 Subject: [PATCH] projects.py: Add cache_func() Add a generic cache for function calls, and use it on functions doing file I/O. This speeds the build process up considerably. Signed-off-by: Jan Lindemann --- scripts/projects.py | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/scripts/projects.py b/scripts/projects.py index c96d9ebc..9ea8e188 100644 --- a/scripts/projects.py +++ b/scripts/projects.py @@ -27,6 +27,27 @@ def debug(*objs): def err(*objs): print("ERR: ", *objs, file=sys.stderr) +def cache_func(func, args): + d = cache + depth = 0 + for a in [ func.__name__ ] + args: + if a is None: + a = 'None' + depth += 1 + #debug('depth = ', depth, 'arg = ', a, 'd = ', str(d)) + if a in d: + if len(args) == depth: + return d[a] + d = d[a] + continue + if len(args) == depth: + r = func(*args) + d[a] = r + return r + d[a] = {} + d = d[a] + raise Exception("cache algorithm failed for function", func.__name__, "in depth", depth) + def proj_dir(name): if name == top_name: return topdir @@ -59,6 +80,11 @@ def get_os(args = ""): return out return "linux" +def get_os_cached(args = ""): + if 'os' in cache: + return cache['os'] + return get_os(args) + # TODO: add support for customizing this in project.conf def htdocs_dir(name): pd = proj_dir(name) @@ -69,7 +95,7 @@ def htdocs_dir(name): return None def os_cascade(): - os = get_os() + os = get_os_cached() name = re.sub('-.*', '', os) # e.g. os, linux, suse, suse-tumbleweed return [ 'os', platform.system().lower(), name, os ] @@ -92,7 +118,10 @@ def get_section(path, section): r = r + line file.close() return r.rstrip() - + +def get_section_cached(path, section): + return cache_func(get_section, [ path, section ]) + def read_value(path, section, key): debug("opening ", path) try: @@ -131,6 +160,9 @@ def read_value(path, section, key): return r[0] return None +def read_value_cached(path, section, key): + return cache_func(read_value, [path, section, key]) + def get_value(name, section, key): debug("getting value [%s].%s for project %s (%s)" %(section, key, name, top_name)) if top_name and name == top_name: @@ -147,7 +179,7 @@ def get_value(name, section, key): path = proj_root + '/make/project.conf' #print('path = ', path, 'top_name = ', top_name, 'name = ', name) - return read_value(path, section, key) + return read_value_cached(path, section, key) def collect_values(names, section, key): r = "" @@ -557,6 +589,8 @@ def cmd_getval(args_): # -------------------------------------------------------------------- here we go global_args = [] +cache = {} + skip = 0 for a in sys.argv[1::]: global_args.append(a) @@ -587,7 +621,7 @@ debug("----------------------------------------- running ", ' '.join(sys.argv)) projs_root = args.prefix if args.topdir: topdir = args.topdir - top_name = read_value(topdir + '/make/project.conf', 'build', 'name') + top_name = read_value_cached(topdir + '/make/project.conf', 'build', 'name') if not top_name: top_name = re.sub('-[0-9.-]*$', '', basename(realpath(topdir)))