import { SegmentsSet } from './segment_set'; import { Segment, SegmentId } from './segment'; export class SegmentArray implements SegmentsSet { private _segments: T[]; private _keyToSegment: Map = new Map(); constructor(private segments?: T[]) { this.setSegments(segments); } getSegments(from?: number, to?: number): T[] { if(from === undefined) { from = -Infinity; } if(to === undefined) { to = Infinity; } const result = []; for(let i = 0; i < this._segments.length; i++) { const s = this._segments[i]; if(from <= s.from && s.to <= to) { result.push(s); } } return result; } setSegments(segments: T[]) { this._segments = []; this._keyToSegment.clear(); if(segments) { segments.forEach(s => { this.addSegment(s); }); } } addSegment(segment: T) { if(this.has(segment.id)) { throw new Error(`Segment with key ${segment.id} exists in set`); } this._keyToSegment.set(segment.id, segment); this._segments.push(segment); } findSegments(point: number, rangeDist: number): T[] { return this._segments.filter(s => { const expanded = s.expandDist(rangeDist, 0.01); return (expanded.from <= point) && (point <= expanded.to); }); } removeInRange(from: number, to: number): T[] { const deleted = []; const newSegments = []; for(let i = 0; i < this._segments.length; i++) { const s = this._segments[i]; if(from <= s.from && s.to <= to) { this._keyToSegment.delete(s.id); deleted.push(s); } else { newSegments.push(s); } } this._segments = newSegments; return deleted; } get length() { return this._segments.length; } clear() { this._segments = []; this._keyToSegment.clear(); } has(key: SegmentId): boolean { return this._keyToSegment.has(key); } remove(key: SegmentId): boolean { if(!this.has(key)) { return false; } const index = this._segments.findIndex(s => s.id === key); this._segments.splice(index, 1); this._keyToSegment.delete(key); return true; } updateId(fromKey: SegmentId, toKey: SegmentId) { const segment = this._keyToSegment.get(fromKey); this._keyToSegment.delete(fromKey); segment.id = toKey; this._keyToSegment.set(toKey, segment); } }