github.com/avenga/couper@v1.12.2/handler/ratelimit/ring_buffer.go (about) 1 package ratelimit 2 3 import ( 4 "sync" 5 "time" 6 ) 7 8 type ringBuffer struct { 9 buf []time.Time 10 len uint 11 mu sync.RWMutex 12 r uint 13 w uint 14 } 15 16 // newRingBuffer creates a new ringBuffer 17 // instance. ringBuffer is thread safe. 18 func newRingBuffer(len uint) *ringBuffer { 19 return &ringBuffer{ 20 buf: make([]time.Time, len), 21 len: len, 22 r: 0, 23 w: len - 1, 24 } 25 } 26 27 // put rotates the ring buffer and puts t at 28 // the "last" position. r must not be empty. 29 func (r *ringBuffer) put(t time.Time) { 30 if r == nil { 31 panic("r must not be empty") 32 } 33 34 r.mu.Lock() 35 36 r.r++ 37 r.r %= r.len 38 39 r.w++ 40 r.w %= r.len 41 42 r.buf[r.w] = t 43 44 r.mu.Unlock() 45 } 46 47 // get returns the value of the "first" element 48 // in the ring buffer. r must not be empty. 49 func (r *ringBuffer) get() time.Time { 50 if r == nil { 51 panic("r must not be empty") 52 } 53 54 r.mu.Lock() 55 defer r.mu.Unlock() 56 57 return r.buf[r.r] 58 }