featurebase/timeframe.go
Ben Johnson 34fa1afad0 refactor
This commit refactors the pilosa codebase. It makes several major
changes:

* Removes bitmap handles
* Removes dispatch/hold/transport
* Removes etcd dependency
* Adds consistent hash ring for slice placement
* Refactors parser/lexer
* Adds strong typing to PQL AST
* Flattens package hierarchy
2015-12-02 15:34:49 -07:00

172 lines
4.8 KiB
Go

package pilosa
import (
"time"
)
type TimeQuantum uint
const (
Y TimeQuantum = 3
YM TimeQuantum = 2
YMD TimeQuantum = 1
YMDH TimeQuantum = 0
)
func GetTimeID(t TimeQuantum, year uint, month uint, day uint, hour uint, tile_id uint64) uint64 {
y := year - 1970 //config.startyear
time_stamp := uint64((uint(t) << 30) | (y << 23) | (month << 19) | (day << 14) | (hour << 9))
time_stamp = time_stamp << 32
result := time_stamp | tile_id
return result
}
func GetTimeIds(tile_id uint64, atime time.Time, min_quantum TimeQuantum) []uint64 {
results := make([]uint64, 0, 4)
year := uint(atime.Year())
month := atime.Month()
day := atime.Day()
hour := atime.Hour()
if min_quantum <= Y {
id := GetTimeID(Y, year, 0, 0, 0, tile_id)
results = append(results, id)
}
if min_quantum <= YM {
id := GetTimeID(YM, uint(year), uint(month), 0, 0, tile_id)
results = append(results, id)
}
if min_quantum <= YMD {
id := GetTimeID(YMD, year, uint(month), uint(day), 0, tile_id)
results = append(results, id)
}
if min_quantum <= YMDH {
id := GetTimeID(YMDH, year, uint(month), uint(day), uint(hour), tile_id)
results = append(results, id)
}
return results
}
func IncrementYear(t time.Time) time.Time {
return t.AddDate(1, 0, 0)
}
func IncrementMonth(t time.Time) time.Time {
return t.AddDate(0, 1, 0)
}
func IncrementDay(t time.Time) time.Time {
return t.AddDate(0, 0, 1)
}
func IncrementHour(t time.Time) time.Time {
return t.Add(time.Hour)
}
func sameYear(t1, t2 time.Time) bool {
y1, _, _ := t1.Date()
y2, _, _ := t2.Date()
return (y1 == y2)
}
func NextYear(start time.Time, end time.Time) bool {
nextYear := start.AddDate(1, 0, 0)
return sameYear(nextYear, end) || end.After(nextYear)
}
func sameMonth(t1, t2 time.Time) bool {
y1, m1, _ := t1.Date()
y2, m2, _ := t2.Date()
return (y1 == y2) && (m1 == m2)
}
func NextMonth(start time.Time, end time.Time) bool {
nextMonth := start.AddDate(0, 1, 0)
return sameMonth(nextMonth, end) || end.After(nextMonth)
}
func sameDay(t1, t2 time.Time) bool {
y1, m1, d1 := t1.Date()
y2, m2, d2 := t2.Date()
return (y1 == y2) && (m1 == m2) && (d1 == d2)
}
func NextDay(start time.Time, end time.Time) bool {
nextDay := start.AddDate(0, 0, 1)
return sameDay(nextDay, end) || end.After(nextDay)
}
func GetRange(start_time time.Time, end_time time.Time, tile_id uint64) []uint64 {
results, marker := upHill(start_time, end_time, tile_id)
r2 := downHill(marker, end_time, tile_id)
results = append(results, r2...)
return results
}
func upHill(start_time time.Time, end_time time.Time, tile_id uint64) ([]uint64, time.Time) {
var results []uint64
time_iterator := start_time
for time_iterator.Before(end_time) {
if NextDay(time_iterator, end_time) {
if time_iterator.Hour() == 0 {
if NextMonth(time_iterator, end_time) {
if time_iterator.Day() == 1 {
if NextYear(time_iterator, end_time) {
if time_iterator.Month() == 1 {
break
} else {
month_id := GetTimeID(YM, uint(time_iterator.Year()), uint(time_iterator.Month()), 0, 0, tile_id)
results = append(results, month_id)
time_iterator = IncrementMonth(time_iterator)
}
} else {
break
}
} else {
day_id := GetTimeID(YMD, uint(time_iterator.Year()), uint(time_iterator.Month()), uint(time_iterator.Day()), 0, tile_id)
results = append(results, day_id)
time_iterator = IncrementDay(time_iterator)
}
} else {
break
}
} else {
hour_id := GetTimeID(YMDH, uint(time_iterator.Year()), uint(time_iterator.Month()), uint(time_iterator.Day()), uint(time_iterator.Hour()), tile_id)
results = append(results, hour_id)
time_iterator = IncrementHour(time_iterator)
}
} else {
break
}
}
return results, time_iterator
}
func downHill(start_time time.Time, end_time time.Time, tile_id uint64) []uint64 {
var results []uint64
time_iterator := start_time
for time_iterator.Before(end_time) {
if NextYear(time_iterator, end_time) {
year_id := GetTimeID(Y, uint(time_iterator.Year()), 0, 0, 0, tile_id)
results = append(results, year_id)
time_iterator = IncrementYear(time_iterator)
} else if NextMonth(time_iterator, end_time) {
month_id := GetTimeID(YM, uint(time_iterator.Year()), uint(time_iterator.Month()), 0, 0, tile_id)
results = append(results, month_id)
time_iterator = IncrementMonth(time_iterator)
} else if NextDay(time_iterator, end_time) {
day_id := GetTimeID(YMD, uint(time_iterator.Year()), uint(time_iterator.Month()), uint(time_iterator.Day()), 0, tile_id)
results = append(results, day_id)
time_iterator = IncrementDay(time_iterator)
} else {
hour_id := GetTimeID(YMDH, uint(time_iterator.Year()), uint(time_iterator.Month()), uint(time_iterator.Day()), uint(time_iterator.Hour()), tile_id)
results = append(results, hour_id)
time_iterator = IncrementHour(time_iterator)
}
}
return results
}