interval.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package tsdb
  15. import (
  16. "fmt"
  17. "strings"
  18. "time"
  19. )
  20. var (
  21. defaultRes int64 = 1500
  22. defaultMinInterval = time.Millisecond * 1
  23. year = time.Hour * 24 * 365
  24. day = time.Hour * 24
  25. )
  26. type Interval struct {
  27. Text string
  28. Value time.Duration
  29. }
  30. type intervalCalculator struct {
  31. minInterval time.Duration
  32. }
  33. type IntervalCalculator interface {
  34. Calculate(timeRange *TimeRange, minInterval time.Duration) Interval
  35. }
  36. type IntervalOptions struct {
  37. MinInterval time.Duration
  38. }
  39. func NewIntervalCalculator(opt *IntervalOptions) *intervalCalculator {
  40. if opt == nil {
  41. opt = &IntervalOptions{}
  42. }
  43. calc := &intervalCalculator{}
  44. if opt.MinInterval == 0 {
  45. calc.minInterval = defaultMinInterval
  46. } else {
  47. calc.minInterval = opt.MinInterval
  48. }
  49. return calc
  50. }
  51. func (i *Interval) Milliseconds() int64 {
  52. return i.Value.Nanoseconds() / int64(time.Millisecond)
  53. }
  54. func (ic *intervalCalculator) Calculate(timerange *TimeRange, minInterval time.Duration) Interval {
  55. to := timerange.MustGetTo().UnixNano()
  56. from := timerange.MustGetFrom().UnixNano()
  57. interval := time.Duration((to - from) / defaultRes)
  58. if interval < minInterval {
  59. return Interval{Text: FormatDuration(minInterval), Value: minInterval}
  60. }
  61. rounded := roundInterval(interval)
  62. return Interval{Text: FormatDuration(rounded), Value: rounded}
  63. }
  64. func GetIntervalFrom(dsInfo *DataSource, queryModel *Query, defaultInterval time.Duration) (time.Duration, error) {
  65. interval := queryModel.Interval
  66. if interval == "" && (dsInfo != nil && dsInfo.TimeInterval != "") {
  67. interval = dsInfo.TimeInterval
  68. }
  69. if interval == "" {
  70. return defaultInterval, nil
  71. }
  72. interval = strings.Replace(strings.Replace(interval, "<", "", 1), ">", "", 1)
  73. parsedInterval, err := time.ParseDuration(interval)
  74. if err != nil {
  75. return time.Duration(0), err
  76. }
  77. return parsedInterval, nil
  78. }
  79. // FormatDuration converts a duration into the kbn format e.g. 1m 2h or 3d
  80. func FormatDuration(inter time.Duration) string {
  81. if inter >= year {
  82. return fmt.Sprintf("%dy", inter/year)
  83. }
  84. if inter >= day {
  85. return fmt.Sprintf("%dd", inter/day)
  86. }
  87. if inter >= time.Hour {
  88. return fmt.Sprintf("%dh", inter/time.Hour)
  89. }
  90. if inter >= time.Minute {
  91. return fmt.Sprintf("%dm", inter/time.Minute)
  92. }
  93. if inter >= time.Second {
  94. return fmt.Sprintf("%ds", inter/time.Second)
  95. }
  96. if inter >= time.Millisecond {
  97. return fmt.Sprintf("%dms", inter/time.Millisecond)
  98. }
  99. return "1ms"
  100. }
  101. func roundInterval(interval time.Duration) time.Duration {
  102. switch true {
  103. // 0.015s
  104. case interval <= 15*time.Millisecond:
  105. return time.Millisecond * 10 // 0.01s
  106. // 0.035s
  107. case interval <= 35*time.Millisecond:
  108. return time.Millisecond * 20 // 0.02s
  109. // 0.075s
  110. case interval <= 75*time.Millisecond:
  111. return time.Millisecond * 50 // 0.05s
  112. // 0.15s
  113. case interval <= 150*time.Millisecond:
  114. return time.Millisecond * 100 // 0.1s
  115. // 0.35s
  116. case interval <= 350*time.Millisecond:
  117. return time.Millisecond * 200 // 0.2s
  118. // 0.75s
  119. case interval <= 750*time.Millisecond:
  120. return time.Millisecond * 500 // 0.5s
  121. // 1.5s
  122. case interval <= 1500*time.Millisecond:
  123. return time.Millisecond * 1000 // 1s
  124. // 3.5s
  125. case interval <= 3500*time.Millisecond:
  126. return time.Millisecond * 2000 // 2s
  127. // 7.5s
  128. case interval <= 7500*time.Millisecond:
  129. return time.Millisecond * 5000 // 5s
  130. // 12.5s
  131. case interval <= 12500*time.Millisecond:
  132. return time.Millisecond * 10000 // 10s
  133. // 17.5s
  134. case interval <= 17500*time.Millisecond:
  135. return time.Millisecond * 15000 // 15s
  136. // 25s
  137. case interval <= 25000*time.Millisecond:
  138. return time.Millisecond * 20000 // 20s
  139. // 45s
  140. case interval <= 45000*time.Millisecond:
  141. return time.Millisecond * 30000 // 30s
  142. // 1.5m
  143. case interval <= 90000*time.Millisecond:
  144. return time.Millisecond * 60000 // 1m
  145. // 3.5m
  146. case interval <= 210000*time.Millisecond:
  147. return time.Millisecond * 120000 // 2m
  148. // 7.5m
  149. case interval <= 450000*time.Millisecond:
  150. return time.Millisecond * 300000 // 5m
  151. // 12.5m
  152. case interval <= 750000*time.Millisecond:
  153. return time.Millisecond * 600000 // 10m
  154. // 12.5m
  155. case interval <= 1050000*time.Millisecond:
  156. return time.Millisecond * 900000 // 15m
  157. // 25m
  158. case interval <= 1500000*time.Millisecond:
  159. return time.Millisecond * 1200000 // 20m
  160. // 45m
  161. case interval <= 2700000*time.Millisecond:
  162. return time.Millisecond * 1800000 // 30m
  163. // 1.5h
  164. case interval <= 5400000*time.Millisecond:
  165. return time.Millisecond * 3600000 // 1h
  166. // 2.5h
  167. case interval <= 9000000*time.Millisecond:
  168. return time.Millisecond * 7200000 // 2h
  169. // 4.5h
  170. case interval <= 16200000*time.Millisecond:
  171. return time.Millisecond * 10800000 // 3h
  172. // 9h
  173. case interval <= 32400000*time.Millisecond:
  174. return time.Millisecond * 21600000 // 6h
  175. // 24h
  176. case interval <= 86400000*time.Millisecond:
  177. return time.Millisecond * 43200000 // 12h
  178. // 48h
  179. case interval <= 172800000*time.Millisecond:
  180. return time.Millisecond * 86400000 // 24h
  181. // 1w
  182. case interval <= 604800000*time.Millisecond:
  183. return time.Millisecond * 86400000 // 24h
  184. // 3w
  185. case interval <= 1814400000*time.Millisecond:
  186. return time.Millisecond * 604800000 // 1w
  187. // 2y
  188. case interval < 3628800000*time.Millisecond:
  189. return time.Millisecond * 2592000000 // 30d
  190. default:
  191. return time.Millisecond * 31536000000 // 1y
  192. }
  193. }