github.com/kayoticsully/syncthing@v0.8.9-0.20140724133906-c45a2fdc03f8/model/suppressor.go (about) 1 // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file). 2 // All rights reserved. Use of this source code is governed by an MIT-style 3 // license that can be found in the LICENSE file. 4 5 package model 6 7 import ( 8 "os" 9 "sync" 10 "time" 11 ) 12 13 const ( 14 MaxChangeHistory = 4 15 ) 16 17 type change struct { 18 size int64 19 when time.Time 20 } 21 22 type changeHistory struct { 23 changes []change 24 next int64 25 prevSup bool 26 } 27 28 type suppressor struct { 29 sync.Mutex 30 changes map[string]changeHistory 31 threshold int64 // bytes/s 32 } 33 34 func (h changeHistory) bandwidth(t time.Time) int64 { 35 if len(h.changes) == 0 { 36 return 0 37 } 38 39 var t0 = h.changes[0].when 40 if t == t0 { 41 return 0 42 } 43 44 var bw float64 45 for _, c := range h.changes { 46 bw += float64(c.size) 47 } 48 return int64(bw / t.Sub(t0).Seconds()) 49 } 50 51 func (h *changeHistory) append(size int64, t time.Time) { 52 c := change{size, t} 53 if len(h.changes) == MaxChangeHistory { 54 h.changes = h.changes[1:MaxChangeHistory] 55 } 56 h.changes = append(h.changes, c) 57 } 58 59 func (s *suppressor) Suppress(name string, fi os.FileInfo) (cur, prev bool) { 60 return s.suppress(name, fi.Size(), time.Now()) 61 } 62 63 func (s *suppressor) suppress(name string, size int64, t time.Time) (bool, bool) { 64 s.Lock() 65 66 if s.changes == nil { 67 s.changes = make(map[string]changeHistory) 68 } 69 h := s.changes[name] 70 sup := h.bandwidth(t) > s.threshold 71 prevSup := h.prevSup 72 h.prevSup = sup 73 if !sup { 74 h.append(size, t) 75 } 76 s.changes[name] = h 77 78 s.Unlock() 79 80 return sup, prevSup 81 }