mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 01:53:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			95 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package io
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"io"
 | 
						|
)
 | 
						|
 | 
						|
// RingBuffer struct satisfies io.ReadWrite interface.
 | 
						|
//
 | 
						|
// ReadBuffer is a revolving buffer data structure, which can be used to store snapshots of data in a
 | 
						|
// revolving window.
 | 
						|
type RingBuffer struct {
 | 
						|
	slice []byte
 | 
						|
	start int
 | 
						|
	end   int
 | 
						|
	size  int
 | 
						|
}
 | 
						|
 | 
						|
// NewRingBuffer method takes in a byte slice as an input and returns a RingBuffer.
 | 
						|
func NewRingBuffer(slice []byte) *RingBuffer {
 | 
						|
	ringBuf := RingBuffer{
 | 
						|
		slice: slice,
 | 
						|
	}
 | 
						|
	return &ringBuf
 | 
						|
}
 | 
						|
 | 
						|
// Write method inserts the elements in a byte slice, and returns the number of bytes written along with any error.
 | 
						|
func (r *RingBuffer) Write(p []byte) (int, error) {
 | 
						|
	for _, b := range p {
 | 
						|
		// check if end points to invalid index, we need to circle back
 | 
						|
		if r.end == len(r.slice) {
 | 
						|
			r.end = 0
 | 
						|
		}
 | 
						|
		// check if start points to invalid index, we need to circle back
 | 
						|
		if r.start == len(r.slice) {
 | 
						|
			r.start = 0
 | 
						|
		}
 | 
						|
		// if ring buffer is filled, increment the start index
 | 
						|
		if r.size == len(r.slice) {
 | 
						|
			r.size--
 | 
						|
			r.start++
 | 
						|
		}
 | 
						|
 | 
						|
		r.slice[r.end] = b
 | 
						|
		r.end++
 | 
						|
		r.size++
 | 
						|
	}
 | 
						|
	return len(p), nil
 | 
						|
}
 | 
						|
 | 
						|
// Read copies the data on the ring buffer into the byte slice provided to the method.
 | 
						|
// Returns the read count along with any error encountered while reading.
 | 
						|
func (r *RingBuffer) Read(p []byte) (int, error) {
 | 
						|
	// readCount keeps track of the number of bytes read
 | 
						|
	var readCount int
 | 
						|
	for j := 0; j < len(p); j++ {
 | 
						|
		// if ring buffer is empty or completely read
 | 
						|
		// return EOF error.
 | 
						|
		if r.size == 0 {
 | 
						|
			return readCount, io.EOF
 | 
						|
		}
 | 
						|
 | 
						|
		if r.start == len(r.slice) {
 | 
						|
			r.start = 0
 | 
						|
		}
 | 
						|
 | 
						|
		p[j] = r.slice[r.start]
 | 
						|
		readCount++
 | 
						|
		// increment the start pointer for ring buffer
 | 
						|
		r.start++
 | 
						|
		// decrement the size of ring buffer
 | 
						|
		r.size--
 | 
						|
	}
 | 
						|
	return readCount, nil
 | 
						|
}
 | 
						|
 | 
						|
// Len returns the number of unread bytes in the buffer.
 | 
						|
func (r *RingBuffer) Len() int {
 | 
						|
	return r.size
 | 
						|
}
 | 
						|
 | 
						|
// Bytes returns a copy of the RingBuffer's bytes.
 | 
						|
func (r RingBuffer) Bytes() []byte {
 | 
						|
	var b bytes.Buffer
 | 
						|
	io.Copy(&b, &r)
 | 
						|
	return b.Bytes()
 | 
						|
}
 | 
						|
 | 
						|
// Reset resets the ring buffer.
 | 
						|
func (r *RingBuffer) Reset() {
 | 
						|
	*r = RingBuffer{
 | 
						|
		slice: r.slice,
 | 
						|
	}
 | 
						|
}
 |