curl2info/trie_test.go
2018-12-04 20:00:30 +08:00

351 lines
5.5 KiB
Go

package curl2info
import (
"time"
)
type SecondNode int
type INode interface {
Get() interface{}
Set(value interface{})
GetStatus() bool
SetStatus(bool)
}
type TYNode struct {
IsOk bool
Value interface{}
}
func (min *TYNode) Get() interface{} {
return min.Value
}
func (min *TYNode) Set(value interface{}) {
min.Value = value
}
func (min *TYNode) SetStatus(status bool) {
min.IsOk = status
}
func (min *TYNode) GetStatus() bool {
return min.IsOk
}
type MinuteNode struct {
TYNode
}
func NewMinuteNode() *MinuteNode {
return &MinuteNode{}
}
type HourNode struct {
TYNode
All *MinuteNode
Minute [60]*MinuteNode
}
func (hour *HourNode) CreateMinute(nminute int) {
min := &MinuteNode{}
min.IsOk = true
hour.Minute[nminute] = min
}
func NewHourNode() *HourNode {
return &HourNode{}
}
type DayNode struct {
TYNode
Week time.Weekday
All *HourNode
Hour [24]*HourNode
}
func (day *DayNode) CreateHour(nhour int) {
hour := &HourNode{}
hour.IsOk = true
day.Hour[nhour] = hour
}
func NewDayNode(curday *time.Time) *DayNode {
day := &DayNode{}
week := curday.Weekday()
day.IsOk = true
day.Week = week
return day
}
type MonthNode struct {
TYNode
MaxDay int
All *DayNode
First *time.Time
Day [32]*DayNode
}
func (month *MonthNode) CreateDay(nday int) {
day := month.First.AddDate(0, 0, nday-1)
month.Day[nday] = NewDayNode(&day)
}
func NewMonthNode(year, month int) *MonthNode {
Month := &MonthNode{}
First := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.Local)
Month.IsOk = true
Month.First = &First
Month.MaxDay = Month.First.AddDate(0, 1, -1).Day()
return Month
}
type TrieYear struct {
Year int
All *MonthNode
Month [13]*MonthNode
}
func (ty *TrieYear) CheckYear() bool {
year := time.Now().Year()
return ty.Year == year
}
func NewTrieYear(year int) *TrieYear {
ty := TrieYear{}
ty.Year = time.Now().Year()
return &ty
}
func (ty *TrieYear) AllPlanTime(aftertime time.Time) []time.Time {
now := aftertime
var result []time.Time
for i := 1; i <= 12; i++ {
if i < int(now.Month()) {
continue
}
var month *MonthNode
if ty.All != nil {
month = ty.All
} else {
month = ty.Month[i]
}
if month != nil {
for j := 1; j <= 31; j++ {
if j < int(now.Day()) {
continue
}
var day *DayNode
if month.All != nil {
day = month.All
} else {
day = month.Day[j]
}
if day != nil {
for k := 0; k <= 23; k++ {
if k < int(now.Hour()) {
continue
}
var hour *HourNode
if day.All != nil {
hour = day.All
} else {
hour = day.Hour[k]
}
if hour != nil {
for n := 0; n <= 59; n++ {
if n < int(now.Minute()) {
continue
}
var min *MinuteNode
if hour.All != nil {
min = hour.All
} else {
min = hour.Minute[n]
}
if min != nil {
if min.IsOk {
result = append(result, time.Date(ty.Year, time.Month(i), j, k, n, 0, 0, time.Local))
}
}
}
}
}
}
}
}
}
return result
}
func (ty *TrieYear) TimeUp() INode {
now := time.Now()
// 月
var month *MonthNode
if ty.All != nil {
month = ty.All
} else {
month = ty.Month[int(now.Month())]
}
// 天
if month != nil {
var day *DayNode
if month.All != nil {
day = month.All
} else {
day = month.Day[now.Day()]
}
if day != nil {
// 星期suit
var hour *HourNode
if day.All != nil {
hour = day.All
} else {
hour = day.Hour[now.Hour()]
}
var min *MinuteNode
if hour != nil {
min = hour.Minute[now.Minute()]
}
return min
}
}
return nil
}
func (ty *TrieYear) InsertCrontab(cron *Crontab) {
// 月的填充
for _, month := range cron.Month {
if month.isAll {
ty.All = NewMonthNode(ty.Year, 1)
insertDay(cron, ty.All)
} else {
left := month.left
right := month.right
for i := left; i <= right; i += month.per {
curMonth := NewMonthNode(ty.Year, i)
ty.Month[i] = curMonth
// 天的填充
insertDay(cron, curMonth)
}
}
}
}
func filterDay(cron *Crontab, curday *DayNode) bool {
for _, w := range cron.Week {
if w.isAll {
return true
}
for n := w.left; n <= w.right; n += w.per {
if time.Weekday(n) == curday.Week {
return true
}
}
}
return false
}
func insertDay(cron *Crontab, curMonth *MonthNode) {
for _, day := range cron.Day {
if day.isAll {
curMonth.All = NewDayNode(curMonth.First)
insertHour(cron, curMonth.All)
} else {
left := day.left
if left < 0 {
left += curMonth.MaxDay + 1
}
right := day.right
if right < 0 {
right += curMonth.MaxDay + 1
}
for j := left; j <= right; j += day.per {
curMonth.CreateDay(j)
curDay := curMonth.Day[j]
insertHour(cron, curDay)
}
}
}
}
func insertHour(cron *Crontab, curDay *DayNode) {
// 时的填充
for _, hour := range cron.Hour {
if hour.isAll {
curDay.All = NewHourNode()
insertMinute(cron, curDay.All)
} else {
left := hour.left
right := hour.right
for k := left; k <= right; k += hour.per {
curDay.CreateHour(k)
curHour := curDay.Hour[k]
insertMinute(cron, curHour)
}
}
}
}
func insertMinute(cron *Crontab, curHour *HourNode) {
for _, min := range cron.Min {
if min.isAll {
curHour.All = NewMinuteNode()
curHour.All.IsOk = true
} else {
left := min.left
right := min.right
for l := left; l <= right; l += min.per {
curHour.CreateMinute(l)
}
}
}
}