index.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. // src/index.ts
  2. var SplayTreeNode = class {
  3. key;
  4. left = null;
  5. right = null;
  6. constructor(key) {
  7. this.key = key;
  8. }
  9. };
  10. var SplayTreeSetNode = class extends SplayTreeNode {
  11. constructor(key) {
  12. super(key);
  13. }
  14. };
  15. var SplayTreeMapNode = class _SplayTreeMapNode extends SplayTreeNode {
  16. value;
  17. constructor(key, value) {
  18. super(key);
  19. this.value = value;
  20. }
  21. replaceValue(value) {
  22. const node = new _SplayTreeMapNode(this.key, value);
  23. node.left = this.left;
  24. node.right = this.right;
  25. return node;
  26. }
  27. };
  28. var SplayTree = class {
  29. size = 0;
  30. modificationCount = 0;
  31. splayCount = 0;
  32. splay(key) {
  33. const root = this.root;
  34. if (root == null) {
  35. this.compare(key, key);
  36. return -1;
  37. }
  38. let right = null;
  39. let newTreeRight = null;
  40. let left = null;
  41. let newTreeLeft = null;
  42. let current = root;
  43. const compare = this.compare;
  44. let comp;
  45. while (true) {
  46. comp = compare(current.key, key);
  47. if (comp > 0) {
  48. let currentLeft = current.left;
  49. if (currentLeft == null) break;
  50. comp = compare(currentLeft.key, key);
  51. if (comp > 0) {
  52. current.left = currentLeft.right;
  53. currentLeft.right = current;
  54. current = currentLeft;
  55. currentLeft = current.left;
  56. if (currentLeft == null) break;
  57. }
  58. if (right == null) {
  59. newTreeRight = current;
  60. } else {
  61. right.left = current;
  62. }
  63. right = current;
  64. current = currentLeft;
  65. } else if (comp < 0) {
  66. let currentRight = current.right;
  67. if (currentRight == null) break;
  68. comp = compare(currentRight.key, key);
  69. if (comp < 0) {
  70. current.right = currentRight.left;
  71. currentRight.left = current;
  72. current = currentRight;
  73. currentRight = current.right;
  74. if (currentRight == null) break;
  75. }
  76. if (left == null) {
  77. newTreeLeft = current;
  78. } else {
  79. left.right = current;
  80. }
  81. left = current;
  82. current = currentRight;
  83. } else {
  84. break;
  85. }
  86. }
  87. if (left != null) {
  88. left.right = current.left;
  89. current.left = newTreeLeft;
  90. }
  91. if (right != null) {
  92. right.left = current.right;
  93. current.right = newTreeRight;
  94. }
  95. if (this.root !== current) {
  96. this.root = current;
  97. this.splayCount++;
  98. }
  99. return comp;
  100. }
  101. splayMin(node) {
  102. let current = node;
  103. let nextLeft = current.left;
  104. while (nextLeft != null) {
  105. const left = nextLeft;
  106. current.left = left.right;
  107. left.right = current;
  108. current = left;
  109. nextLeft = current.left;
  110. }
  111. return current;
  112. }
  113. splayMax(node) {
  114. let current = node;
  115. let nextRight = current.right;
  116. while (nextRight != null) {
  117. const right = nextRight;
  118. current.right = right.left;
  119. right.left = current;
  120. current = right;
  121. nextRight = current.right;
  122. }
  123. return current;
  124. }
  125. _delete(key) {
  126. if (this.root == null) return null;
  127. const comp = this.splay(key);
  128. if (comp != 0) return null;
  129. let root = this.root;
  130. const result = root;
  131. const left = root.left;
  132. this.size--;
  133. if (left == null) {
  134. this.root = root.right;
  135. } else {
  136. const right = root.right;
  137. root = this.splayMax(left);
  138. root.right = right;
  139. this.root = root;
  140. }
  141. this.modificationCount++;
  142. return result;
  143. }
  144. addNewRoot(node, comp) {
  145. this.size++;
  146. this.modificationCount++;
  147. const root = this.root;
  148. if (root == null) {
  149. this.root = node;
  150. return;
  151. }
  152. if (comp < 0) {
  153. node.left = root;
  154. node.right = root.right;
  155. root.right = null;
  156. } else {
  157. node.right = root;
  158. node.left = root.left;
  159. root.left = null;
  160. }
  161. this.root = node;
  162. }
  163. _first() {
  164. const root = this.root;
  165. if (root == null) return null;
  166. this.root = this.splayMin(root);
  167. return this.root;
  168. }
  169. _last() {
  170. const root = this.root;
  171. if (root == null) return null;
  172. this.root = this.splayMax(root);
  173. return this.root;
  174. }
  175. clear() {
  176. this.root = null;
  177. this.size = 0;
  178. this.modificationCount++;
  179. }
  180. has(key) {
  181. return this.validKey(key) && this.splay(key) == 0;
  182. }
  183. defaultCompare() {
  184. return (a, b) => a < b ? -1 : a > b ? 1 : 0;
  185. }
  186. wrap() {
  187. return {
  188. getRoot: () => {
  189. return this.root;
  190. },
  191. setRoot: (root) => {
  192. this.root = root;
  193. },
  194. getSize: () => {
  195. return this.size;
  196. },
  197. getModificationCount: () => {
  198. return this.modificationCount;
  199. },
  200. getSplayCount: () => {
  201. return this.splayCount;
  202. },
  203. setSplayCount: (count) => {
  204. this.splayCount = count;
  205. },
  206. splay: (key) => {
  207. return this.splay(key);
  208. },
  209. has: (key) => {
  210. return this.has(key);
  211. }
  212. };
  213. }
  214. };
  215. var SplayTreeMap = class extends SplayTree {
  216. root = null;
  217. compare;
  218. validKey;
  219. constructor(compare, isValidKey) {
  220. super();
  221. this.compare = compare ?? this.defaultCompare();
  222. this.validKey = isValidKey ?? ((a) => a != null && a != void 0);
  223. }
  224. delete(key) {
  225. if (!this.validKey(key)) return false;
  226. return this._delete(key) != null;
  227. }
  228. forEach(f) {
  229. const nodes = new SplayTreeMapEntryIterableIterator(this.wrap());
  230. let result;
  231. while (result = nodes.next(), !result.done) {
  232. f(result.value[1], result.value[0], this);
  233. }
  234. }
  235. get(key) {
  236. if (!this.validKey(key)) return void 0;
  237. if (this.root != null) {
  238. const comp = this.splay(key);
  239. if (comp == 0) {
  240. return this.root.value;
  241. }
  242. }
  243. return void 0;
  244. }
  245. hasValue(value) {
  246. const initialSplayCount = this.splayCount;
  247. const visit = (node) => {
  248. while (node != null) {
  249. if (node.value == value) return true;
  250. if (initialSplayCount != this.splayCount) {
  251. throw "Concurrent modification during iteration.";
  252. }
  253. if (node.right != null && visit(node.right)) {
  254. return true;
  255. }
  256. node = node.left;
  257. }
  258. return false;
  259. };
  260. return visit(this.root);
  261. }
  262. set(key, value) {
  263. const comp = this.splay(key);
  264. if (comp == 0) {
  265. this.root = this.root.replaceValue(value);
  266. this.splayCount += 1;
  267. return this;
  268. }
  269. this.addNewRoot(new SplayTreeMapNode(key, value), comp);
  270. return this;
  271. }
  272. setAll(other) {
  273. other.forEach((value, key) => {
  274. this.set(key, value);
  275. });
  276. }
  277. setIfAbsent(key, ifAbsent) {
  278. let comp = this.splay(key);
  279. if (comp == 0) {
  280. return this.root.value;
  281. }
  282. const modificationCount = this.modificationCount;
  283. const splayCount = this.splayCount;
  284. const value = ifAbsent();
  285. if (modificationCount != this.modificationCount) {
  286. throw "Concurrent modification during iteration.";
  287. }
  288. if (splayCount != this.splayCount) {
  289. comp = this.splay(key);
  290. }
  291. this.addNewRoot(new SplayTreeMapNode(key, value), comp);
  292. return value;
  293. }
  294. isEmpty() {
  295. return this.root == null;
  296. }
  297. isNotEmpty() {
  298. return !this.isEmpty();
  299. }
  300. firstKey() {
  301. if (this.root == null) return null;
  302. return this._first().key;
  303. }
  304. lastKey() {
  305. if (this.root == null) return null;
  306. return this._last().key;
  307. }
  308. lastKeyBefore(key) {
  309. if (key == null) throw "Invalid arguments(s)";
  310. if (this.root == null) return null;
  311. const comp = this.splay(key);
  312. if (comp < 0) return this.root.key;
  313. let node = this.root.left;
  314. if (node == null) return null;
  315. let nodeRight = node.right;
  316. while (nodeRight != null) {
  317. node = nodeRight;
  318. nodeRight = node.right;
  319. }
  320. return node.key;
  321. }
  322. firstKeyAfter(key) {
  323. if (key == null) throw "Invalid arguments(s)";
  324. if (this.root == null) return null;
  325. const comp = this.splay(key);
  326. if (comp > 0) return this.root.key;
  327. let node = this.root.right;
  328. if (node == null) return null;
  329. let nodeLeft = node.left;
  330. while (nodeLeft != null) {
  331. node = nodeLeft;
  332. nodeLeft = node.left;
  333. }
  334. return node.key;
  335. }
  336. update(key, update, ifAbsent) {
  337. let comp = this.splay(key);
  338. if (comp == 0) {
  339. const modificationCount = this.modificationCount;
  340. const splayCount = this.splayCount;
  341. const newValue = update(this.root.value);
  342. if (modificationCount != this.modificationCount) {
  343. throw "Concurrent modification during iteration.";
  344. }
  345. if (splayCount != this.splayCount) {
  346. this.splay(key);
  347. }
  348. this.root = this.root.replaceValue(newValue);
  349. this.splayCount += 1;
  350. return newValue;
  351. }
  352. if (ifAbsent != null) {
  353. const modificationCount = this.modificationCount;
  354. const splayCount = this.splayCount;
  355. const newValue = ifAbsent();
  356. if (modificationCount != this.modificationCount) {
  357. throw "Concurrent modification during iteration.";
  358. }
  359. if (splayCount != this.splayCount) {
  360. comp = this.splay(key);
  361. }
  362. this.addNewRoot(new SplayTreeMapNode(key, newValue), comp);
  363. return newValue;
  364. }
  365. throw "Invalid argument (key): Key not in map.";
  366. }
  367. updateAll(update) {
  368. const root = this.root;
  369. if (root == null) return;
  370. const iterator = new SplayTreeMapEntryIterableIterator(this.wrap());
  371. let node;
  372. while (node = iterator.next(), !node.done) {
  373. const newValue = update(...node.value);
  374. iterator.replaceValue(newValue);
  375. }
  376. }
  377. keys() {
  378. return new SplayTreeKeyIterableIterator(this.wrap());
  379. }
  380. values() {
  381. return new SplayTreeValueIterableIterator(this.wrap());
  382. }
  383. entries() {
  384. return this[Symbol.iterator]();
  385. }
  386. [Symbol.iterator]() {
  387. return new SplayTreeMapEntryIterableIterator(this.wrap());
  388. }
  389. [Symbol.toStringTag] = "[object Map]";
  390. };
  391. var SplayTreeSet = class _SplayTreeSet extends SplayTree {
  392. root = null;
  393. compare;
  394. validKey;
  395. constructor(compare, isValidKey) {
  396. super();
  397. this.compare = compare ?? this.defaultCompare();
  398. this.validKey = isValidKey ?? ((v) => v != null && v != void 0);
  399. }
  400. delete(element) {
  401. if (!this.validKey(element)) return false;
  402. return this._delete(element) != null;
  403. }
  404. deleteAll(elements) {
  405. for (const element of elements) {
  406. this.delete(element);
  407. }
  408. }
  409. forEach(f) {
  410. const nodes = this[Symbol.iterator]();
  411. let result;
  412. while (result = nodes.next(), !result.done) {
  413. f(result.value, result.value, this);
  414. }
  415. }
  416. add(element) {
  417. const compare = this.splay(element);
  418. if (compare != 0) this.addNewRoot(new SplayTreeSetNode(element), compare);
  419. return this;
  420. }
  421. addAndReturn(element) {
  422. const compare = this.splay(element);
  423. if (compare != 0) this.addNewRoot(new SplayTreeSetNode(element), compare);
  424. return this.root.key;
  425. }
  426. addAll(elements) {
  427. for (const element of elements) {
  428. this.add(element);
  429. }
  430. }
  431. isEmpty() {
  432. return this.root == null;
  433. }
  434. isNotEmpty() {
  435. return this.root != null;
  436. }
  437. single() {
  438. if (this.size == 0) throw "Bad state: No element";
  439. if (this.size > 1) throw "Bad state: Too many element";
  440. return this.root.key;
  441. }
  442. first() {
  443. if (this.size == 0) throw "Bad state: No element";
  444. return this._first().key;
  445. }
  446. last() {
  447. if (this.size == 0) throw "Bad state: No element";
  448. return this._last().key;
  449. }
  450. lastBefore(element) {
  451. if (element == null) throw "Invalid arguments(s)";
  452. if (this.root == null) return null;
  453. const comp = this.splay(element);
  454. if (comp < 0) return this.root.key;
  455. let node = this.root.left;
  456. if (node == null) return null;
  457. let nodeRight = node.right;
  458. while (nodeRight != null) {
  459. node = nodeRight;
  460. nodeRight = node.right;
  461. }
  462. return node.key;
  463. }
  464. firstAfter(element) {
  465. if (element == null) throw "Invalid arguments(s)";
  466. if (this.root == null) return null;
  467. const comp = this.splay(element);
  468. if (comp > 0) return this.root.key;
  469. let node = this.root.right;
  470. if (node == null) return null;
  471. let nodeLeft = node.left;
  472. while (nodeLeft != null) {
  473. node = nodeLeft;
  474. nodeLeft = node.left;
  475. }
  476. return node.key;
  477. }
  478. retainAll(elements) {
  479. const retainSet = new _SplayTreeSet(this.compare, this.validKey);
  480. const modificationCount = this.modificationCount;
  481. for (const object of elements) {
  482. if (modificationCount != this.modificationCount) {
  483. throw "Concurrent modification during iteration.";
  484. }
  485. if (this.validKey(object) && this.splay(object) == 0) {
  486. retainSet.add(this.root.key);
  487. }
  488. }
  489. if (retainSet.size != this.size) {
  490. this.root = retainSet.root;
  491. this.size = retainSet.size;
  492. this.modificationCount++;
  493. }
  494. }
  495. lookup(object) {
  496. if (!this.validKey(object)) return null;
  497. const comp = this.splay(object);
  498. if (comp != 0) return null;
  499. return this.root.key;
  500. }
  501. intersection(other) {
  502. const result = new _SplayTreeSet(this.compare, this.validKey);
  503. for (const element of this) {
  504. if (other.has(element)) result.add(element);
  505. }
  506. return result;
  507. }
  508. difference(other) {
  509. const result = new _SplayTreeSet(this.compare, this.validKey);
  510. for (const element of this) {
  511. if (!other.has(element)) result.add(element);
  512. }
  513. return result;
  514. }
  515. union(other) {
  516. const u = this.clone();
  517. u.addAll(other);
  518. return u;
  519. }
  520. clone() {
  521. const set = new _SplayTreeSet(this.compare, this.validKey);
  522. set.size = this.size;
  523. set.root = this.copyNode(this.root);
  524. return set;
  525. }
  526. copyNode(node) {
  527. if (node == null) return null;
  528. function copyChildren(node2, dest) {
  529. let left;
  530. let right;
  531. do {
  532. left = node2.left;
  533. right = node2.right;
  534. if (left != null) {
  535. const newLeft = new SplayTreeSetNode(left.key);
  536. dest.left = newLeft;
  537. copyChildren(left, newLeft);
  538. }
  539. if (right != null) {
  540. const newRight = new SplayTreeSetNode(right.key);
  541. dest.right = newRight;
  542. node2 = right;
  543. dest = newRight;
  544. }
  545. } while (right != null);
  546. }
  547. const result = new SplayTreeSetNode(node.key);
  548. copyChildren(node, result);
  549. return result;
  550. }
  551. toSet() {
  552. return this.clone();
  553. }
  554. entries() {
  555. return new SplayTreeSetEntryIterableIterator(this.wrap());
  556. }
  557. keys() {
  558. return this[Symbol.iterator]();
  559. }
  560. values() {
  561. return this[Symbol.iterator]();
  562. }
  563. [Symbol.iterator]() {
  564. return new SplayTreeKeyIterableIterator(this.wrap());
  565. }
  566. [Symbol.toStringTag] = "[object Set]";
  567. };
  568. var SplayTreeIterableIterator = class {
  569. tree;
  570. path = new Array();
  571. modificationCount = null;
  572. splayCount;
  573. constructor(tree) {
  574. this.tree = tree;
  575. this.splayCount = tree.getSplayCount();
  576. }
  577. [Symbol.iterator]() {
  578. return this;
  579. }
  580. next() {
  581. if (this.moveNext()) return { done: false, value: this.current() };
  582. return { done: true, value: null };
  583. }
  584. current() {
  585. if (!this.path.length) return null;
  586. const node = this.path[this.path.length - 1];
  587. return this.getValue(node);
  588. }
  589. rebuildPath(key) {
  590. this.path.splice(0, this.path.length);
  591. this.tree.splay(key);
  592. this.path.push(this.tree.getRoot());
  593. this.splayCount = this.tree.getSplayCount();
  594. }
  595. findLeftMostDescendent(node) {
  596. while (node != null) {
  597. this.path.push(node);
  598. node = node.left;
  599. }
  600. }
  601. moveNext() {
  602. if (this.modificationCount != this.tree.getModificationCount()) {
  603. if (this.modificationCount == null) {
  604. this.modificationCount = this.tree.getModificationCount();
  605. let node2 = this.tree.getRoot();
  606. while (node2 != null) {
  607. this.path.push(node2);
  608. node2 = node2.left;
  609. }
  610. return this.path.length > 0;
  611. }
  612. throw "Concurrent modification during iteration.";
  613. }
  614. if (!this.path.length) return false;
  615. if (this.splayCount != this.tree.getSplayCount()) {
  616. this.rebuildPath(this.path[this.path.length - 1].key);
  617. }
  618. let node = this.path[this.path.length - 1];
  619. let next = node.right;
  620. if (next != null) {
  621. while (next != null) {
  622. this.path.push(next);
  623. next = next.left;
  624. }
  625. return true;
  626. }
  627. this.path.pop();
  628. while (this.path.length && this.path[this.path.length - 1].right === node) {
  629. node = this.path.pop();
  630. }
  631. return this.path.length > 0;
  632. }
  633. };
  634. var SplayTreeKeyIterableIterator = class extends SplayTreeIterableIterator {
  635. getValue(node) {
  636. return node.key;
  637. }
  638. };
  639. var SplayTreeSetEntryIterableIterator = class extends SplayTreeIterableIterator {
  640. getValue(node) {
  641. return [node.key, node.key];
  642. }
  643. };
  644. var SplayTreeValueIterableIterator = class extends SplayTreeIterableIterator {
  645. constructor(map) {
  646. super(map);
  647. }
  648. getValue(node) {
  649. return node.value;
  650. }
  651. };
  652. var SplayTreeMapEntryIterableIterator = class extends SplayTreeIterableIterator {
  653. constructor(map) {
  654. super(map);
  655. }
  656. getValue(node) {
  657. return [node.key, node.value];
  658. }
  659. replaceValue(value) {
  660. if (this.modificationCount != this.tree.getModificationCount()) {
  661. throw "Concurrent modification during iteration.";
  662. }
  663. if (this.splayCount != this.tree.getSplayCount()) {
  664. this.rebuildPath(this.path[this.path.length - 1].key);
  665. }
  666. const last = this.path.pop();
  667. const newLast = last.replaceValue(value);
  668. if (!this.path.length) {
  669. this.tree.setRoot(newLast);
  670. } else {
  671. const parent = this.path[this.path.length - 1];
  672. if (last === parent.left) {
  673. parent.left = newLast;
  674. } else {
  675. parent.right = newLast;
  676. }
  677. }
  678. this.path.push(newLast);
  679. const count = this.tree.getSplayCount() + 1;
  680. this.tree.setSplayCount(count);
  681. this.splayCount = count;
  682. }
  683. };
  684. export {
  685. SplayTreeMap,
  686. SplayTreeSet
  687. };
  688. //# sourceMappingURL=index.js.map