Documentation
¶
Overview ¶
Package triplebuffer exposes a potentially viable triple-buffer system for managing data between a producer and consumer where avoiding read/write deadlocks might be problematic. Don't trust anything in this package for Production (prod) usage, oh my god.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Buffer ¶
type Buffer[T any] struct { // contains filtered or unexported fields }
Buffer is a triple buffer! Enjoy! A Buffer has three (private) fields, to wit:
- back: the Back buffer, which is whatever a producer is working on. This is a pointer, so it is modifiable after setting without any extra work. Initially set by Write, then promoted via atomic swap to the Middle buffer by calling Commit after the producer has finished whatever it needs to do with the data.
- middle: the Middle buffer, also known as the very special atomic buffer. Data in the Middle buffer can be in one of two states: "pending", or "stale". Pending data is that which has been committed (via Commit), and is considered new data. When Read is next called, the new data will be promoted to the Front buffer, with the previous Front buffer data being atomically swapped into the Middle buffer and marked as "stale". Stale data has been consumed already.
- front: the Front buffer. Whatever is in here will be returned by Read if there is no pending data in the Middle buffer. If there is pending data in Middle, that data gets promoted and returned by Read.
Note that Commit can (and, likely at some point *will*) overwrite whatever is in the Middle buffer, even if that data is still pending a read.
func NewBufferWithFront ¶
NewBufferWithFront returns a Buffer with the Front buffer populated, (ie it's ready to CONSUME!)
func NewPopulatedBuffer ¶
NewPopulatedBuffer returns a fully populated Buffer. Good luck. Note: the Middle buffer item (`middle`) will be considered Pending (ie. fresh off the line from a producer, and subject to swappage when Buffer.Read is called).
func (*Buffer[T]) Commit ¶
func (b *Buffer[T]) Commit()
Commit is called once whatever data in the Back buffer has finished being created. On commit, the following happens: Back buffer is promoted to the Middle buffer. Middle buffer is swapped into the Back buffer, which is more or less useless.
func (*Buffer[T]) Read ¶
Read is part of the consumer API. It returns the value currently in the Front buffer. If the value currently in the Middle buffer is pending, (ie. it has just been written to by a producer) then the Front and Middle buffers will be swapped and the *new* Front buffer returned. Otherwise, the stale Front buffer value will be returned. If there is no value in the Middle buffer, no swap occurs. The returned boolean corresponds to whether the value is "stale": false, or "pending": true.