fe944750 |
import { |
b681b265 |
findIndex, map, propEq, reduce,
reverse, prop, flatten, uniq, reject, contains, omit |
fe944750 |
} from 'rambda';
import type { JobId } from '../../types'; |
b681b265 |
import { max, remove } from 'ramda'; |
fe944750 |
type JobTime = {
jobId: JobId, |
8c7841d1 |
name: string, |
fe944750 |
t: number,
d: number,
w: number,
anc: JobId[],
};
const findMinJob = (fi: number, jobTimes: JobTime[]) =>
reduce(
(minJob: JobTime, jobTime: JobTime) => {
const minJobU = minJob.w * max(fi - minJob.d, 0);
const jobTimeU = jobTime.w * max(fi - jobTime.d, 0);
return minJobU < jobTimeU ? minJob : jobTime;
},
{ w: Infinity },
jobTimes
);
const updateCTime = (jobTimes: JobTime[]) => {
let prev = 0;
const cj = map((jobTime: JobTime) => {
prev += jobTime.t;
return { ...jobTime, c: prev };
}, jobTimes);
return cj;
};
|
b681b265 |
const fillCorrupted = (jobs: JobTime[]) => map(
({ d, w, anc, ...rest }) => ({ ...rest, d: d || 1000, w: w || 1, anc: anc || [] }),
jobs);
|
fe944750 |
export const createSchedule = (jobs: JobTime[]) => { |
b681b265 |
jobs = fillCorrupted(jobs);
|
fe944750 |
let fi = reduce((sum, job: JobTime) => sum + job.t, 0, jobs);
let jobsD = jobs;
let R = [];
while (fi > 0) {
const allAcc = uniq(flatten(
map(prop('anc'), jobsD)
));
const G = reject((jobTime: JobTime) => contains(jobTime.jobId, allAcc), jobsD);
if (!G.length) return null;
const minJob = findMinJob(fi, G);
const minJobIndex = findIndex(propEq('jobId', minJob.jobId), jobsD);
jobsD = remove(minJobIndex, 1, jobsD);
fi -= minJob.t;
R.push(minJob);
}
const withC = updateCTime(reverse(R));
return map(omit(['w', 'anc']), withC);
};
export default (jobs: JobTime[]) => {
const schedule = createSchedule(jobs);
|
b681b265 |
if (!schedule) return null;
|
fe944750 |
const normalizedSchedule = map((jobTime: JobTime) => ({
processor: 1,
startTime: jobTime.c - jobTime.t,
endTime: jobTime.c, |
8c7841d1 |
delayed: max(0, jobTime.c - jobTime.d),
name: jobTime.name |
fe944750 |
}), schedule);
return [normalizedSchedule];
}; |