Skip to content

Commit f0d4068

Browse files
Refactor session overlap computation to treat overlapping sessions correctly. Commit ready for merge.
- Legacy-Id: 19954
1 parent 8fd6f33 commit f0d4068

1 file changed

Lines changed: 45 additions & 33 deletions

File tree

ietf/static/ietf/js/edit-meeting-schedule.js

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -552,10 +552,43 @@ jQuery(document).ready(function () {
552552

553553
// hints for the current schedule
554554

555+
/** Find all pairs of overlapping intervals
556+
*
557+
* @param data Array of arbitrary interval-like objects with 'start' and 'end' properties
558+
* @returns Map from data item index to a list of overlapping data item indexes
559+
*/
560+
function findOverlappingIntervals(data) {
561+
const overlaps = {}; // results
562+
// Build ordered lists of start/end times, keeping track of the original index for each item
563+
const startIndexes = data.map((d, i) => ({time: d.start, index: i}));
564+
startIndexes.sort((a, b) => (b.time - a.time)); // sort reversed
565+
const endIndexes = data.map((d, i) => ({time: d.end, index: i}));
566+
endIndexes.sort((a, b) => (b.time - a.time)); // sort reversed
567+
568+
// items are sorted in reverse, so pop() will get the earliest item from each list
569+
let nextStart = startIndexes.pop();
570+
let nextEnd = endIndexes.pop();
571+
const openIntervalIndexes = [];
572+
while (nextStart && nextEnd) {
573+
if (nextStart.time < nextEnd.time) {
574+
// an interval opened - it overlaps all open intervals and all open intervals overlap it
575+
for (const intervalIndex of openIntervalIndexes) {
576+
overlaps[intervalIndex].push(nextStart.index);
577+
}
578+
overlaps[nextStart.index] = [...openIntervalIndexes]; // make a copy of the open list
579+
openIntervalIndexes.push(nextStart.index);
580+
nextStart = startIndexes.pop();
581+
} else {
582+
// an interval closed - remove its index from the list of open intervals
583+
openIntervalIndexes.splice(openIntervalIndexes.indexOf(nextEnd.index), 1);
584+
nextEnd = endIndexes.pop();
585+
}
586+
}
587+
return overlaps;
588+
}
589+
555590
function updateSessionConstraintViolations() {
556-
// do a sweep on sessions sorted by start time
557591
let scheduledSessions = [];
558-
559592
sessions.each(function () {
560593
let timeslot = jQuery(this).closest(".timeslot");
561594
if (timeslot.length === 1) {
@@ -569,19 +602,8 @@ jQuery(document).ready(function () {
569602
}
570603
});
571604

572-
scheduledSessions.sort(function (a, b) {
573-
if (a.start < b.start) {
574-
return -1;
575-
}
576-
if (a.start > b.start) {
577-
return 1;
578-
}
579-
return 0;
580-
});
581-
582-
let currentlyOpen = {};
583-
let openedIndex = 0;
584-
let markSessionConstraintViolations = function (sess, currentlyOpen) {
605+
// helper function to mark constraint violations
606+
const markSessionConstraintViolations = function (sess, currentlyOpen) {
585607
sess.element.find(".constraints > span").each(function() {
586608
let sessionIds = this.dataset.sessions;
587609

@@ -600,25 +622,15 @@ jQuery(document).ready(function () {
600622
});
601623
};
602624

603-
for (let i = 0; i < scheduledSessions.length; ++i) {
604-
let s = scheduledSessions[i];
605-
606-
// prune
607-
for (let sessionIdStr in currentlyOpen) {
608-
if (currentlyOpen[sessionIdStr].end <= s.start) {
609-
delete currentlyOpen[sessionIdStr];
610-
}
611-
}
612-
613-
// expand
614-
while (openedIndex < scheduledSessions.length && scheduledSessions[openedIndex].start < s.end) {
615-
let toAdd = scheduledSessions[openedIndex];
616-
currentlyOpen[toAdd.id] = toAdd;
617-
++openedIndex;
625+
// now go through the sessions and mark constraint violations
626+
const overlaps = findOverlappingIntervals(scheduledSessions);
627+
for (const index in overlaps) {
628+
const currentlyOpen = {};
629+
for (const overlapIndex of overlaps[index]) {
630+
const otherSess = scheduledSessions[overlapIndex];
631+
currentlyOpen[otherSess.id] = otherSess;
618632
}
619-
620-
// check for violated constraints
621-
markSessionConstraintViolations(s, currentlyOpen);
633+
markSessionConstraintViolations(scheduledSessions[index], currentlyOpen);
622634
}
623635
}
624636

0 commit comments

Comments
 (0)