github.com/aswedchain/aswed@v1.0.1/eth/gasprice/utils.go (about) 1 package gasprice 2 3 import "sync" 4 5 // CirculeQueue currently is only for special usage. 6 // Thread unsafe! 7 type CirculeQueue struct { 8 items []interface{} 9 cap int // 10 n int // lenght 11 i int // start index 12 e int // end index 13 } 14 15 func NewCirculeQueue(c int) *CirculeQueue { 16 if c <= 0 { 17 panic("capacity must greater than 0") 18 } 19 return &CirculeQueue{ 20 items: make([]interface{}, 0, c), 21 cap: c, 22 } 23 } 24 25 func NewCirculeQueueByItems(items []interface{}) *CirculeQueue { 26 its := make([]interface{}, len(items)) 27 copy(its, items) 28 return &CirculeQueue{ 29 items: its, 30 cap: len(its), 31 n: len(its), 32 i: len(its) - 1, 33 } 34 } 35 36 // EnAndReplace enqueue one price and return the replaced one, 37 // if there's no item replaced, the return will be nil. 38 func (q *CirculeQueue) EnAndReplace(b interface{}) (d interface{}) { 39 if q.n == q.cap { 40 d = q.items[q.e] 41 q.i = q.e 42 q.items[q.i] = b 43 q.e = (q.e + 1) % q.cap 44 } else { 45 q.i = (q.i + 1) % q.cap 46 q.items[q.i] = b 47 q.n++ 48 } 49 return 50 } 51 52 // Stats statistics tx count of the last few blocks 53 type Stats struct { 54 q *CirculeQueue 55 n int 56 sum int 57 avg int 58 59 lock sync.RWMutex 60 } 61 62 func NewStats(txc []int) *Stats { 63 n := len(txc) 64 its := make([]interface{}, n) 65 total := 0 66 for i, v := range txc { 67 its[i] = v 68 total += v 69 } 70 q := NewCirculeQueueByItems(its) 71 return &Stats{ 72 q: q, 73 n: n, 74 sum: total, 75 avg: total / n, 76 } 77 } 78 79 func (s *Stats) Add(cnt int) { 80 s.lock.Lock() 81 defer s.lock.Unlock() 82 d := s.q.EnAndReplace(cnt) 83 i := d.(int) 84 s.sum += cnt - i 85 s.avg = s.sum / s.n 86 } 87 88 func (s *Stats) Avg() int { 89 s.lock.RLock() 90 defer s.lock.RUnlock() 91 return s.avg 92 }