suppressor.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package model
  2. import (
  3. "os"
  4. "sync"
  5. "time"
  6. )
  7. const (
  8. MaxChangeHistory = 4
  9. )
  10. type change struct {
  11. size int64
  12. when time.Time
  13. }
  14. type changeHistory struct {
  15. changes []change
  16. next int64
  17. prevSup bool
  18. }
  19. type suppressor struct {
  20. sync.Mutex
  21. changes map[string]changeHistory
  22. threshold int64 // bytes/s
  23. }
  24. func (h changeHistory) bandwidth(t time.Time) int64 {
  25. if len(h.changes) == 0 {
  26. return 0
  27. }
  28. var t0 = h.changes[0].when
  29. if t == t0 {
  30. return 0
  31. }
  32. var bw float64
  33. for _, c := range h.changes {
  34. bw += float64(c.size)
  35. }
  36. return int64(bw / t.Sub(t0).Seconds())
  37. }
  38. func (h *changeHistory) append(size int64, t time.Time) {
  39. c := change{size, t}
  40. if len(h.changes) == MaxChangeHistory {
  41. h.changes = h.changes[1:MaxChangeHistory]
  42. }
  43. h.changes = append(h.changes, c)
  44. }
  45. func (s *suppressor) Suppress(name string, fi os.FileInfo) (cur, prev bool) {
  46. return s.suppress(name, fi.Size(), time.Now())
  47. }
  48. func (s *suppressor) suppress(name string, size int64, t time.Time) (bool, bool) {
  49. s.Lock()
  50. if s.changes == nil {
  51. s.changes = make(map[string]changeHistory)
  52. }
  53. h := s.changes[name]
  54. sup := h.bandwidth(t) > s.threshold
  55. prevSup := h.prevSup
  56. h.prevSup = sup
  57. if !sup {
  58. h.append(size, t)
  59. }
  60. s.changes[name] = h
  61. s.Unlock()
  62. return sup, prevSup
  63. }