location.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { Address } from "./address";
  2. class LocationHolder {
  3. public data: Address[];
  4. private address_id: number
  5. constructor () {
  6. this.data = [];
  7. this.address_id = 0;
  8. }
  9. /**
  10. *
  11. * @param {*} value the value to be allocated
  12. * @returns {Number} - the address id
  13. */
  14. allocate (value:any) : number {
  15. const id = this.address_id;
  16. const address = new Address(id, value);
  17. this.data.push(address);
  18. this.address_id += 1;
  19. return id;
  20. }
  21. /**
  22. *
  23. * @param {Number} id
  24. */
  25. deallocate (id: number) : boolean {
  26. const index = this.findIndex(id);
  27. // console.log("Deallocation address "+ id);
  28. if(index !== -1) {
  29. this.data.splice(index, 1);
  30. return true;
  31. }
  32. return false;
  33. }
  34. /**
  35. *
  36. * @param {Number} id
  37. * @returns {Address} the address identified by id
  38. */
  39. find (id: number): Address | null {
  40. let beg = 0
  41. let end = this.data.length;
  42. // console.log("Finding address "+id);
  43. while (beg < end) {
  44. const med = Math.floor((beg + end)/2);
  45. const address = this.getAddressAt(med);
  46. if(address.id === id) {
  47. return address;
  48. } else if (id > address.id) {
  49. beg = med;
  50. } else {
  51. end = med
  52. }
  53. }
  54. return null;
  55. }
  56. getAddressAt (pos: number): Address {
  57. return this.data[pos];
  58. }
  59. /**
  60. *
  61. * @param {Number} id address id
  62. * @returns {Number} the index of the address identified by id
  63. */
  64. findIndex (id: number) : number {
  65. let beg = 0
  66. let end = this.data.length;
  67. while (beg < end) {
  68. const med = Math.floor((beg + end)/2);
  69. const address = this.getAddressAt(med);
  70. if(address.id === id) {
  71. return med;
  72. } else if (id > address.id) {
  73. beg = med;
  74. } else {
  75. end = med
  76. }
  77. }
  78. return -1;
  79. }
  80. updateAddress (id: number, value: any, is_var = false): void {
  81. const index = this.findIndex(id);
  82. if(index === -1) {
  83. throw new Error("Invalid address..." + id);
  84. }
  85. this.data[index].value = value;
  86. this.data[index].is_var = is_var;
  87. }
  88. clear () {
  89. for (let i = 0; i < this.data.length; i += 1) {
  90. delete this.data[i];
  91. }
  92. this.data = [];
  93. this.address_id = 0;
  94. }
  95. gc (): number {
  96. const to_remove = [];
  97. for (let i = 0; i < this.data.length; i += 1) {
  98. const address = this.data[i];
  99. if (!address.is_var) {
  100. to_remove.push(address.id);
  101. }
  102. }
  103. to_remove.forEach(x => this.deallocate(x), this);
  104. return to_remove.length;
  105. }
  106. }
  107. const inner_ref = new LocationHolder();
  108. export const Location = Object.freeze({
  109. allocate: inner_ref.allocate.bind(inner_ref),
  110. deallocate: inner_ref.deallocate.bind(inner_ref),
  111. find: inner_ref.find.bind(inner_ref),
  112. updateAddress: inner_ref.updateAddress.bind(inner_ref),
  113. clear: inner_ref.clear.bind(inner_ref),
  114. gc: inner_ref.gc.bind(inner_ref),
  115. size: () => inner_ref.data.length
  116. });