@@ -17,6 +17,10 @@ class ComputedArtifact {
1717 this . _allComputedArtifacts = allComputedArtifacts ;
1818 }
1919
20+ get requiredNumberOfArtifacts ( ) {
21+ return 1 ;
22+ }
23+
2024 /* eslint-disable no-unused-vars */
2125
2226 /**
@@ -31,21 +35,103 @@ class ComputedArtifact {
3135 throw new Error ( 'compute_() not implemented for computed artifact ' + this . name ) ;
3236 }
3337
38+ /**
39+ * This is a helper function for performing cache operations and is responsible for maintaing the
40+ * internal cache structure. This function accepts a path of artifacts, used to find the correct
41+ * nested cache object, and an operation to perform on that cache with the final key.
42+ *
43+ * The cache is structured with the first argument occupying the keys of the toplevel cache that point
44+ * to the Map of keys for the second argument and so forth until the 2nd to last argument's Map points
45+ * to result values rather than further nesting. In the simplest case of a single argument, there
46+ * is no nesting and the keys point directly to result values.
47+ *
48+ * Map(
49+ * argument1A -> Map(
50+ * argument2A -> result1A2A
51+ * argument2B -> result1A2B
52+ * )
53+ * argument1B -> Map(
54+ * argument2A -> result1B2A
55+ * )
56+ * )
57+ *
58+ * @param {!Array<*> } artifacts
59+ * @param {function(!Map, *) } cacheOperation
60+ */
61+ _performCacheOperation ( artifacts , cacheOperation ) {
62+ artifacts = artifacts . slice ( ) ;
63+
64+ let cache = this . _cache ;
65+ while ( artifacts . length > 1 ) {
66+ const nextKey = artifacts . shift ( ) ;
67+ if ( cache . has ( nextKey ) ) {
68+ cache = cache . get ( nextKey ) ;
69+ } else {
70+ const nextCache = new Map ( ) ;
71+ cache . set ( nextKey , nextCache ) ;
72+ cache = nextCache ;
73+ }
74+ }
75+
76+ return cacheOperation ( cache , artifacts . shift ( ) ) ;
77+ }
78+
79+ /**
80+ * Performs a cache.has operation, see _performCacheOperation for more.
81+ * @param {!Array<*> } artifacts
82+ * @return {boolean }
83+ */
84+ _cacheHas ( artifacts ) {
85+ return this . _performCacheOperation ( artifacts , ( cache , key ) => cache . has ( key ) ) ;
86+ }
87+
88+ /**
89+ * Performs a cache.get operation, see _performCacheOperation for more.
90+ * @param {!Array<*> } artifacts
91+ * @return {* }
92+ */
93+ _cacheGet ( artifacts ) {
94+ return this . _performCacheOperation ( artifacts , ( cache , key ) => cache . get ( key ) ) ;
95+ }
96+
97+ /**
98+ * Performs a cache.set operation, see _performCacheOperation for more.
99+ * @param {!Array<*> } artifacts
100+ * @param {* } result
101+ */
102+ _cacheSet ( artifacts , result ) {
103+ return this . _performCacheOperation ( artifacts , ( cache , key ) => cache . set ( key , result ) ) ;
104+ }
105+
106+ /**
107+ * Asserts that the length of the array is the same as the number of inputs the class expects
108+ * @param {!Array<*> } artifacts
109+ */
110+ _assertCorrectNumberOfArtifacts ( artifacts ) {
111+ const actual = artifacts . length ;
112+ const expected = this . requiredNumberOfArtifacts ;
113+ if ( actual !== expected ) {
114+ const className = this . constructor . name ;
115+ throw new Error ( `${ className } requires ${ expected } artifacts but ${ actual } were given` ) ;
116+ }
117+ }
118+
34119 /* eslint-enable no-unused-vars */
35120
36121 /**
37122 * Request a computed artifact, caching the result on the input artifact.
38- * @param {* } artifact
123+ * @param {... * } artifacts
39124 * @return {!Promise<*> }
40125 */
41- request ( artifact ) {
42- if ( this . _cache . has ( artifact ) ) {
43- return Promise . resolve ( this . _cache . get ( artifact ) ) ;
126+ request ( ...artifacts ) {
127+ this . _assertCorrectNumberOfArtifacts ( artifacts ) ;
128+ if ( this . _cacheHas ( artifacts ) ) {
129+ return Promise . resolve ( this . _cacheGet ( artifacts ) ) ;
44130 }
45131
46132 const artifactPromise = Promise . resolve ( )
47- . then ( _ => this . compute_ ( artifact , this . _allComputedArtifacts ) ) ;
48- this . _cache . set ( artifact , artifactPromise ) ;
133+ . then ( _ => this . compute_ ( ... artifacts , this . _allComputedArtifacts ) ) ;
134+ this . _cacheSet ( artifacts , artifactPromise ) ;
49135
50136 return artifactPromise ;
51137 }
0 commit comments