if (m==null) return null;
// figure out how many executors we need on each computer?
Map<Computer,Integer> footprint = new HashMap<Computer, Integer>();
for (Entry<WorkChunk, ExecutorChunk> e : m.toMap().entrySet()) {
Computer c = e.getValue().computer;
Integer v = footprint.get(c);
if (v==null) v = 0;
v += e.getKey().size();
footprint.put(c,v);
}
// the point of a tentative plan is to displace other jobs to create a point in time
// where this task can start executing. An incorrectly estimated duration is not
// a problem in this regard, as we just need enough idle executors in the right moment.
// The downside of guessing the duration wrong is that we can end up creating tentative plans
// afterward that may be incorrect, but those plans will be rebuilt.
long d = bi.task.getEstimatedDuration();
if (d<=0) d = TimeUnit2.MINUTES.toMillis(5);
TimeRange slot = new TimeRange(System.currentTimeMillis(), d);
// now, based on the real predicted loads, figure out the approximation of when we can
// start executing this guy.
for (Entry<Computer, Integer> e : footprint.entrySet()) {
Computer computer = e.getKey();
Timeline timeline = new Timeline();
for (LoadPredictor lp : LoadPredictor.all()) {
for (FutureLoad fl : Iterables.limit(lp.predict(worksheet, computer, slot.start, slot.end),100)) {
timeline.insert(fl.startTime, fl.startTime+fl.duration, fl.numExecutors);
}
}
Long x = timeline.fit(slot.start, slot.duration, computer.countExecutors()-e.getValue());
// if no suitable range was found in [slot.start,slot.end), slot.end would be a good approximation
if (x==null) x = slot.end;
slot = slot.shiftTo(x);
}