Documentation ¶
Overview ¶
package rbuf
package rbuf
package rbuf
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) 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 Ring
- type TwoBuffers
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AtomicFixedSizeRingBuf ¶ added in v0.3.1
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 ¶ added in v0.3.1
func NewAtomicFixedSizeRingBuf(maxViewInBytes int) *AtomicFixedSizeRingBuf
constructor. NewAtomicFixedSizeRingBuf will allocate internally two buffers of size maxViewInBytes.
func (*AtomicFixedSizeRingBuf) Adopt ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func (b *AtomicFixedSizeRingBuf) ContigLen() int
get 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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func (b *AtomicFixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error)
func (*AtomicFixedSizeRingBuf) ReadFrom ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func (b *AtomicFixedSizeRingBuf) Readable() int
Readable() returns the number of bytes available for reading.
func (*AtomicFixedSizeRingBuf) Reset ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func NewFixedSizeRingBuf(maxViewInBytes int) *FixedSizeRingBuf
constructor. NewFixedSizeRingBuf will allocate internally two buffers of size maxViewInBytes.
func (*FixedSizeRingBuf) Adopt ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func (f *FixedSizeRingBuf) Avail() int
func (*FixedSizeRingBuf) Bytes ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func (b *FixedSizeRingBuf) ContigLen() int
get 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 ¶ added in v0.3.1
func (f *FixedSizeRingBuf) DeleteMostRecentBytes(n int)
DeleteMostRecentBytes trims back the last n bytes written.
func (*FixedSizeRingBuf) First ¶ added in v0.3.1
func (f *FixedSizeRingBuf) First() int
returns the earliest index, or -1 if the ring is empty
func (*FixedSizeRingBuf) Kth ¶ added in v0.3.1
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 ¶ added in v0.3.1
func (f *FixedSizeRingBuf) Last() int
returns the index of the last element, or -1 if the ring is empty.
func (*FixedSizeRingBuf) LegalPos ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func (b *FixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error)
func (*FixedSizeRingBuf) ReadFrom ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 pointers available in A (in use) }
Float64RingBuf:
a fixed-size circular ring buffer of float64
func NewFloat64RingBuf ¶ added in v0.3.1
func NewFloat64RingBuf(maxViewInBytes int) *Float64RingBuf
constructor. NewFloat64RingBuf will allocate internally a slice of size maxViewInBytes.
func (*Float64RingBuf) Adopt ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func (b *Float64RingBuf) TwoContig(makeCopy bool) (first []float64, second []float64)
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 (*Float64RingBuf) Write ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
func NewPointerRingBuf(sliceN int) *PointerRingBuf
constructor. NewPointerRingBuf will allocate internally a slice of size sliceN
func (*PointerRingBuf) Adopt ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 ¶ added in v0.3.1
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.