import { ParkingGetterSetterRepository } from "./ParkingGetterSetterRepository"; import { IParkingStructure, IParkingStructureTimestampRecord } from "../entities/ParkingRepositoryEntities"; import { HistoricalParkingAverageQueryResult } from "./ParkingGetterRepository"; import { CircularQueue } from "../types/CircularQueue"; export type ParkingStructureID = string; // Every 10 minutes // 6x per hour * 24x per day * 7x per week = 1008 entries for one week export const PARKING_LOGGING_INTERVAL_MS = 600000; // This will last two weeks export const MAX_NUM_ENTRIES = 2016; export class InMemoryParkingRepository implements ParkingGetterSetterRepository { private dataLastAdded: Map = new Map(); constructor( private structures: Map = new Map(), private historicalData: Map> = new Map(), ) { } addOrUpdateParkingStructure = async (structure: IParkingStructure): Promise => { this.structures.set(structure.id, { ...structure }); await this.addHistoricalDataForStructure(structure); }; private addHistoricalDataForStructure = async (structure: IParkingStructure): Promise => { const now = Date.now(); const lastAdded = this.dataLastAdded.get(structure.id); function parkingLoggingIntervalExceeded() { return !lastAdded || (now - lastAdded.getTime()) >= PARKING_LOGGING_INTERVAL_MS; } if (parkingLoggingIntervalExceeded()) { const timestampRecord: IParkingStructureTimestampRecord = { id: structure.id, spotsAvailable: structure.spotsAvailable, timestampMs: now, }; if (!this.historicalData.has(structure.id)) { this.historicalData.set(structure.id, new CircularQueue(MAX_NUM_ENTRIES)); } const sortingCallback = (a: IParkingStructureTimestampRecord, b: IParkingStructureTimestampRecord) => a.timestampMs - b.timestampMs; this.historicalData.get(structure.id)?.appendWithSorting(timestampRecord, sortingCallback); this.dataLastAdded.set(structure.id, new Date(now)); } } clearParkingStructureData = async (): Promise => { this.structures.clear(); }; getParkingStructureById = async (id: string): Promise => { const structure = this.structures.get(id); return structure ? { ...structure } : null; }; getParkingStructures = async (): Promise => Array.from(this.structures.values()).map(structure => ({...structure})); removeParkingStructureIfExists = async (id: string): Promise => { const structure = this.structures.get(id); if (structure) { this.structures.delete(id); return { ...structure }; } return null; }; getHistoricalAveragesOfParkingStructureCounts = async (id: string): Promise => { return []; }; }