import { addIndex, findIndex, find, map, propEq, reduce, sort, range, concat } from 'rambda'; import type { JobId } from '../../types'; import { remove, slice } from 'ramda'; type JobTime = { jobId: JobId, t: number, d: number, c: number }; const mapWithIndex = addIndex(map); // const byAsc = (a: JobTime, b: JobTime) => a.time - b.time; const findJobById = (jobId: JobId, jobTimes: JobTime[]): JobTime => find(propEq('jobId', jobId), jobTimes); const findLateJob = (jobTimes: JobTime[]) => find(({ c, d }: JobTime) => c > d, jobTimes); const findMaxTJob = (jobTimes: JobTime[]) => reduce( (maxTJob: JobTime, jobTime: JobTime) => maxTJob.t > jobTime.t ? maxTJob : jobTime, { t: -Infinity }, jobTimes ); const updateCTime = (jobTimes: JobTime[]) => { let prev = 0; const cj = map((jobTime: JobTime) => { prev += jobTime.t; return { ...jobTime, c: prev }; }, jobTimes); return cj; }; export const createSchedule = (jobs: JobTime[]) => { const F = sort((a: JobTime, b: JobTime) => a.d - b.d, jobs); const L = []; let cj = updateCTime(F); let lateJob; while (lateJob = findLateJob(cj)) { const lateJobIndex = findIndex(propEq('jobId', lateJob.jobId), cj); const jobsBeforeLateJob = slice(0, lateJobIndex + 1, cj); const maxTJob = findMaxTJob(jobsBeforeLateJob); const maxTJobIndex = findIndex(propEq('jobId', maxTJob.jobId), cj); cj = remove(maxTJobIndex, 1, cj); cj = updateCTime(cj); L.push(maxTJob); } const schedule = concat(cj, L); return updateCTime(schedule); }; export default (jobs: JobTime[]) => { const schedule = createSchedule(jobs); const normalizedSchedule = map((jobTime: JobTime) => ({ processor: 1, startTime: jobTime.c - jobTime.t, endTime: jobTime.c, }), schedule); return [normalizedSchedule]; };