web 3d图形渲染器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
16 KiB

  1. export class RangeTree {
  2. constructor(start, end, delta, children) {
  3. this.start = start;
  4. this.end = end;
  5. this.delta = delta;
  6. this.children = children;
  7. }
  8. /**
  9. * @precodition `ranges` are well-formed and pre-order sorted
  10. */
  11. static fromSortedRanges(ranges) {
  12. let root;
  13. // Stack of parent trees and parent counts.
  14. const stack = [];
  15. for (const range of ranges) {
  16. const node = new RangeTree(range.startOffset, range.endOffset, range.count, []);
  17. if (root === undefined) {
  18. root = node;
  19. stack.push([node, range.count]);
  20. continue;
  21. }
  22. let parent;
  23. let parentCount;
  24. while (true) {
  25. [parent, parentCount] = stack[stack.length - 1];
  26. // assert: `top !== undefined` (the ranges are sorted)
  27. if (range.startOffset < parent.end) {
  28. break;
  29. }
  30. else {
  31. stack.pop();
  32. }
  33. }
  34. node.delta -= parentCount;
  35. parent.children.push(node);
  36. stack.push([node, range.count]);
  37. }
  38. return root;
  39. }
  40. normalize() {
  41. const children = [];
  42. let curEnd;
  43. let head;
  44. const tail = [];
  45. for (const child of this.children) {
  46. if (head === undefined) {
  47. head = child;
  48. }
  49. else if (child.delta === head.delta && child.start === curEnd) {
  50. tail.push(child);
  51. }
  52. else {
  53. endChain();
  54. head = child;
  55. }
  56. curEnd = child.end;
  57. }
  58. if (head !== undefined) {
  59. endChain();
  60. }
  61. if (children.length === 1) {
  62. const child = children[0];
  63. if (child.start === this.start && child.end === this.end) {
  64. this.delta += child.delta;
  65. this.children = child.children;
  66. // `.lazyCount` is zero for both (both are after normalization)
  67. return;
  68. }
  69. }
  70. this.children = children;
  71. function endChain() {
  72. if (tail.length !== 0) {
  73. head.end = tail[tail.length - 1].end;
  74. for (const tailTree of tail) {
  75. for (const subChild of tailTree.children) {
  76. subChild.delta += tailTree.delta - head.delta;
  77. head.children.push(subChild);
  78. }
  79. }
  80. tail.length = 0;
  81. }
  82. head.normalize();
  83. children.push(head);
  84. }
  85. }
  86. /**
  87. * @precondition `tree.start < value && value < tree.end`
  88. * @return RangeTree Right part
  89. */
  90. split(value) {
  91. let leftChildLen = this.children.length;
  92. let mid;
  93. // TODO(perf): Binary search (check overhead)
  94. for (let i = 0; i < this.children.length; i++) {
  95. const child = this.children[i];
  96. if (child.start < value && value < child.end) {
  97. mid = child.split(value);
  98. leftChildLen = i + 1;
  99. break;
  100. }
  101. else if (child.start >= value) {
  102. leftChildLen = i;
  103. break;
  104. }
  105. }
  106. const rightLen = this.children.length - leftChildLen;
  107. const rightChildren = this.children.splice(leftChildLen, rightLen);
  108. if (mid !== undefined) {
  109. rightChildren.unshift(mid);
  110. }
  111. const result = new RangeTree(value, this.end, this.delta, rightChildren);
  112. this.end = value;
  113. return result;
  114. }
  115. /**
  116. * Get the range coverages corresponding to the tree.
  117. *
  118. * The ranges are pre-order sorted.
  119. */
  120. toRanges() {
  121. const ranges = [];
  122. // Stack of parent trees and counts.
  123. const stack = [[this, 0]];
  124. while (stack.length > 0) {
  125. const [cur, parentCount] = stack.pop();
  126. const count = parentCount + cur.delta;
  127. ranges.push({ startOffset: cur.start, endOffset: cur.end, count });
  128. for (let i = cur.children.length - 1; i >= 0; i--) {
  129. stack.push([cur.children[i], count]);
  130. }
  131. }
  132. return ranges;
  133. }
  134. }
  135. //# sourceMappingURL=data:application/json;charset=utf8;base64,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