| /* |
| Copyright 2017 The Kubernetes Authors. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| package buffer |
| |
| // RingGrowing is a growing ring buffer. |
| // Not thread safe. |
| type RingGrowing struct { |
| data []interface{} |
| n int // Size of Data |
| beg int // First available element |
| readable int // Number of data items available |
| } |
| |
| // NewRingGrowing constructs a new RingGrowing instance with provided parameters. |
| func NewRingGrowing(initialSize int) *RingGrowing { |
| return &RingGrowing{ |
| data: make([]interface{}, initialSize), |
| n: initialSize, |
| } |
| } |
| |
| // ReadOne reads (consumes) first item from the buffer if it is available, otherwise returns false. |
| func (r *RingGrowing) ReadOne() (data interface{}, ok bool) { |
| if r.readable == 0 { |
| return nil, false |
| } |
| r.readable-- |
| element := r.data[r.beg] |
| r.data[r.beg] = nil // Remove reference to the object to help GC |
| if r.beg == r.n-1 { |
| // Was the last element |
| r.beg = 0 |
| } else { |
| r.beg++ |
| } |
| return element, true |
| } |
| |
| // WriteOne adds an item to the end of the buffer, growing it if it is full. |
| func (r *RingGrowing) WriteOne(data interface{}) { |
| if r.readable == r.n { |
| // Time to grow |
| newN := r.n * 2 |
| newData := make([]interface{}, newN) |
| to := r.beg + r.readable |
| if to <= r.n { |
| copy(newData, r.data[r.beg:to]) |
| } else { |
| copied := copy(newData, r.data[r.beg:]) |
| copy(newData[copied:], r.data[:(to%r.n)]) |
| } |
| r.beg = 0 |
| r.data = newData |
| r.n = newN |
| } |
| r.data[(r.readable+r.beg)%r.n] = data |
| r.readable++ |
| } |