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  }