Skip to content

Commit

Permalink
scheduling conflicts are now calculated for coincidence as well
Browse files Browse the repository at this point in the history
  • Loading branch information
kneerunjun committed Aug 1, 2021
1 parent 5de802a commit 9e78fb9
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 36 deletions.
41 changes: 21 additions & 20 deletions patchsched.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,28 @@ func (pas *patchSchedule) ToTask() (Trigger, Trigger, int, int) {

// Please be ware here another cannot be a primary schedule
func (pas *patchSchedule) ConflictsWith(another Schedule) bool {
// Here schedules with same time slot (subset, overlaps, coincide) cannot have the same relays
// if they have disjoint relays to work on.. then all of the above is allowed
// for patch schedule, it cannot overlap / coincide with primary schedule
_, inside, overlap := overlapsWith(pas, another)
if inside {
another.AddDelay(pas.Delay())
}
if overlap {
_, ok := another.(*patchSchedule)
if ok {
// patch schedule when being assesed with othe patch schedule ..
// 2 patch schedules can have overlaps incase they are operating on different relays
anLw, _ := another.Triggers()
if pas.lower.Intersects(anLw, false) {
// Overlaps and also intersects .. so conflict
return true
// https://eensymachines-in.github.io/luminapi/schedule-conflicts
// Read here patch schedules conflict with other patch schedules only in the case of overlap and intersection
// in all other cases if the schedules are delayed incase of intersection
outside, inside, overlap, coinc := overlapsWith(pas, another)
// Getting if there's an intersection on the relays
anLw, _ := another.Triggers()
intersects := pas.lower.Intersects(anLw, false)
if inside || outside || coinc {
// Delay is added only if schedule intersects
if intersects {
// Delay is added to that schedule that comes later in the day
if another.Midpoint() > pas.Midpoint() {
another.AddDelay(pas.Delay())
} else {
pas.AddDelay(another.Delay())
}
// Overlaps but has no intersection
return false
}
return true // if overlaps and it isnt another patch schedule then there is conflict
return false
}
if overlap && intersects {
_, ok := another.(*patchSchedule)
return ok // if the schedule type is not patchSchedule conflict cannot be determined
}
return false // if there isnt any overlap then outright there isnt any conflict
return false // if the schedules either does not overlap or does not intersect
}
7 changes: 4 additions & 3 deletions primarysched.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (ps *primarySched) Close() {
log.Infof("%s Schedule is now closing", ps)
}
func (ps *primarySched) String() string {
return fmt.Sprintf("%s - %s %v %v", TmStrFromUnixSecs(ps.lower.At()), TmStrFromUnixSecs(ps.higher.At()), ps.lower.RelayIDs(), ps.higher.RelayIDs())
return fmt.Sprintf("%s - %s %v ", TmStrFromUnixSecs(ps.lower.At()), TmStrFromUnixSecs(ps.higher.At()), ps.lower.RelayIDs())
}

// NearFarTrigger : in context of the current time, this helps to get the triggers that are near or far
Expand Down Expand Up @@ -81,8 +81,9 @@ func (ps *primarySched) ConflictsWith(another Schedule) bool {
// overlaps are checked for circular and non-cicrular schedule
return true
}
outside, inside, overlap := overlapsWith(ps, another)
if outside || inside {
// When comparing with primary schedule all that matters is if the schedule is not overlapping
outside, inside, overlap, coinc := overlapsWith(ps, another)
if outside || inside || coinc {
// When its the primary schedule the patch schedule will always be given proceedence
another.AddDelay(ps.Delay())
}
Expand Down
9 changes: 5 additions & 4 deletions sch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func TestWriteSchedules(t *testing.T) {
if err != nil {
panic(err)
}
return
}

func TestScheduleConflicts(t *testing.T) {
Expand Down Expand Up @@ -143,15 +142,17 @@ func TestScheduleLoop(t *testing.T) {
}

func TestOverlappingSchedules(t *testing.T) {
scheds, err := ReadScheduleFile("test_sched3.json")
scheds, err := ReadScheduleFile("test_sched4.json")
if err != nil {
t.Error(err)
panic("TestReadSchedules: error reading schedule files")
}
for i, s := range scheds {
for _, ss := range scheds[i+1:] {
ou, in, ov := overlapsWith(s, ss)
t.Logf("outside: %t, inside: %t, overlap: %t", ou, in, ov)
ou, in, ov, co := overlapsWith(s, ss)
t.Logf("%s/%d-%s/%d", s, s.Delay(), ss, ss.Delay())
t.Logf("outside: %t, inside: %t, overlap: %t, coincide: %t", ou, in, ov, co)
t.Logf("Conflicts: %t", s.ConflictsWith(ss))
}
}
}
Expand Down
22 changes: 17 additions & 5 deletions sched.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ func Loop(sch Schedule, cancel, interrupt chan interface{}, send chan []byte, er
}

// overlapsWith : is the function for basis of identifying the conflicts in any 2 schedules
func overlapsWith(left, right Schedule) (bool, bool, bool) {
var outside, inside, overlap bool
func overlapsWith(left, right Schedule) (bool, bool, bool, bool) {
var outside, inside, overlap, coincide bool
// Midpoints are distance of the half time since midnight for any schedule
mdpt1, mdpt2 := left.Midpoint(), right.Midpoint()
// half duration of each schedule
Expand All @@ -152,12 +152,24 @@ func overlapsWith(left, right Schedule) (bool, bool, bool) {
} else {
min, max = hfdur2, hfdur1
}
if outside, inside = (mdptdis > (hfdur1 + hfdur2)), ((mdptdis + min) < max); outside || inside {
// https://eensymachines-in.github.io/luminapi/schedule-conflicts
// https://github.com/eensymachines-in/scheduling/issues/3
outside = (mdptdis > (hfdur1 + hfdur2))
inside = ((mdptdis + min) < max)
if outside || inside {
// this means its completely outside or completely inside
overlap = false
} else {
overlap = true
if (mdptdis == hfdur1+hfdur2) || (mdptdis+min == max) {
// is the case of coincidence but not overlap
coincide = true
overlap = false
} else {
// None of the cases and hence the schedules are overlapping
overlap = true
}
}
return outside, inside, overlap
return outside, inside, overlap, coincide
}

// JSONRelayState : relaystate but in json format
Expand Down
6 changes: 2 additions & 4 deletions test_sched3.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"schedules": [
{"on":"06:20 PM", "off":"06:00 AM","primary":true, "ids":["IN1","IN2","IN3","IN4"]},
{"on":"07:35 PM", "off":"08:00 PM","primary":false, "ids":["IN4"]},
{"on":"07:45 PM", "off":"07:40 PM","primary":false, "ids":["IN4"]},
{"on":"08:01 PM", "off":"08:30 PM","primary":false, "ids":["IN4"]},
{"on":"07:45 PM", "off":"08:10 PM","primary":false, "ids":["IN1"]}
{"on":"07:35 PM", "off":"08:01 PM","primary":false, "ids":["IN3"]},
{"on":"06:20 PM", "off":"08:01 PM","primary":false, "ids":["IN3"]}
]
}
13 changes: 13 additions & 0 deletions test_sched4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"schedules": [
{"on":"06:20 PM", "off":"06:00 AM","primary":true, "ids":["IN1","IN2","IN3","IN4"]},
{"on":"07:35 PM", "off":"08:01 PM","primary":false, "ids":["IN3"]},
{"on":"06:20 PM", "off":"08:01 PM","primary":false, "ids":["IN3"]},

{"on":"04:35 AM", "off":"05:01 AM","primary":false, "ids":["IN4"]},
{"on":"04:35 AM", "off":"07:00 AM","primary":false, "ids":["IN1"]},

{"on":"04:20 PM", "off":"05:00 PM","primary":false, "ids":["IN2"]},
{"on":"04:20 PM", "off":"06:20 PM","primary":false, "ids":["IN3"]}
]
}

0 comments on commit 9e78fb9

Please sign in to comment.