gxring

package
v0.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 9, 2020 License: Apache-2.0, MIT Imports: 3 Imported by: 0

README

rbuf: a circular ring buffer in Golang

type FixedSizeRingBuf struct:

  • is a fixed-size circular ring buffer. Yes, just what is says. This structure is only for bytes, as it was written to optimize I/O, but could be easily adapted to any other type.

  • 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. If all you need is len(Bytes()), then it is better to use the FixedSizeRingBuf.Readable member directly. 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, unwrapped, 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.

copyright (c) 2014, Jason E. Aten

license: MIT

Documentation

Overview

package rbuf

package rbuf

package rbuf

Index

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 Ring added in v0.3.2

type Ring struct {
	// contains filtered or unexported fields
}

func NewRing added in v0.3.2

func NewRing(capacity int) *Ring

func (*Ring) Capacity added in v0.3.2

func (b *Ring) Capacity() int

func (*Ring) Clear added in v0.3.2

func (b *Ring) Clear()

func (*Ring) Empty added in v0.3.2

func (b *Ring) Empty() bool

func (*Ring) FreeSize added in v0.3.2

func (b *Ring) FreeSize() int

func (*Ring) Full added in v0.3.2

func (b *Ring) Full() bool

func (*Ring) Read added in v0.3.2

func (b *Ring) Read(data []byte) int

func (*Ring) Size added in v0.3.2

func (b *Ring) Size() int

func (*Ring) Write added in v0.3.2

func (b *Ring) Write(data []byte) bool

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL