73 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
| /*
 | |
| 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++
 | |
| }
 |