summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/core/utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src/js/core/utils.js')
-rw-r--r--addons/web/static/src/js/core/utils.js31
1 files changed, 31 insertions, 0 deletions
diff --git a/addons/web/static/src/js/core/utils.js b/addons/web/static/src/js/core/utils.js
index 1bdd9e70a69..0b4af722203 100644
--- a/addons/web/static/src/js/core/utils.js
+++ b/addons/web/static/src/js/core/utils.js
@@ -301,6 +301,37 @@ var utils = {
return fn(mod, Math.floor(x));
},
/**
+ * Topological sort of nodes
+ *
+ * @param {Object} nodes where key is name of node, and value is list of
+ * names of dependent nodes.
+ * @param {string[]} nodes[name] list of named dependencies of node having
+ * 'name' as its name.
+ * @return {string[]} topological sort of nodes by their names.
+ * @throws {Error} if there is at least one circular
+ * dependency between nodes
+ */
+ topologicalSort: function (nodes) {
+ var sorted = [];
+ var unresolved = nodes;
+ while (!_.isEmpty(unresolved)) {
+ // Get all nodes that have no dependency
+ var resolvable = _.pick(unresolved, function (dependencies, name) {
+ return _.isEmpty(_.difference(dependencies, sorted));
+ });
+ if (_.isEmpty(resolvable)) {
+ throw new Error("Circular dependency detected");
+ }
+ // Append them to sorted
+ sorted = _.union(sorted, _.keys(resolvable));
+ // Remove these nodes from unresolved
+ _.each(resolvable, function (dependencies, name) {
+ unresolved = _.omit(unresolved, name);
+ });
+ }
+ return sorted;
+ },
+ /**
* performs a half up rounding with a fixed amount of decimals, correcting for float loss of precision
* See the corresponding float_round() in server/tools/float_utils.py for more info
* @param {Number} value the value to be rounded