linked-index.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /**
  2. * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. /** A data structure useful for graph traversal */
  7. interface LinkedIndex {
  8. readonly head: number,
  9. has(i: number): boolean,
  10. remove(i: number): void
  11. }
  12. function LinkedIndex(size: number): LinkedIndex {
  13. return new LinkedIndexImpl(size);
  14. }
  15. class LinkedIndexImpl implements LinkedIndex {
  16. private prev: Int32Array;
  17. private next: Int32Array;
  18. head: number;
  19. remove(i: number) {
  20. const { prev, next } = this;
  21. const p = prev[i], n = next[i];
  22. if (p >= 0) {
  23. next[p] = n;
  24. prev[i] = -1;
  25. }
  26. if (n >= 0) {
  27. prev[n] = p;
  28. next[i] = -1;
  29. }
  30. if (i === this.head) {
  31. if (p < 0) this.head = n;
  32. else this.head = p;
  33. }
  34. }
  35. has(i: number) {
  36. return this.prev[i] >= 0 || this.next[i] >= 0 || this.head === i;
  37. }
  38. constructor(size: number) {
  39. this.head = size > 0 ? 0 : -1;
  40. this.prev = new Int32Array(size);
  41. this.next = new Int32Array(size);
  42. for (let i = 0; i < size; i++) {
  43. this.next[i] = i + 1;
  44. this.prev[i] = i - 1;
  45. }
  46. this.prev[0] = -1;
  47. this.next[size - 1] = -1;
  48. }
  49. }
  50. export default LinkedIndex;