trie.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Trie = void 0;
  4. const trie_node_js_1 = require("./trie_node.js");
  5. const trie_node_factory_js_1 = require("./trie_node_factory.js");
  6. class Trie {
  7. static collectRules_(root) {
  8. const rules = [];
  9. let explore = [root];
  10. while (explore.length) {
  11. const node = explore.shift();
  12. if (node.getKind() === trie_node_js_1.TrieNodeKind.QUERY ||
  13. node.getKind() === trie_node_js_1.TrieNodeKind.BOOLEAN) {
  14. const rule = node.getRule();
  15. if (rule) {
  16. rules.unshift(rule);
  17. }
  18. }
  19. explore = explore.concat(node.getChildren());
  20. }
  21. return rules;
  22. }
  23. static printWithDepth_(node, depth, str) {
  24. const prefix = new Array(depth + 2).join(depth.toString()) + ': ';
  25. str += prefix + node.toString() + '\n';
  26. const children = node.getChildren();
  27. for (let i = 0, child; (child = children[i]); i++) {
  28. str = Trie.printWithDepth_(child, depth + 1, str);
  29. }
  30. return str;
  31. }
  32. static order_(node) {
  33. const children = node.getChildren();
  34. if (!children.length) {
  35. return 0;
  36. }
  37. const max = Math.max.apply(null, children.map(Trie.order_));
  38. return Math.max(children.length, max);
  39. }
  40. constructor() {
  41. this.root = (0, trie_node_factory_js_1.getNode)(trie_node_js_1.TrieNodeKind.ROOT, '', null);
  42. }
  43. addRule(rule) {
  44. let node = this.root;
  45. const context = rule.context;
  46. const dynamicCstr = rule.dynamicCstr.getValues();
  47. for (let i = 0, l = dynamicCstr.length; i < l; i++) {
  48. node = this.addNode_(node, dynamicCstr[i], trie_node_js_1.TrieNodeKind.DYNAMIC, context);
  49. }
  50. node = this.addNode_(node, rule.precondition.query, trie_node_js_1.TrieNodeKind.QUERY, context);
  51. const booleans = rule.precondition.constraints;
  52. for (let i = 0, l = booleans.length; i < l; i++) {
  53. node = this.addNode_(node, booleans[i], trie_node_js_1.TrieNodeKind.BOOLEAN, context);
  54. }
  55. node.setRule(rule);
  56. }
  57. lookupRules(xml, dynamic) {
  58. let nodes = [this.root];
  59. const rules = [];
  60. while (dynamic.length) {
  61. const dynamicSet = dynamic.shift();
  62. const newNodes = [];
  63. while (nodes.length) {
  64. const node = nodes.shift();
  65. const children = node.getChildren();
  66. children.forEach((child) => {
  67. if (child.getKind() !== trie_node_js_1.TrieNodeKind.DYNAMIC ||
  68. dynamicSet.indexOf(child.getConstraint()) !== -1) {
  69. newNodes.push(child);
  70. }
  71. });
  72. }
  73. nodes = newNodes.slice();
  74. }
  75. while (nodes.length) {
  76. const node = nodes.shift();
  77. if (node.getRule) {
  78. const rule = node.getRule();
  79. if (rule) {
  80. rules.push(rule);
  81. }
  82. }
  83. const children = node.findChildren(xml);
  84. nodes = nodes.concat(children);
  85. }
  86. return rules;
  87. }
  88. hasSubtrie(cstrs) {
  89. let subtrie = this.root;
  90. for (let i = 0, l = cstrs.length; i < l; i++) {
  91. const cstr = cstrs[i];
  92. subtrie = subtrie.getChild(cstr);
  93. if (!subtrie) {
  94. return false;
  95. }
  96. }
  97. return true;
  98. }
  99. toString() {
  100. return Trie.printWithDepth_(this.root, 0, '');
  101. }
  102. collectRules(root = this.root) {
  103. return Trie.collectRules_(root);
  104. }
  105. order() {
  106. return Trie.order_(this.root);
  107. }
  108. enumerate(opt_info) {
  109. return this.enumerate_(this.root, opt_info);
  110. }
  111. byConstraint(constraint) {
  112. let node = this.root;
  113. while (constraint.length && node) {
  114. const cstr = constraint.shift();
  115. node = node.getChild(cstr);
  116. }
  117. return node || null;
  118. }
  119. enumerate_(node, info) {
  120. info = info || {};
  121. const children = node.getChildren();
  122. for (let i = 0, child; (child = children[i]); i++) {
  123. if (child.kind !== trie_node_js_1.TrieNodeKind.DYNAMIC) {
  124. continue;
  125. }
  126. info[child.getConstraint()] = this.enumerate_(child, info[child.getConstraint()]);
  127. }
  128. return info;
  129. }
  130. addNode_(node, constraint, kind, context) {
  131. let nextNode = node.getChild(constraint);
  132. if (!nextNode) {
  133. nextNode = (0, trie_node_factory_js_1.getNode)(kind, constraint, context);
  134. node.addChild(nextNode);
  135. }
  136. return nextNode;
  137. }
  138. }
  139. exports.Trie = Trie;