1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
  
     | 
    
      package metrics
import (
	"sync"
	"time"
)
// TrackItem implements tracked item with value and timestamp
type TrackItem struct {
	Value     int64 `json:"value"`
	Timestamp int64 `json:"timestamp"`
}
// TrackBuffer implements buffer of TrackItems
type TrackBuffer struct {
	track     []*TrackItem
	trackDiff []*TrackItem
	lock      sync.RWMutex
	pos       int
	length    int
	last     *TrackItem
	lastDiff *TrackItem
}
// NewTrackBuffer returns new TrackBuffer
func NewTrackBuffer(length int) *TrackBuffer {
	return &TrackBuffer{
		track:     make([]*TrackItem, length),
		trackDiff: make([]*TrackItem, length),
		pos:       0,
		length:    length,
	}
}
// Add adds counter value into track
func (t *TrackBuffer) Add(item int64) {
	t.lock.Lock()
	defer t.lock.Unlock()
	t.track[t.pos] = &TrackItem{
		Value:     item,
		Timestamp: time.Now().Unix(),
	}
	var diffItem int64
	t.trackDiff[t.pos] = &TrackItem{
		Timestamp: time.Now().Unix(),
	}
	if t.pos > 0 {
		diffItem = item - t.track[t.pos-1].Value
	} else if t.track[t.length-1] != nil {
		diffItem = item - t.track[t.length-1].Value
	} else {
		diffItem = item
	}
	t.trackDiff[t.pos].Value = diffItem
	t.last = t.track[t.pos]
	t.lastDiff = t.trackDiff[t.pos]
	t.pos = (t.pos + 1) % t.length
}
// GetTrack returns current recorded track
func (t *TrackBuffer) GetTrack() []*TrackItem {
	t.lock.RLock()
	defer t.lock.RUnlock()
	track := make([]*TrackItem, t.length)
	copy(track[0:t.length-t.pos], t.track[t.pos:])
	copy(track[t.length-t.pos:], t.track[:t.pos])
	return track
}
// GetDiffTrack returns current recorded diff-track
func (t *TrackBuffer) GetDiffTrack() []*TrackItem {
	t.lock.RLock()
	defer t.lock.RUnlock()
	track := make([]*TrackItem, t.length)
	copy(track[0:t.length-t.pos], t.trackDiff[t.pos:])
	copy(track[t.length-t.pos:], t.trackDiff[:t.pos])
	return track
}
// GetLastTrackItem returns last tracked item
func (t *TrackBuffer) GetLastTrackItem() *TrackItem {
	t.lock.RLock()
	defer t.lock.RUnlock()
	return t.last
}
// GetLastDiffTrackItem returns last tracked diff item
func (t *TrackBuffer) GetLastDiffTrackItem() *TrackItem {
	t.lock.RLock()
	defer t.lock.RUnlock()
	return t.lastDiff
}
 
     |