Documentation
¶
Index ¶
- type AtomicFixedSizeRingBuf
- func (b *AtomicFixedSizeRingBuf) Adopt(me []byte)
- func (b *AtomicFixedSizeRingBuf) Advance(n int)
- func (b *AtomicFixedSizeRingBuf) AdvanceBytesTwo(tb TwoBuffers)
- func (b *AtomicFixedSizeRingBuf) Bytes(makeCopy bool) []byte
- func (b *AtomicFixedSizeRingBuf) BytesTwo() TwoBuffers
- func (b *AtomicFixedSizeRingBuf) ContigLen() int
- func (b *AtomicFixedSizeRingBuf) Read(p []byte) (n int, err error)
- func (b *AtomicFixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error)
- func (b *AtomicFixedSizeRingBuf) ReadFrom(r io.Reader) (n int64, err error)
- func (b *AtomicFixedSizeRingBuf) ReadWithoutAdvance(p []byte) (n int, err error)
- func (b *AtomicFixedSizeRingBuf) Readable() int
- func (b *AtomicFixedSizeRingBuf) Reset()
- func (b *AtomicFixedSizeRingBuf) Write(p []byte) (n int, err error)
- func (b *AtomicFixedSizeRingBuf) WriteTo(w io.Writer) (n int64, err error)
- type FixedSizeRingBuf
- func (b *FixedSizeRingBuf) Adopt(me []byte)
- func (b *FixedSizeRingBuf) Advance(n int)
- func (f *FixedSizeRingBuf) Avail() int
- func (b *FixedSizeRingBuf) Bytes() []byte
- func (b *FixedSizeRingBuf) BytesTwo(makeCopy bool) (first []byte, second []byte)
- func (b *FixedSizeRingBuf) ContigLen() int
- func (f *FixedSizeRingBuf) DeleteMostRecentBytes(n int)
- func (f *FixedSizeRingBuf) First() int
- func (f *FixedSizeRingBuf) Kth(k int) int
- func (f *FixedSizeRingBuf) Last() int
- func (b *FixedSizeRingBuf) LegalPos() (a0, aLast, b0, bLast int)
- func (f *FixedSizeRingBuf) Nextpos(from int) int
- func (f *FixedSizeRingBuf) Prevpos(from int) int
- func (b *FixedSizeRingBuf) Read(p []byte) (n int, err error)
- func (b *FixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error)
- func (b *FixedSizeRingBuf) ReadFrom(r io.Reader) (n int64, err error)
- func (b *FixedSizeRingBuf) ReadWithoutAdvance(p []byte) (n int, err error)
- func (b *FixedSizeRingBuf) Reset()
- func (b *FixedSizeRingBuf) Write(p []byte) (n int, err error)
- func (b *FixedSizeRingBuf) WriteAndMaybeOverwriteOldestData(p []byte) (n int, err error)
- func (b *FixedSizeRingBuf) WriteTo(w io.Writer) (n int64, err error)
- type Float64RingBuf
- func (b *Float64RingBuf) Adopt(me []float64)
- func (b *Float64RingBuf) Advance(n int)
- func (b *Float64RingBuf) Earliest() (v float64, ok bool)
- func (b *Float64RingBuf) ReadFloat64(p []float64) (n int, err error)
- func (b *Float64RingBuf) ReadWithoutAdvance(p []float64) (n int, err error)
- func (b *Float64RingBuf) Reset()
- func (b *Float64RingBuf) TwoContig(makeCopy bool) (first []float64, second []float64)
- func (b *Float64RingBuf) Values() []float64
- func (b *Float64RingBuf) Write(p []float64) (n int, err error)
- func (b *Float64RingBuf) WriteAndMaybeOverwriteOldestData(p []float64) (n int, err error)
- type PointerRingBuf
- func (b *PointerRingBuf) Adopt(me []interface{})
- func (b *PointerRingBuf) Advance(n int)
- func (b *PointerRingBuf) Push(p []interface{}) (n int, err error)
- func (b *PointerRingBuf) PushAndMaybeOverwriteOldestData(p []interface{}) (n int, err error)
- func (b *PointerRingBuf) ReadPtrs(p []interface{}) (n int, err error)
- func (b *PointerRingBuf) ReadWithoutAdvance(p []interface{}) (n int, err error)
- func (b *PointerRingBuf) Reset()
- func (b *PointerRingBuf) TwoContig() (first []interface{}, second []interface{})
- func (b *PointerRingBuf) WritePtrs(p []interface{}) (n int, err error)
- type TwoBuffers
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AtomicFixedSizeRingBuf ¶
type AtomicFixedSizeRingBuf struct { A [2][]byte // a pair of ping/pong buffers. Only one is active. Use int // which A buffer is in active use, 0 or 1 N int // MaxViewInBytes, the size of A[0] and A[1] in bytes. Beg int // start of data in A[Use] // contains filtered or unexported fields }
AtomicFixedSizeRingBuf: see FixedSizeRingBuf for the full details; this is the same, just safe for current access (and thus paying the price of synchronization on each call as well.)
func NewAtomicFixedSizeRingBuf ¶
func NewAtomicFixedSizeRingBuf(maxViewInBytes int) *AtomicFixedSizeRingBuf
constructor. NewAtomicFixedSizeRingBuf will allocate internally two buffers of size maxViewInBytes.
func (*AtomicFixedSizeRingBuf) Adopt ¶
func (b *AtomicFixedSizeRingBuf) Adopt(me []byte)
Adopt(): non-standard.
For efficiency's sake, (possibly) take ownership of already allocated slice offered in me.
If me is large we will adopt it, and we will potentially then write to the me buffer. If we already have a bigger buffer, copy me into the existing buffer instead.
Side-effect: may change b.Use, among other internal state changes.
func (*AtomicFixedSizeRingBuf) Advance ¶
func (b *AtomicFixedSizeRingBuf) Advance(n int)
Advance(): non-standard, but better than Next(), because we don't have to unwrap our buffer and pay the cpu time for the copy that unwrapping may need. Useful in conjuction/after ReadWithoutAdvance() above.
func (*AtomicFixedSizeRingBuf) AdvanceBytesTwo ¶
func (b *AtomicFixedSizeRingBuf) AdvanceBytesTwo(tb TwoBuffers)
Purpose of BytesTwo() and AdvanceBytesTwo(): avoid extra copying of data.
AdvanceBytesTwo() takes a TwoBuffers as input, this must have been from a previous call to BytesTwo(); no intervening calls to Bytes() or Adopt() are allowed (or any other future routine or client data access that changes the internal data location or contents) can have been made.
After sanity checks, AdvanceBytesTwo() advances the internal buffer, effectively calling Advance( len(tb.First) + len(tb.Second)).
If intervening-calls that changed the buffers (other than appending data to the buffer) are detected, we will panic as a safety/sanity/ aid-to-debugging measure.
func (*AtomicFixedSizeRingBuf) Bytes ¶
func (b *AtomicFixedSizeRingBuf) Bytes(makeCopy bool) []byte
Bytes() returns a slice of the contents of the unread portion of the buffer.
To avoid copying, see the companion BytesTwo() call.
Unlike the standard library Bytes() method (on bytes.Buffer for example), the result of the AtomicFixedSizeRingBuf::Bytes(true) is a completely new returned slice, so modifying that slice will have no impact on the contents of the internal ring.
Bytes(false) acts like the standard library bytes.Buffer::Bytes() call, in that it returns a slice which is backed by the buffer itself (so no copy is involved).
The largest slice Bytes ever returns is bounded above by the maxViewInBytes value used when calling NewAtomicFixedSizeRingBuf().
Possible side-effect: may modify b.Use, the buffer in use.
func (*AtomicFixedSizeRingBuf) BytesTwo ¶
func (b *AtomicFixedSizeRingBuf) BytesTwo() TwoBuffers
BytesTwo returns all readable bytes, but in two separate slices, to avoid copying. The two slices are from the same buffer, but are not contiguous. Either or both may be empty slices.
func (*AtomicFixedSizeRingBuf) ContigLen ¶
func (b *AtomicFixedSizeRingBuf) ContigLen() int
ContigLen gets the length of the largest read that we can provide to a contiguous slice without an extra linearizing copy of all bytes internally.
func (*AtomicFixedSizeRingBuf) Read ¶
func (b *AtomicFixedSizeRingBuf) Read(p []byte) (n int, err error)
Read():
From bytes.Buffer.Read(): Read reads the next len(p) bytes from the buffer or until the buffer is drained. The return value n is the number of bytes read. If the buffer has no data to return, err is io.EOF (unless len(p) is zero); otherwise it is nil.
from the description of the Reader interface, http://golang.org/pkg/io/#Reader
Reader is the interface that wraps the basic Read method.
Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.
When Read encounters an error or end-of-file condition after successfully reading n > 0 bytes, it returns the number of bytes read. It may return the (non-nil) error from the same call or return the error (and n == 0) from a subsequent call. An instance of this general case is that a Reader returning a non-zero number of bytes at the end of the input stream may return either err == EOF or err == nil. The next Read should return 0, EOF regardless.
Callers should always process the n > 0 bytes returned before considering the error err. Doing so correctly handles I/O errors that happen after reading some bytes and also both of the allowed EOF behaviors.
Implementations of Read are discouraged from returning a zero byte count with a nil error, and callers should treat that situation as a no-op.
func (*AtomicFixedSizeRingBuf) ReadAndMaybeAdvance ¶
func (b *AtomicFixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error)
func (*AtomicFixedSizeRingBuf) ReadFrom ¶
func (b *AtomicFixedSizeRingBuf) ReadFrom(r io.Reader) (n int64, err error)
ReadFrom avoids intermediate allocation and copies. ReadFrom() reads data from r until EOF or error. The return value n is the number of bytes read. Any error except io.EOF encountered during the read is also returned.
func (*AtomicFixedSizeRingBuf) ReadWithoutAdvance ¶
func (b *AtomicFixedSizeRingBuf) ReadWithoutAdvance(p []byte) (n int, err error)
ReadWithoutAdvance(): if you want to Read the data and leave it in the buffer, so as to peek ahead for example.
func (*AtomicFixedSizeRingBuf) Readable ¶
func (b *AtomicFixedSizeRingBuf) Readable() int
Readable() returns the number of bytes available for reading.
func (*AtomicFixedSizeRingBuf) Reset ¶
func (b *AtomicFixedSizeRingBuf) Reset()
Reset quickly forgets any data stored in the ring buffer. The data is still there, but the ring buffer will ignore it and overwrite those buffers as new data comes in.
func (*AtomicFixedSizeRingBuf) Write ¶
func (b *AtomicFixedSizeRingBuf) Write(p []byte) (n int, err error)
Write writes len(p) bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p).
Write doesn't modify b.User, so once a []byte is pinned with a call to Bytes(), it should remain valid even with additional calls to Write() that come after the Bytes() call.
func (*AtomicFixedSizeRingBuf) WriteTo ¶
func (b *AtomicFixedSizeRingBuf) WriteTo(w io.Writer) (n int64, err error)
WriteTo avoids intermediate allocation and copies. WriteTo writes data to w until there's no more data to write or when an error occurs. The return value n is the number of bytes written. Any error encountered during the write is also returned.
type FixedSizeRingBuf ¶
type FixedSizeRingBuf struct { A [2][]byte // a pair of ping/pong buffers. Only one is active. Use int // which A buffer is in active use, 0 or 1 N int // MaxViewInBytes, the size of A[0] and A[1] in bytes. Beg int // start of data in A[Use] Readable int // number of bytes available to read in A[Use] }
FixedSizeRingBuf:
a fixed-size circular ring buffer. Yes, just what is says. We keep a pair of ping/pong buffers so that we can linearize the circular buffer into a contiguous slice if need be.
For efficiency, a FixedSizeRingBuf may be vastly preferred to a bytes.Buffer. The ReadWithoutAdvance(), Advance(), and Adopt() methods are all non-standard methods written for speed.
For an I/O heavy application, I have replaced bytes.Buffer with FixedSizeRingBuf and seen memory consumption go from 8GB to 25MB. Yes, that is a 300x reduction in memory footprint. Everything ran faster too.
Note that Bytes(), while inescapable at times, is expensive: avoid it if possible. Instead it is better to use the FixedSizeRingBuf.Readable member to get the number of bytes available. Bytes() is expensive because it may copy the back and then the front of a wrapped buffer A[Use] into A[1-Use] in order to get a contiguous slice. If possible use ContigLen() first to get the size that can be read without copying, Read() that amount, and then Read() a second time -- to avoid the copy. See BytesTwo() for a method that does this for you.
func NewFixedSizeRingBuf ¶
func NewFixedSizeRingBuf(maxViewInBytes int) *FixedSizeRingBuf
constructor. NewFixedSizeRingBuf will allocate internally two buffers of size maxViewInBytes.
func (*FixedSizeRingBuf) Adopt ¶
func (b *FixedSizeRingBuf) Adopt(me []byte)
Adopt(): non-standard.
For efficiency's sake, (possibly) take ownership of already allocated slice offered in me.
If me is large we will adopt it, and we will potentially then write to the me buffer. If we already have a bigger buffer, copy me into the existing buffer instead.
func (*FixedSizeRingBuf) Advance ¶
func (b *FixedSizeRingBuf) Advance(n int)
Advance(): non-standard, but better than Next(), because we don't have to unwrap our buffer and pay the cpu time for the copy that unwrapping may need. Useful in conjuction/after ReadWithoutAdvance() above.
func (*FixedSizeRingBuf) Avail ¶
func (f *FixedSizeRingBuf) Avail() int
func (*FixedSizeRingBuf) Bytes ¶
func (b *FixedSizeRingBuf) Bytes() []byte
from the standard library description of Bytes(): Bytes() returns a slice of the contents of the unread portion of the buffer. If the caller changes the contents of the returned slice, the contents of the buffer will change provided there
are no intervening method calls on the Buffer.
The largest slice Bytes ever returns is bounded above by the maxViewInBytes value used when calling NewFixedSizeRingBuf().
func (*FixedSizeRingBuf) BytesTwo ¶
func (b *FixedSizeRingBuf) BytesTwo(makeCopy bool) (first []byte, second []byte)
BytesTwo returns all readable bytes, but in two separate slices, to avoid copying. The two slices are from the same buffer, but are not contiguous. Either or both may be empty slices.
func (*FixedSizeRingBuf) ContigLen ¶
func (b *FixedSizeRingBuf) ContigLen() int
ContigLen gets the length of the largest read that we can provide to a contiguous slice without an extra linearizing copy of all bytes internally.
func (*FixedSizeRingBuf) DeleteMostRecentBytes ¶
func (f *FixedSizeRingBuf) DeleteMostRecentBytes(n int)
DeleteMostRecentBytes trims back the last n bytes written.
func (*FixedSizeRingBuf) First ¶
func (f *FixedSizeRingBuf) First() int
First returns the earliest index, or -1 if the ring is empty
func (*FixedSizeRingBuf) Kth ¶
func (f *FixedSizeRingBuf) Kth(k int) int
Kth presents the contents of the ring as a strictly linear sequence, so the user doesn't need to think about modular arithmetic. Here k indexes from [0, f.Readable-1], assuming f.Avail() is greater than 0. Kth() returns an actual index where the logical k-th element, starting from f.Beg, resides. f.Beg itself lives at k = 0. If k is out of bounds, or the ring is empty, -1 is returned.
func (*FixedSizeRingBuf) Last ¶
func (f *FixedSizeRingBuf) Last() int
Last returns the index of the last element, or -1 if the ring is empty.
func (*FixedSizeRingBuf) LegalPos ¶
func (b *FixedSizeRingBuf) LegalPos() (a0, aLast, b0, bLast int)
LegalPos returns the legal index positions, [a0,aLast] and [b0,bLast] inclusive, where the [a0,aLast] holds the first FIFO ordered segment, and the [b0,bLast] holds the second ordered segment, if any. A position of -1 means the segment is not used, perhaps because b.Readable is zero, or because the second segment [b0,bLast] is not in use (when everything fits in the first [a0,aLast] segment).
func (*FixedSizeRingBuf) Nextpos ¶
func (f *FixedSizeRingBuf) Nextpos(from int) int
Next returns the index of the element after from, or -1 if no more. returns -2 if erroneous input (bad from).
func (*FixedSizeRingBuf) Prevpos ¶
func (f *FixedSizeRingBuf) Prevpos(from int) int
Prevpos returns the index of the element before from, or -1 if no more and from is the first in the ring. Returns -2 on bad from position.
func (*FixedSizeRingBuf) Read ¶
func (b *FixedSizeRingBuf) Read(p []byte) (n int, err error)
Read():
from bytes.Buffer.Read(): Read reads the next len(p) bytes from the buffer or until the buffer is drained. The return value n is the number of bytes read. If the buffer has no data to return, err is io.EOF (unless len(p) is zero); otherwise it is nil.
from the description of the Reader interface, http://golang.org/pkg/io/#Reader
Reader is the interface that wraps the basic Read method.
Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.
When Read encounters an error or end-of-file condition after successfully reading n > 0 bytes, it returns the number of bytes read. It may return the (non-nil) error from the same call or return the error (and n == 0) from a subsequent call. An instance of this general case is that a Reader returning a non-zero number of bytes at the end of the input stream may return either err == EOF or err == nil. The next Read should return 0, EOF regardless.
Callers should always process the n > 0 bytes returned before considering the error err. Doing so correctly handles I/O errors that happen after reading some bytes and also both of the allowed EOF behaviors.
Implementations of Read are discouraged from returning a zero byte count with a nil error, and callers should treat that situation as a no-op.
func (*FixedSizeRingBuf) ReadAndMaybeAdvance ¶
func (b *FixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error)
func (*FixedSizeRingBuf) ReadFrom ¶
func (b *FixedSizeRingBuf) ReadFrom(r io.Reader) (n int64, err error)
ReadFrom avoids intermediate allocation and copies. ReadFrom() reads data from r until EOF or error. The return value n is the number of bytes read. Any error except io.EOF encountered during the read is also returned.
func (*FixedSizeRingBuf) ReadWithoutAdvance ¶
func (b *FixedSizeRingBuf) ReadWithoutAdvance(p []byte) (n int, err error)
ReadWithoutAdvance(): if you want to Read the data and leave it in the buffer, so as to peek ahead for example.
func (*FixedSizeRingBuf) Reset ¶
func (b *FixedSizeRingBuf) Reset()
Reset quickly forgets any data stored in the ring buffer. The data is still there, but the ring buffer will ignore it and overwrite those buffers as new data comes in.
func (*FixedSizeRingBuf) Write ¶
func (b *FixedSizeRingBuf) Write(p []byte) (n int, err error)
Write writes len(p) bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p).
func (*FixedSizeRingBuf) WriteAndMaybeOverwriteOldestData ¶
func (b *FixedSizeRingBuf) WriteAndMaybeOverwriteOldestData(p []byte) (n int, err error)
WriteAndMaybeOverwriteOldestData always consumes the full buffer p, even if that means blowing away the oldest unread bytes in the ring to make room. In reality, only the last min(len(p),b.N) bytes of p will end up being written to the ring.
This allows the ring to act as a record of the most recent b.N bytes of data -- a kind of temporal LRU cache, so the speak. The linux kernel's dmesg ring buffer is similar.
func (*FixedSizeRingBuf) WriteTo ¶
func (b *FixedSizeRingBuf) WriteTo(w io.Writer) (n int64, err error)
WriteTo avoids intermediate allocation and copies. WriteTo writes data to w until there's no more data to write or when an error occurs. The return value n is the number of bytes written. Any error encountered during the write is also returned.
type Float64RingBuf ¶
type Float64RingBuf struct { A []float64 N int // MaxView, the total size of A, whether or not in use. Beg int // start of in-use data in A Readable int // number of float64 available in A (in use) }
Float64RingBuf:
a fixed-size circular ring buffer of float64
func NewFloat64RingBuf ¶
func NewFloat64RingBuf(maxViewItems int) *Float64RingBuf
constructor. NewFloat64RingBuf will allocate internally a slice of maxViewItems float64.
func (*Float64RingBuf) Adopt ¶
func (b *Float64RingBuf) Adopt(me []float64)
Adopt(): non-standard.
For efficiency's sake, (possibly) take ownership of already allocated slice offered in me.
If me is large we will adopt it, and we will potentially then write to the me buffer. If we already have a bigger buffer, copy me into the existing buffer instead.
func (*Float64RingBuf) Advance ¶
func (b *Float64RingBuf) Advance(n int)
Advance(): non-standard, but better than Next(), because we don't have to unwrap our buffer and pay the cpu time for the copy that unwrapping may need. Useful in conjuction/after ReadWithoutAdvance() above.
func (*Float64RingBuf) Earliest ¶
func (b *Float64RingBuf) Earliest() (v float64, ok bool)
Earliest returns the earliest written value v. ok will be true unless the ring is empty, in which case ok will be false, and v will be zero.
func (*Float64RingBuf) ReadFloat64 ¶
func (b *Float64RingBuf) ReadFloat64(p []float64) (n int, err error)
ReadFloat64():
from bytes.Buffer.Read(): Read reads the next len(p) float64 pointers from the buffer or until the buffer is drained. The return value n is the number of bytes read. If the buffer has no data to return, err is io.EOF (unless len(p) is zero); otherwise it is nil.
func (*Float64RingBuf) ReadWithoutAdvance ¶
func (b *Float64RingBuf) ReadWithoutAdvance(p []float64) (n int, err error)
ReadWithoutAdvance(): if you want to Read the data and leave it in the buffer, so as to peek ahead for example.
func (*Float64RingBuf) Reset ¶
func (b *Float64RingBuf) Reset()
Reset quickly forgets any data stored in the ring buffer. The data is still there, but the ring buffer will ignore it and overwrite those buffers as new data comes in.
func (*Float64RingBuf) TwoContig ¶
func (b *Float64RingBuf) TwoContig(makeCopy bool) (first []float64, second []float64)
TwoContig returns all readable float64, but in two separate slices, to avoid copying. The two slices are from the same buffer, but are not contiguous. Either or both may be empty slices.
func (*Float64RingBuf) Values ¶
func (b *Float64RingBuf) Values() []float64
Values returns all readable float64 in a single buffer. Calling this function might allocate a new buffer to store the elements contiguously.
func (*Float64RingBuf) Write ¶
func (b *Float64RingBuf) Write(p []float64) (n int, err error)
Write writes len(p) float64 values from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p).
func (*Float64RingBuf) WriteAndMaybeOverwriteOldestData ¶
func (b *Float64RingBuf) WriteAndMaybeOverwriteOldestData(p []float64) (n int, err error)
WriteAndMaybeOverwriteOldestData always consumes the full buffer p, even if that means blowing away the oldest unread bytes in the ring to make room. In reality, only the last min(len(p),b.N) bytes of p will end up being written to the ring.
This allows the ring to act as a record of the most recent b.N bytes of data -- a kind of temporal LRU cache, so the speak. The linux kernel's dmesg ring buffer is similar.
type PointerRingBuf ¶
type PointerRingBuf struct { A []interface{} N int // MaxView, the total size of A, whether or not in use. Beg int // start of in-use data in A Readable int // number of pointers available in A (in use) }
PointerRingBuf:
a fixed-size circular ring buffer of interface{}
func NewPointerRingBuf ¶
func NewPointerRingBuf(sliceN int) *PointerRingBuf
constructor. NewPointerRingBuf will allocate internally a slice of size sliceN
func (*PointerRingBuf) Adopt ¶
func (b *PointerRingBuf) Adopt(me []interface{})
Adopt(): non-standard.
For efficiency's sake, (possibly) take ownership of already allocated slice offered in me.
If me is large we will adopt it, and we will potentially then write to the me buffer. If we already have a bigger buffer, copy me into the existing buffer instead.
func (*PointerRingBuf) Advance ¶
func (b *PointerRingBuf) Advance(n int)
Advance(): non-standard, but better than Next(), because we don't have to unwrap our buffer and pay the cpu time for the copy that unwrapping may need. Useful in conjuction/after ReadWithoutAdvance() above.
func (*PointerRingBuf) Push ¶
func (b *PointerRingBuf) Push(p []interface{}) (n int, err error)
Push writes len(p) pointers from p to the ring. It returns the number of elements written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Push must return a non-nil error if it returns n < len(p).
func (*PointerRingBuf) PushAndMaybeOverwriteOldestData ¶
func (b *PointerRingBuf) PushAndMaybeOverwriteOldestData(p []interface{}) (n int, err error)
PushAndMaybeOverwriteOldestData always consumes the full slice p, even if that means blowing away the oldest unread pointers in the ring to make room. In reality, only the last min(len(p),b.N) bytes of p will end up being written to the ring.
This allows the ring to act as a record of the most recent b.N bytes of data -- a kind of temporal LRU cache, so the speak. The linux kernel's dmesg ring buffer is similar.
func (*PointerRingBuf) ReadPtrs ¶
func (b *PointerRingBuf) ReadPtrs(p []interface{}) (n int, err error)
ReadPtrs():
from bytes.Buffer.Read(): Read reads the next len(p) interface{} pointers from the buffer or until the buffer is drained. The return value n is the number of bytes read. If the buffer has no data to return, err is io.EOF (unless len(p) is zero); otherwise it is nil.
func (*PointerRingBuf) ReadWithoutAdvance ¶
func (b *PointerRingBuf) ReadWithoutAdvance(p []interface{}) (n int, err error)
ReadWithoutAdvance(): if you want to Read the data and leave it in the buffer, so as to peek ahead for example.
func (*PointerRingBuf) Reset ¶
func (b *PointerRingBuf) Reset()
Reset quickly forgets any data stored in the ring buffer. The data is still there, but the ring buffer will ignore it and overwrite those buffers as new data comes in.
func (*PointerRingBuf) TwoContig ¶
func (b *PointerRingBuf) TwoContig() (first []interface{}, second []interface{})
TwoContig returns all readable pointers, but in two separate slices, to avoid copying. The two slices are from the same buffer, but are not contiguous. Either or both may be empty slices.
func (*PointerRingBuf) WritePtrs ¶
func (b *PointerRingBuf) WritePtrs(p []interface{}) (n int, err error)
WritePtrs writes len(p) interface{} values from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p).
type TwoBuffers ¶
type TwoBuffers struct { First []byte // the first part of the contents Second []byte // the second part of the contents }
TwoBuffers: the return value of BytesTwo(). TwoBuffers holds two slices to the contents of the readable area of the internal buffer. The slices contents are logically ordered First then Second, but the Second will actually be physically before the First. Either or both of First and Second may be empty slices.