228d6eb47a3614f89694242f60319f04dc5e1cb767c93d2942ddd213e96e1813c4c3bf63f69f006761c6ab43f91109a2e0e191530333f26535fb3048c9704d 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. export class TreeNode {
  6. constructor(piece, color) {
  7. this.piece = piece;
  8. this.color = color;
  9. this.size_left = 0;
  10. this.lf_left = 0;
  11. this.parent = this;
  12. this.left = this;
  13. this.right = this;
  14. }
  15. next() {
  16. if (this.right !== SENTINEL) {
  17. return leftest(this.right);
  18. }
  19. let node = this;
  20. while (node.parent !== SENTINEL) {
  21. if (node.parent.left === node) {
  22. break;
  23. }
  24. node = node.parent;
  25. }
  26. if (node.parent === SENTINEL) {
  27. return SENTINEL;
  28. }
  29. else {
  30. return node.parent;
  31. }
  32. }
  33. prev() {
  34. if (this.left !== SENTINEL) {
  35. return righttest(this.left);
  36. }
  37. let node = this;
  38. while (node.parent !== SENTINEL) {
  39. if (node.parent.right === node) {
  40. break;
  41. }
  42. node = node.parent;
  43. }
  44. if (node.parent === SENTINEL) {
  45. return SENTINEL;
  46. }
  47. else {
  48. return node.parent;
  49. }
  50. }
  51. detach() {
  52. this.parent = null;
  53. this.left = null;
  54. this.right = null;
  55. }
  56. }
  57. export const SENTINEL = new TreeNode(null, 0 /* NodeColor.Black */);
  58. SENTINEL.parent = SENTINEL;
  59. SENTINEL.left = SENTINEL;
  60. SENTINEL.right = SENTINEL;
  61. SENTINEL.color = 0 /* NodeColor.Black */;
  62. export function leftest(node) {
  63. while (node.left !== SENTINEL) {
  64. node = node.left;
  65. }
  66. return node;
  67. }
  68. export function righttest(node) {
  69. while (node.right !== SENTINEL) {
  70. node = node.right;
  71. }
  72. return node;
  73. }
  74. export function calculateSize(node) {
  75. if (node === SENTINEL) {
  76. return 0;
  77. }
  78. return node.size_left + node.piece.length + calculateSize(node.right);
  79. }
  80. export function calculateLF(node) {
  81. if (node === SENTINEL) {
  82. return 0;
  83. }
  84. return node.lf_left + node.piece.lineFeedCnt + calculateLF(node.right);
  85. }
  86. export function resetSentinel() {
  87. SENTINEL.parent = SENTINEL;
  88. }
  89. export function leftRotate(tree, x) {
  90. const y = x.right;
  91. // fix size_left
  92. y.size_left += x.size_left + (x.piece ? x.piece.length : 0);
  93. y.lf_left += x.lf_left + (x.piece ? x.piece.lineFeedCnt : 0);
  94. x.right = y.left;
  95. if (y.left !== SENTINEL) {
  96. y.left.parent = x;
  97. }
  98. y.parent = x.parent;
  99. if (x.parent === SENTINEL) {
  100. tree.root = y;
  101. }
  102. else if (x.parent.left === x) {
  103. x.parent.left = y;
  104. }
  105. else {
  106. x.parent.right = y;
  107. }
  108. y.left = x;
  109. x.parent = y;
  110. }
  111. export function rightRotate(tree, y) {
  112. const x = y.left;
  113. y.left = x.right;
  114. if (x.right !== SENTINEL) {
  115. x.right.parent = y;
  116. }
  117. x.parent = y.parent;
  118. // fix size_left
  119. y.size_left -= x.size_left + (x.piece ? x.piece.length : 0);
  120. y.lf_left -= x.lf_left + (x.piece ? x.piece.lineFeedCnt : 0);
  121. if (y.parent === SENTINEL) {
  122. tree.root = x;
  123. }
  124. else if (y === y.parent.right) {
  125. y.parent.right = x;
  126. }
  127. else {
  128. y.parent.left = x;
  129. }
  130. x.right = y;
  131. y.parent = x;
  132. }
  133. export function rbDelete(tree, z) {
  134. let x;
  135. let y;
  136. if (z.left === SENTINEL) {
  137. y = z;
  138. x = y.right;
  139. }
  140. else if (z.right === SENTINEL) {
  141. y = z;
  142. x = y.left;
  143. }
  144. else {
  145. y = leftest(z.right);
  146. x = y.right;
  147. }
  148. if (y === tree.root) {
  149. tree.root = x;
  150. // if x is null, we are removing the only node
  151. x.color = 0 /* NodeColor.Black */;
  152. z.detach();
  153. resetSentinel();
  154. tree.root.parent = SENTINEL;
  155. return;
  156. }
  157. const yWasRed = (y.color === 1 /* NodeColor.Red */);
  158. if (y === y.parent.left) {
  159. y.parent.left = x;
  160. }
  161. else {
  162. y.parent.right = x;
  163. }
  164. if (y === z) {
  165. x.parent = y.parent;
  166. recomputeTreeMetadata(tree, x);
  167. }
  168. else {
  169. if (y.parent === z) {
  170. x.parent = y;
  171. }
  172. else {
  173. x.parent = y.parent;
  174. }
  175. // as we make changes to x's hierarchy, update size_left of subtree first
  176. recomputeTreeMetadata(tree, x);
  177. y.left = z.left;
  178. y.right = z.right;
  179. y.parent = z.parent;
  180. y.color = z.color;
  181. if (z === tree.root) {
  182. tree.root = y;
  183. }
  184. else {
  185. if (z === z.parent.left) {
  186. z.parent.left = y;
  187. }
  188. else {
  189. z.parent.right = y;
  190. }
  191. }
  192. if (y.left !== SENTINEL) {
  193. y.left.parent = y;
  194. }
  195. if (y.right !== SENTINEL) {
  196. y.right.parent = y;
  197. }
  198. // update metadata
  199. // we replace z with y, so in this sub tree, the length change is z.item.length
  200. y.size_left = z.size_left;
  201. y.lf_left = z.lf_left;
  202. recomputeTreeMetadata(tree, y);
  203. }
  204. z.detach();
  205. if (x.parent.left === x) {
  206. const newSizeLeft = calculateSize(x);
  207. const newLFLeft = calculateLF(x);
  208. if (newSizeLeft !== x.parent.size_left || newLFLeft !== x.parent.lf_left) {
  209. const delta = newSizeLeft - x.parent.size_left;
  210. const lf_delta = newLFLeft - x.parent.lf_left;
  211. x.parent.size_left = newSizeLeft;
  212. x.parent.lf_left = newLFLeft;
  213. updateTreeMetadata(tree, x.parent, delta, lf_delta);
  214. }
  215. }
  216. recomputeTreeMetadata(tree, x.parent);
  217. if (yWasRed) {
  218. resetSentinel();
  219. return;
  220. }
  221. // RB-DELETE-FIXUP
  222. let w;
  223. while (x !== tree.root && x.color === 0 /* NodeColor.Black */) {
  224. if (x === x.parent.left) {
  225. w = x.parent.right;
  226. if (w.color === 1 /* NodeColor.Red */) {
  227. w.color = 0 /* NodeColor.Black */;
  228. x.parent.color = 1 /* NodeColor.Red */;
  229. leftRotate(tree, x.parent);
  230. w = x.parent.right;
  231. }
  232. if (w.left.color === 0 /* NodeColor.Black */ && w.right.color === 0 /* NodeColor.Black */) {
  233. w.color = 1 /* NodeColor.Red */;
  234. x = x.parent;
  235. }
  236. else {
  237. if (w.right.color === 0 /* NodeColor.Black */) {
  238. w.left.color = 0 /* NodeColor.Black */;
  239. w.color = 1 /* NodeColor.Red */;
  240. rightRotate(tree, w);
  241. w = x.parent.right;
  242. }
  243. w.color = x.parent.color;
  244. x.parent.color = 0 /* NodeColor.Black */;
  245. w.right.color = 0 /* NodeColor.Black */;
  246. leftRotate(tree, x.parent);
  247. x = tree.root;
  248. }
  249. }
  250. else {
  251. w = x.parent.left;
  252. if (w.color === 1 /* NodeColor.Red */) {
  253. w.color = 0 /* NodeColor.Black */;
  254. x.parent.color = 1 /* NodeColor.Red */;
  255. rightRotate(tree, x.parent);
  256. w = x.parent.left;
  257. }
  258. if (w.left.color === 0 /* NodeColor.Black */ && w.right.color === 0 /* NodeColor.Black */) {
  259. w.color = 1 /* NodeColor.Red */;
  260. x = x.parent;
  261. }
  262. else {
  263. if (w.left.color === 0 /* NodeColor.Black */) {
  264. w.right.color = 0 /* NodeColor.Black */;
  265. w.color = 1 /* NodeColor.Red */;
  266. leftRotate(tree, w);
  267. w = x.parent.left;
  268. }
  269. w.color = x.parent.color;
  270. x.parent.color = 0 /* NodeColor.Black */;
  271. w.left.color = 0 /* NodeColor.Black */;
  272. rightRotate(tree, x.parent);
  273. x = tree.root;
  274. }
  275. }
  276. }
  277. x.color = 0 /* NodeColor.Black */;
  278. resetSentinel();
  279. }
  280. export function fixInsert(tree, x) {
  281. recomputeTreeMetadata(tree, x);
  282. while (x !== tree.root && x.parent.color === 1 /* NodeColor.Red */) {
  283. if (x.parent === x.parent.parent.left) {
  284. const y = x.parent.parent.right;
  285. if (y.color === 1 /* NodeColor.Red */) {
  286. x.parent.color = 0 /* NodeColor.Black */;
  287. y.color = 0 /* NodeColor.Black */;
  288. x.parent.parent.color = 1 /* NodeColor.Red */;
  289. x = x.parent.parent;
  290. }
  291. else {
  292. if (x === x.parent.right) {
  293. x = x.parent;
  294. leftRotate(tree, x);
  295. }
  296. x.parent.color = 0 /* NodeColor.Black */;
  297. x.parent.parent.color = 1 /* NodeColor.Red */;
  298. rightRotate(tree, x.parent.parent);
  299. }
  300. }
  301. else {
  302. const y = x.parent.parent.left;
  303. if (y.color === 1 /* NodeColor.Red */) {
  304. x.parent.color = 0 /* NodeColor.Black */;
  305. y.color = 0 /* NodeColor.Black */;
  306. x.parent.parent.color = 1 /* NodeColor.Red */;
  307. x = x.parent.parent;
  308. }
  309. else {
  310. if (x === x.parent.left) {
  311. x = x.parent;
  312. rightRotate(tree, x);
  313. }
  314. x.parent.color = 0 /* NodeColor.Black */;
  315. x.parent.parent.color = 1 /* NodeColor.Red */;
  316. leftRotate(tree, x.parent.parent);
  317. }
  318. }
  319. }
  320. tree.root.color = 0 /* NodeColor.Black */;
  321. }
  322. export function updateTreeMetadata(tree, x, delta, lineFeedCntDelta) {
  323. // node length change or line feed count change
  324. while (x !== tree.root && x !== SENTINEL) {
  325. if (x.parent.left === x) {
  326. x.parent.size_left += delta;
  327. x.parent.lf_left += lineFeedCntDelta;
  328. }
  329. x = x.parent;
  330. }
  331. }
  332. export function recomputeTreeMetadata(tree, x) {
  333. let delta = 0;
  334. let lf_delta = 0;
  335. if (x === tree.root) {
  336. return;
  337. }
  338. // go upwards till the node whose left subtree is changed.
  339. while (x !== tree.root && x === x.parent.right) {
  340. x = x.parent;
  341. }
  342. if (x === tree.root) {
  343. // well, it means we add a node to the end (inorder)
  344. return;
  345. }
  346. // x is the node whose right subtree is changed.
  347. x = x.parent;
  348. delta = calculateSize(x.left) - x.size_left;
  349. lf_delta = calculateLF(x.left) - x.lf_left;
  350. x.size_left += delta;
  351. x.lf_left += lf_delta;
  352. // go upwards till root. O(logN)
  353. while (x !== tree.root && (delta !== 0 || lf_delta !== 0)) {
  354. if (x.parent.left === x) {
  355. x.parent.size_left += delta;
  356. x.parent.lf_left += lf_delta;
  357. }
  358. x = x.parent;
  359. }
  360. }