import { Address } from "./address"; class LocationHolder { public data: Address[]; private address_id: number constructor () { this.data = []; this.address_id = 0; } /** * * @param {never} value the value to be allocated * @returns {number} - the address id */ allocate (value: unknown): number { const id = this.address_id; // console.log("Allocation address "+ id); const address = new Address(id, value); this.data.push(address); this.address_id += 1; return id; } /** * * @param {number} id */ deallocate (id: number): boolean { const index = this.findIndex(id); // console.log("Deallocation address "+ id); if(index !== -1) { this.data.splice(index, 1); return true; } return false; } /** * * @param {number} id * @returns {Address} the address identified by id */ find (id: number): Address | undefined { let beg = 0 let end = this.data.length; // console.log("Finding address "+id); while (beg < end) { const med = Math.floor((beg + end)/2); const address = this.getAddressAt(med); if(address.id === id) { return address; } else if (id > address.id) { beg = med; } else { end = med } } return undefined; } getAddressAt (pos: number): Address { return this.data[pos]; } /** * * @param {number} id address id * @returns {number} the index of the address identified by id */ findIndex (id: number): number { let beg = 0 let end = this.data.length; while (beg < end) { const med = Math.floor((beg + end)/2); const address = this.getAddressAt(med); if(address.id === id) { return med; } else if (id > address.id) { beg = med; } else { end = med } } return -1; } updateAddress (id: number, value: unknown): void { const index = this.findIndex(id); if(index === -1) { throw new Error("Invalid address..." + id); } this.data[index].value = value; } clear (): void { for (let i = 0; i < this.data.length; i += 1) { delete this.data[i]; } this.data = []; this.address_id = 0; } } const inner_ref = new LocationHolder(); export const Location = Object.freeze({ allocate: inner_ref.allocate.bind(inner_ref), deallocate: inner_ref.deallocate.bind(inner_ref), find: inner_ref.find.bind(inner_ref), updateAddress: inner_ref.updateAddress.bind(inner_ref), clear: inner_ref.clear.bind(inner_ref), size: () => inner_ref.data.length });