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 <jan@janware.com>
This commit is contained in:
Jan Lindemann 2017-08-09 13:06:18 +00:00
commit da3089e5b7

View file

@ -27,6 +27,27 @@ def debug(*objs):
def err(*objs): def err(*objs):
print("ERR: ", *objs, file=sys.stderr) 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): def proj_dir(name):
if name == top_name: if name == top_name:
return topdir return topdir
@ -59,6 +80,11 @@ def get_os(args = ""):
return out return out
return "linux" 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 # TODO: add support for customizing this in project.conf
def htdocs_dir(name): def htdocs_dir(name):
pd = proj_dir(name) pd = proj_dir(name)
@ -69,7 +95,7 @@ def htdocs_dir(name):
return None return None
def os_cascade(): def os_cascade():
os = get_os() os = get_os_cached()
name = re.sub('-.*', '', os) name = re.sub('-.*', '', os)
# e.g. os, linux, suse, suse-tumbleweed # e.g. os, linux, suse, suse-tumbleweed
return [ 'os', platform.system().lower(), name, os ] return [ 'os', platform.system().lower(), name, os ]
@ -92,7 +118,10 @@ def get_section(path, section):
r = r + line r = r + line
file.close() file.close()
return r.rstrip() return r.rstrip()
def get_section_cached(path, section):
return cache_func(get_section, [ path, section ])
def read_value(path, section, key): def read_value(path, section, key):
debug("opening ", path) debug("opening ", path)
try: try:
@ -131,6 +160,9 @@ def read_value(path, section, key):
return r[0] return r[0]
return None return None
def read_value_cached(path, section, key):
return cache_func(read_value, [path, section, key])
def get_value(name, section, key): def get_value(name, section, key):
debug("getting value [%s].%s for project %s (%s)" %(section, key, name, top_name)) debug("getting value [%s].%s for project %s (%s)" %(section, key, name, top_name))
if top_name and 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' path = proj_root + '/make/project.conf'
#print('path = ', path, 'top_name = ', top_name, 'name = ', name) #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): def collect_values(names, section, key):
r = "" r = ""
@ -557,6 +589,8 @@ def cmd_getval(args_):
# -------------------------------------------------------------------- here we go # -------------------------------------------------------------------- here we go
global_args = [] global_args = []
cache = {}
skip = 0 skip = 0
for a in sys.argv[1::]: for a in sys.argv[1::]:
global_args.append(a) global_args.append(a)
@ -587,7 +621,7 @@ debug("----------------------------------------- running ", ' '.join(sys.argv))
projs_root = args.prefix projs_root = args.prefix
if args.topdir: if args.topdir:
topdir = 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: if not top_name:
top_name = re.sub('-[0-9.-]*$', '', basename(realpath(topdir))) top_name = re.sub('-[0-9.-]*$', '', basename(realpath(topdir)))