Index: tools/turbolizer/util.js |
diff --git a/tools/turbolizer/util.js b/tools/turbolizer/util.js |
index 09a747379018c3c650280f30319567abe425c83a..652f0c6bf2f4fcd8b4a585125d962ab1b3f5d5af 100644 |
--- a/tools/turbolizer/util.js |
+++ b/tools/turbolizer/util.js |
@@ -69,3 +69,43 @@ function sortUnique(arr, f) { |
} |
return ret; |
} |
+ |
+// Find elements in the array that match a filter. Apply an action on each |
+// such element. Check if new elements match the filter; apply the action to |
+// those elements. Repeat until no new elements match the filter and the |
+// action has been called at least once on elements that match the filter. |
+// |
+// The filter should not have any side effects. Any elements that match the |
+// filter should continue to match the filter, regardless of calls to the |
+// action on arbitrary elements. |
+// |
+// Returns nothing. |
+function filterActionUntilStabilize(arr, filt, action) { |
+ |
+ var elementsLeft = arr.slice(); // shallow copy |
+ |
+ while (true) { |
+ var matching = []; |
+ var nonMatching = []; |
+ |
+ elementsLeft.forEach(function(element) { |
+ if (filt(element)) { |
+ matching.push(element); |
+ action(element); |
+ } else { |
+ nonMatching.push(element); |
+ } |
+ }); |
+ |
+ if (elementsLeft.length == nonMatching.length) { |
+ // We stabilized; exit. |
+ break; |
+ } else { |
+ // Some elements matched and we called the action. It is possible that |
+ // elements that never matched the filter, will match it on the next |
+ // iteration. |
+ elementsLeft = nonMatching; |
+ continue; |
+ } |
+ } |
+} |