You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

649 lines
18 KiB

package schedule
import (
"container/list"
"time"
)
type TimeCurveSrv struct {
StartTime time.Time // 时间曲线的起始时间点
EndTime time.Time // 时间曲线的结束时间点
EffFactor float64 // 效率因子
TimeLineArray []TimeLineSrv
TimeLineList *list.List
}
// 将时间数组转化成列表
func(tcs *TimeCurveSrv)GetLineList(){
var(
tlsrv TimeLineSrv
)
// 初始化
tcs.TimeLineList = list.New()
for _, tlsrv = range tcs.TimeLineArray {
tcs.TimeLineList.PushBack(&tlsrv)
}
}
// 将时间列表转化成数组
func(tcs *TimeCurveSrv)GetLineArray(){
var(
e *list.Element
tlsrv *TimeLineSrv
)
// 初始化数组
tcs.TimeLineArray = []TimeLineSrv{}
for e = tcs.TimeLineList.Front(); e != nil; e = e.Next() {
tlsrv = e.Value.(*TimeLineSrv)
tcs.TimeLineArray = append(tcs.TimeLineArray, *tlsrv)
}
}
// 获取某时间点在时间曲线上的位置(哪条时间线上)
func(tcs *TimeCurveSrv)GetTimeLine(tp time.Time) (node *list.Element, err error) {
var (
e *list.Element
tl, prevtl *TimeLineSrv
)
/** 如果结束时间点小于计划曲线的起始时间点
|-------------------|
*
*
*/
if tp.Unix() < tcs.StartTime.Unix() || tp.Unix() > tcs.EndTime.Unix() {
node = nil
return
}
for e = tcs.TimeLineList.Front(); e != nil; e = e.Next() {
tl = e.Value.(*TimeLineSrv)
if tp.Unix() >= tl.StartTime.Unix() && tp.Unix() <= tl.EndTime.Unix() {
node = e
return
}
// 如果正好落在两段时间之内不可用时段,则返回后面时段的位置
if e.Prev() != nil {
prevtl = e.Prev().Value.(*TimeLineSrv)
if tp.Unix() >= prevtl.EndTime.Unix() && tp.Unix() <= tl.StartTime.Unix() {
node = e
return
}
}
}
node = nil
return
}
// 删除指定时间线节点之后的所有节点
func (tcs *TimeCurveSrv)RemoveListAllAfterItem(delNode *list.Element, delItem bool) (err error) {
var (
e, el, next, n *list.Element
)
// 删除litem之后所有的节点
for e = tcs.TimeLineList.Front(); e != nil; e = e.Next() {
if delNode == e {
next = e.Next()
if delItem {
tcs.TimeLineList.Remove(e)
}
for el = next; el != nil; el = n {
n = el.Next()
tcs.TimeLineList.Remove(el)
}
break
}
}
return
}
// 删除指定时间线节点之前的所有节点
func (tcs *TimeCurveSrv)RemoveListAllBeforeItem(delNode *list.Element, delItem bool) (err error) {
var (
e, el, prev, p *list.Element
)
// 删除litem之前所有的节点
for e = tcs.TimeLineList.Front(); e != nil; e = e.Next() {
if delNode == e {
prev = e.Prev()
if delItem {
tcs.TimeLineList.Remove(e)
}
for el = prev; el != nil; el = p {
p = el.Prev()
tcs.TimeLineList.Remove(el)
}
break
}
}
return
}
// 增加工作时段
func(tcs *TimeCurveSrv)AddTimeLine(addtlsrv TimeLineSrv)(err error){
var (
tlsrv TimeLineSrv
tl, tlb, tle *TimeLineSrv
e, next, nodeBeg, nodeEnd *list.Element
)
if addtlsrv.EndTime.Unix() <= addtlsrv.StartTime.Unix() {
return
}
/** 如果结束时间点小于计划曲线的起始时间点
|-------------------|
<---->
*/
if addtlsrv.EndTime.Unix() <= tcs.StartTime.Unix() {
return
}
/** 如果计算起始时间点大于等于计划曲线的起始时间点
|--------------------|
<----------->
*/
if addtlsrv.StartTime.Unix() >= tcs.EndTime.Unix() {
return
}
/** |-------------------|
<--------------------------->
*/
if addtlsrv.StartTime.Unix() < tcs.StartTime.Unix() && addtlsrv.EndTime.Unix() > tcs.EndTime.Unix() {
tlsrv = TimeLineSrv{}
tlsrv.StartTime = addtlsrv.StartTime
tlsrv.EndTime = addtlsrv.EndTime
tlsrv.EffFactor = addtlsrv.EffFactor
tcs.TimeLineList.Init()
tcs.StartTime = addtlsrv.StartTime
tcs.EndTime = addtlsrv.EndTime
tcs.EffFactor = addtlsrv.EffFactor
tcs.TimeLineList.PushBack(&tlsrv)
return
}
/** |-------------------|
<------>
*/
if addtlsrv.StartTime.Unix() < tcs.StartTime.Unix() && addtlsrv.EndTime.Unix() > tcs.StartTime.Unix() && addtlsrv.EndTime.Unix() <= tcs.EndTime.Unix() {
if nodeEnd, err = tcs.GetTimeLine(addtlsrv.EndTime); err != nil {
return
}
if nodeEnd != nil {
tl = nodeEnd.Value.(*TimeLineSrv)
tl.StartTime = addtlsrv.StartTime
tcs.RemoveListAllBeforeItem(nodeEnd, false)
tcs.StartTime = addtlsrv.StartTime
} else {
// 删除时段内的节点
for e = tcs.TimeLineList.Front(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.StartTime.Unix() > addtlsrv.StartTime.Unix() && tl.EndTime.Unix() < addtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
}
}
tlsrv = TimeLineSrv{}
tlsrv.StartTime = addtlsrv.StartTime
tlsrv.EndTime = addtlsrv.EndTime
tlsrv.EffFactor = tcs.EffFactor
tcs.TimeLineList.PushFront(tlsrv)
tcs.StartTime = addtlsrv.StartTime
}
}
/** |-------------------|
<------>
*/
if addtlsrv.StartTime.Unix() >= tcs.StartTime.Unix() && addtlsrv.EndTime.Unix() <= tcs.EndTime.Unix() {
if nodeBeg, err = tcs.GetTimeLine(addtlsrv.StartTime); err != nil {
return
}
if nodeEnd, err = tcs.GetTimeLine(addtlsrv.EndTime); err != nil {
return
}
/** 落在可用时段内
情况一: |-------|
|****|
**/
if nodeBeg != nil && nodeEnd == nil {
tlb = nodeBeg.Value.(*TimeLineSrv)
// 删除开始节点之后到结束时间点之间的Node
for e = nodeBeg.Next(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.EndTime.Unix() <= addtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
} else {
break
}
}
// 更新开始节点的结束时间
tlb.EndTime = addtlsrv.EndTime
}
/**
情况二: |-------| |-------|
|***|
**/
if nodeBeg == nil && nodeEnd == nil {
tlsrv = TimeLineSrv{}
tlsrv.StartTime = addtlsrv.StartTime
tlsrv.EndTime = addtlsrv.EndTime
tlsrv.EffFactor = addtlsrv.EffFactor
// 删除开始节点之后到结束时间点之间的Node
for e = tcs.TimeLineList.Front(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.StartTime.Unix() > addtlsrv.StartTime.Unix() && tl.EndTime.Unix() < addtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
}
}
// 添加节点到时间曲线中
for e = tcs.TimeLineList.Front(); e != nil; e = next {
tl = e.Value.(*TimeLineSrv)
if tl.EndTime.Unix() >= tlsrv.StartTime.Unix() {
tcs.TimeLineList.InsertAfter(tlsrv, e)
break
}
}
}
/**
情况三: |-------| |-------|
|**|
**/
if nodeBeg == nil && nodeEnd != nil {
tle = nodeEnd.Value.(*TimeLineSrv)
// 删除开始节点到结束时间点之间的Node
for e = tcs.TimeLineList.Front(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.StartTime.Unix() > addtlsrv.StartTime.Unix() && tl.EndTime.Unix() < addtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
}
}
// 更新结束节点的开始时间
tle.StartTime = addtlsrv.StartTime
}
/**
情况四: |-------| |-------|
|****|
*/
if nodeBeg != nil && nodeEnd != nil {
if nodeBeg != nodeEnd {
tlb = nodeBeg.Value.(*TimeLineSrv)
tle = nodeEnd.Value.(*TimeLineSrv)
if tlb != tle {
// 删除两节点之间的所有节点
for e = nodeBeg.Next(); e != nil && e != nodeEnd; e = next {
next = e.Next()
tcs.TimeLineList.Remove(e)
}
// 更新起始时间点
tlb.EndTime = tle.EndTime
tcs.TimeLineList.Remove(nodeEnd)
}
}
}
}
/** |-------------------|
<------>
*/
if addtlsrv.StartTime.Unix() >= tcs.StartTime.Unix() && addtlsrv.StartTime.Unix() < tcs.EndTime.Unix() && addtlsrv.EndTime.Unix() > tcs.EndTime.Unix() {
if nodeBeg, err = tcs.GetTimeLine(addtlsrv.StartTime); err != nil {
return
}
if nodeBeg != nil {
tl = nodeBeg.Value.(*TimeLineSrv)
tl.EndTime = addtlsrv.EndTime
tcs.RemoveListAllAfterItem(nodeBeg, false)
tcs.EndTime = addtlsrv.EndTime
} else {
// 删除时段内的节点
for e = tcs.TimeLineList.Front(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.StartTime.Unix() > addtlsrv.StartTime.Unix() && tl.EndTime.Unix() < addtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
}
}
tlsrv = TimeLineSrv{}
tlsrv.StartTime = addtlsrv.StartTime
tlsrv.EndTime = addtlsrv.EndTime
tlsrv.EffFactor = addtlsrv.EffFactor
tcs.TimeLineList.PushBack(tlsrv)
tcs.EndTime = addtlsrv.EndTime
}
}
return
}
// 减少工作时段
func(tcs *TimeCurveSrv)SubTimeLine(subtlsrv TimeLineSrv)(err error){
var (
tlsrv TimeLineSrv
tl, tlb, tle *TimeLineSrv
e, next, nodeBeg, nodeEnd *list.Element
)
if subtlsrv.EndTime.Unix() <= subtlsrv.StartTime.Unix() {
return
}
/** 如果结束时间点小于计划曲线的起始时间点
|-------------------|
<---->
*/
if subtlsrv.EndTime.Unix() <= tcs.StartTime.Unix() {
return
}
/** 如果计算起始时间点大于等于计划曲线的起始时间点
|--------------------|
<----------->
*/
if subtlsrv.StartTime.Unix() >= tcs.EndTime.Unix() {
return
}
/** |-------------------|
<--------------------------->
*/
if subtlsrv.StartTime.Unix() < tcs.StartTime.Unix() && subtlsrv.EndTime.Unix() > tcs.EndTime.Unix() {
tcs.TimeLineList.Init()
return
}
/** |-------------------|
<------>
*/
if subtlsrv.StartTime.Unix() < tcs.StartTime.Unix() && subtlsrv.EndTime.Unix() > tcs.StartTime.Unix() && subtlsrv.EndTime.Unix() <= tcs.EndTime.Unix() {
if nodeEnd, err = tcs.GetTimeLine(subtlsrv.EndTime); err != nil {
return
}
if nodeEnd != nil {
tl = nodeEnd.Value.(*TimeLineSrv)
tl.StartTime = subtlsrv.EndTime
tcs.RemoveListAllBeforeItem(nodeEnd, false)
tcs.StartTime = subtlsrv.EndTime
} else {
// 删除时段内的节点
for e = tcs.TimeLineList.Front(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.StartTime.Unix() > subtlsrv.StartTime.Unix() && tl.EndTime.Unix() < subtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
}
}
tl = tcs.TimeLineList.Front().Value.(*TimeLineSrv)
tcs.StartTime = tl.StartTime
}
}
/** |-------------------|
<------>
*/
if subtlsrv.StartTime.Unix() >= tcs.StartTime.Unix() && subtlsrv.EndTime.Unix() <= tcs.EndTime.Unix() {
if nodeBeg, err = tcs.GetTimeLine(subtlsrv.StartTime); err != nil || nodeBeg == nil {
return
}
if nodeEnd, err = tcs.GetTimeLine(subtlsrv.EndTime); err != nil || nodeEnd == nil {
return
}
/** 落在可用时段内
情况一: |-------|
|****|
**/
if nodeBeg != nil && nodeEnd == nil {
tlb = nodeBeg.Value.(*TimeLineSrv)
// 删除开始节点之后到结束时间点之间的Node
for e = nodeBeg.Next(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.EndTime.Unix() <= subtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
} else {
break
}
}
// 更新开始节点的结束时间
tlb.EndTime = subtlsrv.StartTime
}
/**
情况二: |-------| |-------|
|***|
**/
if nodeBeg == nil && nodeEnd == nil {
tlsrv = TimeLineSrv{}
tlsrv.StartTime = subtlsrv.StartTime
tlsrv.EndTime = subtlsrv.EndTime
tlsrv.EffFactor = subtlsrv.EffFactor
// 删除开始节点之后到结束时间点之间的Node
for e = tcs.TimeLineList.Front(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.StartTime.Unix() > subtlsrv.StartTime.Unix() && tl.EndTime.Unix() < subtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
}
}
}
/**
情况三: |-------| |-------|
|**|
**/
if nodeBeg == nil && nodeEnd != nil {
tle = nodeEnd.Value.(*TimeLineSrv)
// 删除开始节点到结束时间点之间的Node
for e = tcs.TimeLineList.Front(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.StartTime.Unix() > subtlsrv.StartTime.Unix() && tl.EndTime.Unix() < subtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
}
}
// 更新结束节点的开始时间
tle.StartTime = subtlsrv.EndTime
}
/**
情况四: |-------| |-------|
|****|
*/
if nodeBeg != nil && nodeEnd != nil {
if nodeBeg != nodeEnd {
tlb = nodeBeg.Value.(*TimeLineSrv)
tle = nodeEnd.Value.(*TimeLineSrv)
if tlb != tle {
// 删除两节点之间的所有节点
for e = nodeBeg.Next(); e != nil && e != nodeEnd; e = next {
next = e.Next()
tcs.TimeLineList.Remove(e)
}
// 更新起始时间点
tlb.EndTime = subtlsrv.StartTime
tle.StartTime = subtlsrv.EndTime
}
} else {
tlb.EndTime = subtlsrv.StartTime
tlsrv = TimeLineSrv{}
tlsrv.StartTime = subtlsrv.StartTime
tlsrv.EndTime = subtlsrv.EndTime
tlsrv.EffFactor = subtlsrv.EffFactor
tcs.TimeLineList.InsertAfter(tlsrv, nodeBeg)
}
}
}
/** |-------------------|
<------>
*/
if subtlsrv.StartTime.Unix() >= tcs.StartTime.Unix() && subtlsrv.StartTime.Unix() < tcs.EndTime.Unix() && subtlsrv.EndTime.Unix() > tcs.EndTime.Unix() {
if nodeBeg, err = tcs.GetTimeLine(subtlsrv.StartTime); err != nil {
return
}
if nodeBeg != nil {
tl = nodeBeg.Value.(*TimeLineSrv)
tl.EndTime = subtlsrv.StartTime
tcs.RemoveListAllAfterItem(nodeBeg, false)
tcs.EndTime = subtlsrv.StartTime
} else {
// 删除时段内的节点
for e = tcs.TimeLineList.Front(); e != nil; e = next {
next = e.Next()
tl = e.Value.(*TimeLineSrv)
if tl.StartTime.Unix() > subtlsrv.StartTime.Unix() && tl.EndTime.Unix() < subtlsrv.EndTime.Unix() {
tcs.TimeLineList.Remove(e)
}
}
// 获取最后一个节点
tl = tcs.TimeLineList.Back().Value.(*TimeLineSrv)
tcs.EndTime = tl.EndTime
}
}
return
}
// 基于起始时间点和Duration计算在当前时间曲线上的结束时间点
func(tcs *TimeCurveSrv)CalEndTime(startTime time.Time, duration time.Duration)(endTime time.Time){
var(
i int
calDuration,totalDuration time.Duration
)
// 处理临界条件
if duration <= 0{
endTime = startTime
return
}
// 如果计算起始时间点大于等于计划曲线的结束时间点
if startTime.Unix() >= tcs.EndTime.Unix(){
endTime = startTime.Add(duration)
return
}
// 初始化
calDuration = duration
endTime = startTime
// 如果计算起始时间点小于计划曲线的起始时间点
if startTime.Unix() < tcs.StartTime.Unix(){
if startTime.Add(duration).Unix() <= tcs.StartTime.Unix() {
endTime = startTime.Add(duration)
return
}else{
calDuration = duration - tcs.StartTime.Sub(startTime)
}
}
totalDuration = 0
for i = 0; i < len(tcs.TimeLineArray); i++ {
if startTime.Unix() >= tcs.TimeLineArray[i].EndTime.Unix() {
continue
}
totalDuration = totalDuration + tcs.TimeLineArray[i].Duration
if totalDuration >= calDuration {
endTime = tcs.TimeLineArray[i].GetEndTimeByDuration(totalDuration - calDuration)
return
}
}
endTime = tcs.TimeLineArray[i].EndTime.Add(calDuration - totalDuration)
return
}
// 基于给定的两个时间点获取时间曲线上的Duration
func(tcs *TimeCurveSrv)CalDuration(startTime, endTime time.Time)(totalDuration time.Duration){
var(
i int
actStartTime, actEndTime time.Time
)
// 初始化
totalDuration = 0
// 临界条件处理
if startTime.Unix() >= endTime.Unix(){
return
}
if endTime.Unix() <= tcs.StartTime.Unix() || startTime.Unix() >= tcs.EndTime.Unix(){
totalDuration = endTime.Sub(startTime)
return
}
// |-------------------|
// <------>
if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() {
actStartTime = tcs.StartTime
actEndTime = endTime
totalDuration = tcs.StartTime.Sub(startTime)
}
// |-------------------|
// <--------------------------->
if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.EndTime.Unix() {
actStartTime = tcs.StartTime
actEndTime = tcs.EndTime
totalDuration = tcs.StartTime.Sub(startTime) + endTime.Sub(tcs.EndTime)
}
// |-------------------|
// <------>
if startTime.Unix() >= tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() {
actStartTime = startTime
actEndTime = endTime
totalDuration = 0
}
// |-------------------|
// <------>
if startTime.Unix() >= tcs.StartTime.Unix() && endTime.Unix() > tcs.EndTime.Unix() {
actStartTime = startTime
actEndTime = tcs.EndTime
totalDuration = endTime.Sub(tcs.EndTime)
}
/**# 计算落在计划时间区间内的有效时间
# ===================
#NO |-------|
#NO |-----|
#1.YES |--------|
#2.YES |---------------------------|
#3.YES |------------|
#4.YES |---------------------| **/
for i = 0; i < len(tcs.TimeLineArray); i++ {
if actEndTime.Unix() <= tcs.TimeLineArray[i].StartTime.Unix() || actStartTime.Unix() >= tcs.TimeLineArray[i].EndTime.Unix(){
continue
}
if tcs.TimeLineArray[i].EffFactor <= 0 {
tcs.TimeLineArray[i].EffFactor = 1.0
}
if actStartTime.Unix() < tcs.TimeLineArray[i].StartTime.Unix() && actEndTime.Unix() > tcs.TimeLineArray[i].StartTime.Unix() {
if actEndTime.Unix() <= tcs.TimeLineArray[i].EndTime.Unix(){
// 条件1
totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByEndTime(actEndTime)
break
}else{
// 条件2
totalDuration = totalDuration + tcs.TimeLineArray[i].Duration
actStartTime = tcs.TimeLineArray[i].EndTime
}
}
if actStartTime.Unix() >= tcs.TimeLineArray[i].StartTime.Unix() && actStartTime.Unix() < tcs.TimeLineArray[i].EndTime.Unix() {
if actEndTime.Unix() <= tcs.TimeLineArray[i].EndTime.Unix(){
// 条件3
totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByStartEndTime(actStartTime,actEndTime)
break
}else{
// 条件4
totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByStartTime(actStartTime)
actStartTime = tcs.TimeLineArray[i].EndTime
}
}
}
return
}