summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2014-11-17 01:31:58 -0500
committerLuke Shumaker <lukeshu@sbcglobal.net>2014-11-17 01:31:58 -0500
commitf57d328369def0dc728f01918e2b99e2dc2968cb (patch)
tree9c93045abd454e04a3c1d7a3c5e28e17ec4f7448
parente2373eca805c6ba6753413edffde6765d662cf10 (diff)
Makefile: memoize the spec2 and file2 functions (for performance)
-rw-r--r--Makefile35
1 files changed, 32 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 5fd9bdf..119d07f 100644
--- a/Makefile
+++ b/Makefile
@@ -20,15 +20,44 @@ WGET = wget
all: package
+# memoization ##################################################################
+
+# How to use: Define 2 variables (the type you would pass to $(call):
+# `_NAME_main` and `_NAME_hash`. Now, `_NAME_main` is the function getting
+# memoized, and _NAME_hash is a function that hashes the function arguments
+# into a string suitable for a variable name.
+#
+# Then, define the final function like:
+#
+# NAME = $(foreach func,NAME,$(memoized))
+
+_main = $(_$(func)_main)
+_hash = _memoized_$(_$(func)_hash)
+memoized = $(if $($(_hash)),,$(eval $(_hash) := _ $(_main)))$(wordlist 2,$(words $($(_hash))),$($(_hash)))
+
# utilities ####################################################################
# murl = "mangled url"
# spec = type|url|extra
# file = type/murl/extra
# base = type/murl
-name2 = $(call spec2,$1,$(foreach package,$2,$($(package))))
-spec2 = $(shell utils/spec2 $1 $(foreach a,$2,'$a'))
-file2 = $(shell utils/file2 $1 $(foreach a,$2,'$a'))
+
+_spec2_main = $(shell utils/spec2 $1 '$2')
+_file2_main = $(shell utils/file2 $1 '$2')
+
+_spec2_hash = spec2$1_$(subst :,^3A,$(subst ^,^5E,$2))
+_file2_hash = file2$1_$2
+
+# There's another level of indirection, because $2 is a list, and each item
+# needs to be memoized separately
+_spec2_memo = $(foreach func,spec2,$(memoized))
+_file2_memo = $(foreach func,file2,$(memoized))
+
+name2 = $(call spec2,$1,$(foreach name,$2,$($(name))))
+#spec2 = $(shell utils/spec2 $1 $(foreach a,$2,'$a'))
+#file2 = $(shell utils/file2 $1 $(foreach a,$2,'$a'))
+spec2 = $(foreach spec,$2,$(call _spec2_memo,$1,$(spec)))
+file2 = $(foreach file,$2,$(call _file2_memo,$1,$(file)))
specs_for = $(strip $(foreach t,$1,$(filter $t|%,$(if $2,$2,$(specs)))))