StormByte-Buffer 2.0.0
C++26 buffer module of the StormByte suite
 
Loading...
Searching...
No Matches
StormByte::Buffer::IO::BufferedWriter Class Referenceabstract

Coordinated binary write sink with optional chunked write-behind and a delayed-seek page map. More...

#include <StormByte/buffer/io/buffered_writer.hxx>

Inheritance diagram for StormByte::Buffer::IO::BufferedWriter:

Classes

class  Parameters
 Writer knobs. More...
 

Public Member Functions

const StormByte::String::String & Path () const noexcept
 Locator stored at construction.
 
enum Location Location () const noexcept
 Where Path points.
 
virtual operator bool () const noexcept final
 Whether the sink is prepared to write.
 
virtual enum State State () const noexcept final
 Session state.
 
Lifecycle
 BufferedWriter (const BufferedWriter &)=delete
 Copy constructor is deleted.
 
 BufferedWriter (BufferedWriter &&other) noexcept
 Move constructor.
 
virtual ~BufferedWriter () noexcept
 Virtual destructor.
 
BufferedWriter & operator= (const BufferedWriter &)=delete
 Copy assignment is deleted.
 
BufferedWriter & operator= (BufferedWriter &&other) noexcept
 Move assignment.
 
Session
virtual bool Open () final
 Arm the origin.
 
virtual bool Close () final
 Flush then close the origin.
 
virtual bool Rewind () final
 Re-arm: Close then Open when currently armed.
 
virtual bool IsOpen () const noexcept final
 Whether Open succeeded and Close has not.
 
virtual Result Flush () final
 Materialise every dirty page, drain the ring and OriginFlush.
 
virtual Result Truncate () final
 Drop dirty pages and the ring, then truncate the origin.
 
Write
virtual Result Write (const FIFO &src) final
 Write every unread byte of src.
 
virtual Result Write (FIFO &src) final
 Write every unread byte of src.
 
virtual Result Write (std::span< const std::byte > src) final
 Write the whole span.
 
Position
virtual StormByte::ByteSize Tell () const noexcept
 Logical write offset.
 
virtual StormByte::ByteSize Dirty () const noexcept
 Bytes not yet on the origin.
 
virtual StormByte::ByteSize Size () const noexcept
 Logical sink length in bytes.
 
virtual Result Seek (std::ptrdiff_t offset, Position mode)
 Move the write cursor.
 
Telemetry
const StormByte::Shared< StormByte::Buffer::WriteTelemetry > Telemetry () const noexcept
 Shared write counters.
 
Policy
virtual StormByte::ByteSize WriteChunk () const noexcept
 Configured origin push unit.
 
virtual void WriteChunk (StormByte::ByteSize bytes)
 Set origin push unit.
 
virtual std::size_t BackPressure () const noexcept
 Configured dirty cap in WriteChunk units.
 
virtual void BackPressure (std::size_t chunks)
 Set dirty cap in WriteChunk units.
 
virtual StormByte::ByteSize MaxMemory () const noexcept
 Byte budget for dirty pages that are not yet on the origin.
 
virtual void MaxMemory (StormByte::ByteSize bytes)
 Set the dirty-page budget.
 
virtual std::chrono::milliseconds MaxWait () const noexcept
 Wait cap for OriginPush.
 
virtual void MaxWait (std::chrono::milliseconds wait)
 Set wait cap for OriginPush.
 

Protected Member Functions

STORMBYTE_FORCE_INLINE BufferedWriter (StormByte::String::String path, enum Location location, Parameters parameters={})
 Construct an unopened coordinator (State::Unavailable).
 
 BufferedWriter (StormByte::String::String path, enum Location location, StormByte::ByteSize write_chunk, std::size_t back_pressure, std::chrono::milliseconds max_wait, StormByte::ByteSize max_memory)
 Construct an unopened coordinator (State::Unavailable).
 
void SetState (enum State state) noexcept
 Publish session state from a leaf hook.
 
void SetTell (StormByte::ByteSize offset) noexcept
 Publish the logical write offset from a leaf Seek.
 
virtual void Setup ()
 Leaf policy hook.
 
virtual StormByte::Shared< StormByte::Buffer::WriteTelemetry > CreateTelemetry () const
 Allocate the telemetry object this instance will keep.
 
virtual bool WillWrite (StormByte::ByteSize n) const
 Whether n more bytes can be accepted now.
 
Origin hooks
virtual Result OriginOpen ()=0
 Arm the device and SetState.
 
virtual Result OriginClose ()=0
 Release the device and SetState Unavailable.
 
virtual Result OriginPush (std::span< const std::byte > data)=0
 Write data to the device.
 
virtual Result OriginFlush ()=0
 Make accepted bytes visible on the device.
 
virtual Result OriginTruncate ()=0
 Discard origin contents.
 
virtual Result OriginSeek (StormByte::ByteSize absolute)
 Seek the origin to absolute.
 

Friends

class StormByte::Buffer::Backend::IO::BufferedWriter
 
class StormByte::Buffer::Backend::Bridge
 

Detailed Description

Coordinated binary write sink with optional chunked write-behind and a delayed-seek page map.

Public base for byte destinations. Leaves implement the Origin* hooks and may override Setup, Seek, Size, WillWrite and CreateTelemetry. They do not override Write, Flush, Open, Close, Rewind or Truncate.

Binary only
Octets only. No text mode.
Session
Construction is State::Unavailable. A successful Open moves to State::Idle. Close is idempotent, always Flush then OriginClose, and returns to State::Unavailable on success or State::Fault if Flush failed. Open is not idempotent. Close then Open is a valid round-trip. Destructor of a leaf must call Close while the leaf vtable is live.

operator bool is true when State is Idle.

Write
Write consumes the whole visible source or nothing (atomic). FIFO is read from the current read position (FIFO::Read is const; the cursor is mutable). The FIFO / span is left untouched on Status::TryAgain, Status::Failed and Status::Error.
Lazy write / MaxMemory
Every Write is lazy until MaxMemory. The origin is touched only when dirty pages exceed MaxMemory (GC), or on Flush / Close. MaxMemory == 0 stores no pages: each Write goes to the origin (and to the ring when both ring knobs are on).

This is not magic RAM. Local seeks and seeks into a still-dirty past stay in the map. Distant random writes need a larger MaxMemory or the farthest-past island is evicted to the origin (that eviction is real I/O and may block). A jump far ahead is supported only while it fits; it is not the typical case. The typical case is a correction near the write high-water and a seek back to that front.

GC evicts the farthest past first, in a contiguous run, so one OriginSeek covers a cheap sequential push. Future islands are evicted only when no evictable past remains.

A durable-progress ratio is Materialized / HighWater when HighWater > 0. HighWater is the maximum logical cursor this session. Tell is the cursor and may sit behind HighWater. Materialized is what the origin already holds. Do not use Accepted or Tell as the denominator. After a sequential session Close, Materialized equals HighWater.

WriteChunk / BackPressure
Either ring knob 0 disables the drain pipe. Both > 0 enable an internal SPSC ring used only to push a GC / Flush / Close run. Capacity is BackPressure * WriteChunk bytes. A Write that would exceed that cap returns Status::TryAgain. The worker does not empty the page map just because the origin cursor is aligned.

Setters take effect immediately. Turning the ring off or lowering the cap below Dirty flushes dirty bytes first and may block. Setting MaxMemory does not Flush and does not resize the ring.

Flush / Truncate
Flush blocks, materialises every dirty page in offset order (with the OriginSeek calls that need), drains the ring, calls OriginFlush, and never returns Status::TryAgain. Flush is not where seek elision happens. Truncate drops the map and the ring without pushing and calls OriginTruncate. Tell, HighWater and Materialized become 0.

Public Flush and the Flush inside Close count toward MeanRate. Internal worker / GC drains do not. A cache Write can look like GiB/s; that is the caller rate. The explicit Flush is what reflects the origin.

Seek / Size
Seek moves only Tell. It does not call OriginSeek and does not Flush. Default Seek fails when the leaf has no usable OriginSeek (the base hook fails). A file leaf uses the base implementation.

Typical correction inside resident dirty pages is O(1) with respect to the device. A Write / Seek that trips GC may block on origin I/O on purpose: random access on a slow device is more expensive than that wait.

Default Size is Tell (includes dirty pages). A file leaf returns max(filesystem size, Tell).

MaxWait
Applies to the next OriginPush (direct Write or worker). 0ms waits without limit. The ring itself is not timed. Setting MaxWait does not abort an in-flight push.
WillWrite
Protected probe used by StormByte::Buffer::Backend::Bridge. Default asks the ring cap. Leaves may tighten it (disk space, socket). The answer is indicative: another process, quotas or a network filesystem can still make the later Write fail.
Telemetry
Telemetry returns a const StormByte::Shared of StormByte::Buffer::WriteTelemetry. The user cannot reseat the handle. The office updates the same object. Default dynamic type is IO::WriteTelemetry. Accumulators start at construction and do not reset on Close. Materialized and HighWater are levels, not accumulators. MeanRate is the caller rate, not disk throughput.
Movable, not copyable
Move transfers m_io. The worker is not stopped. Moved-from is Unavailable.
See also
Status, State, Result, FIFO, StormByte::Buffer::Backend::IO::BufferedWriter

Constructor & Destructor Documentation

◆ BufferedWriter() [1/4]

Copy constructor is deleted.

◆ BufferedWriter() [2/4]

Move constructor.

Parameters
otherInstance to take from. Left Unavailable.

◆ ~BufferedWriter()

virtual StormByte::Buffer::IO::BufferedWriter::~BufferedWriter ( )
virtualnoexcept

Virtual destructor.

Stops the worker. Does not call Origin*.

Leaves must call Close in their destructor.

◆ BufferedWriter() [3/4]

Construct an unopened coordinator (State::Unavailable).

Parameters
pathLocator. Stored once.
locationLocation::Local or Location::Remote. Stored once.
parametersOmitted knobs are 0 / 0 ms. Resolved in the caller.

◆ BufferedWriter() [4/4]

StormByte::Buffer::IO::BufferedWriter::BufferedWriter ( StormByte::String::String  path,
enum Location  location,
StormByte::ByteSize  write_chunk,
std::size_t  back_pressure,
std::chrono::milliseconds  max_wait,
StormByte::ByteSize  max_memory 
)
protected

Construct an unopened coordinator (State::Unavailable).

Parameters
pathLocator. Stored once.
locationLocation::Local or Location::Remote. Stored once.
write_chunkInitial WriteChunk in bytes.
back_pressureInitial BackPressure in chunk units.
max_waitInitial MaxWait.
max_memoryInitial MaxMemory in bytes.

DLL boundary. Children that already resolved knobs call this.

Member Function Documentation

◆ BackPressure() [1/2]

virtual std::size_t StormByte::Buffer::IO::BufferedWriter::BackPressure ( ) const
virtualnoexcept

Configured dirty cap in WriteChunk units.

Returns
Chunk count. 0 disables the ring.

◆ BackPressure() [2/2]

virtual void StormByte::Buffer::IO::BufferedWriter::BackPressure ( std::size_t  chunks)
virtual

Set dirty cap in WriteChunk units.

Takes effect immediately.

Parameters
chunks0 disables the ring. Otherwise cap is chunks * WriteChunk.

May block. Zero, or a cap below Dirty, flushes dirty bytes before the setter returns. Not deferred to the next Write.

◆ Close()

virtual bool StormByte::Buffer::IO::BufferedWriter::Close ( )
finalvirtual

Flush then close the origin.

Returns
true if State is Unavailable afterwards.

Idempotent on an already closed instance. Blocking. Flush failure leaves State::Fault and returns false. The Flush counts toward MeanRate.

◆ CreateTelemetry()

virtual StormByte::Shared< StormByte::Buffer::WriteTelemetry > StormByte::Buffer::IO::BufferedWriter::CreateTelemetry ( ) const
protectedvirtual

Allocate the telemetry object this instance will keep.

Returns
Shared handle. Default is IO::WriteTelemetry.

Called once, after the most-derived constructor, the first time telemetry is needed. Must not return empty.

◆ Dirty()

virtual StormByte::ByteSize StormByte::Buffer::IO::BufferedWriter::Dirty ( ) const
virtualnoexcept

Bytes not yet on the origin.

Returns
Page map plus drain pipe. 0 after a successful Flush.

◆ Flush()

virtual Result StormByte::Buffer::IO::BufferedWriter::Flush ( )
finalvirtual

Materialise every dirty page, drain the ring and OriginFlush.

Returns
Status::Ok, Status::Error or Status::Failed. Never Status::TryAgain.

Blocking. Tell is unchanged. Counts toward MeanRate. Internal worker drains do not.

◆ IsOpen()

virtual bool StormByte::Buffer::IO::BufferedWriter::IsOpen ( ) const
finalvirtualnoexcept

Whether Open succeeded and Close has not.

Returns
true if the session is armed.

◆ Location()

enum Location StormByte::Buffer::IO::BufferedWriter::Location ( ) const
noexcept

Where Path points.

Does not change.

Returns
Location::Local or Location::Remote. Location::Local if moved-from.

◆ MaxMemory() [1/2]

virtual StormByte::ByteSize StormByte::Buffer::IO::BufferedWriter::MaxMemory ( ) const
virtualnoexcept

Byte budget for dirty pages that are not yet on the origin.

Returns
Bytes. 0 stores no page map (eager origin writes).

Independent of WriteChunk / BackPressure.

◆ MaxMemory() [2/2]

virtual void StormByte::Buffer::IO::BufferedWriter::MaxMemory ( StormByte::ByteSize  bytes)
virtual

Set the dirty-page budget.

Takes effect immediately.

Parameters
bytes0 disables the page map.

Does not Flush. Does not resize the ring. A value below current dirty pages trips GC and may block.

◆ MaxWait() [1/2]

virtual std::chrono::milliseconds StormByte::Buffer::IO::BufferedWriter::MaxWait ( ) const
virtualnoexcept

Wait cap for OriginPush.

Returns
0ms waits without limit.

◆ MaxWait() [2/2]

virtual void StormByte::Buffer::IO::BufferedWriter::MaxWait ( std::chrono::milliseconds  wait)
virtual

Set wait cap for OriginPush.

Takes effect on the next push.

Parameters
wait0ms = unlimited.

Does not cancel an in-flight OriginPush. Does not Flush.

◆ Open()

virtual bool StormByte::Buffer::IO::BufferedWriter::Open ( )
finalvirtual

Arm the origin.

Returns
true if State is Idle afterwards.

Calls Setup then the backend Open. Not idempotent.

◆ operator bool()

virtual StormByte::Buffer::IO::BufferedWriter::operator bool ( ) const
explicitfinalvirtualnoexcept

Whether the sink is prepared to write.

Returns
true if State is State::Idle.

◆ operator=() [1/2]

BufferedWriter & StormByte::Buffer::IO::BufferedWriter::operator= ( BufferedWriter &&  other)
noexcept

Move assignment.

Parameters
otherInstance to take from. Left Unavailable.
Returns
*this.

◆ operator=() [2/2]

BufferedWriter & StormByte::Buffer::IO::BufferedWriter::operator= ( const BufferedWriter &  )
delete

Copy assignment is deleted.

Returns
*this.

◆ OriginClose()

virtual Result StormByte::Buffer::IO::BufferedWriter::OriginClose ( )
protectedpure virtual

Release the device and SetState Unavailable.

Returns
Status::Ok or Status::Failed.

Implemented in StormByte::Buffer::IO::BufferedFileWriter.

◆ OriginFlush()

virtual Result StormByte::Buffer::IO::BufferedWriter::OriginFlush ( )
protectedpure virtual

Make accepted bytes visible on the device.

Returns
Status::Ok, Error or Failed.

The base calls this after a completed direct Write and after Flush has drained the ring. Do not buffer here.

Implemented in StormByte::Buffer::IO::BufferedFileWriter.

◆ OriginOpen()

virtual Result StormByte::Buffer::IO::BufferedWriter::OriginOpen ( )
protectedpure virtual

Arm the device and SetState.

Returns
Status::Ok or Status::Failed.

Implemented in StormByte::Buffer::IO::BufferedFileWriter.

◆ OriginPush()

virtual Result StormByte::Buffer::IO::BufferedWriter::OriginPush ( std::span< const std::byte >  data)
protectedpure virtual

Write data to the device.

Do not buffer in the hook.

Parameters
dataContiguous octets. May be a full WriteChunk or a tail.
Returns
Ok with count == data.size(), Ok with a short count (backend retries), Error or Failed.

Implemented in StormByte::Buffer::IO::BufferedFileWriter.

◆ OriginSeek()

virtual Result StormByte::Buffer::IO::BufferedWriter::OriginSeek ( StormByte::ByteSize  absolute)
protectedvirtual

Seek the origin to absolute.

Parameters
absoluteByte offset from the start.
Returns
Status::Ok or Status::Failed.

Default fails. File and remote leaves override this. Public Seek does not call this; GC / Flush / Close do.

Reimplemented in StormByte::Buffer::IO::BufferedFileWriter, and StormByte::Buffer::IO::BufferedLocationWriter.

◆ OriginTruncate()

virtual Result StormByte::Buffer::IO::BufferedWriter::OriginTruncate ( )
protectedpure virtual

Discard origin contents.

Network may no-op Ok.

Returns
Status::Ok or Status::Failed.

Implemented in StormByte::Buffer::IO::BufferedFileWriter.

◆ Path()

const StormByte::String::String & StormByte::Buffer::IO::BufferedWriter::Path ( ) const
noexcept

Locator stored at construction.

Does not change.

A file path, socket://… or http://… . A file leaf's path is always a local filesystem path.

Returns
Owned text. Empty if moved-from.

◆ Rewind()

virtual bool StormByte::Buffer::IO::BufferedWriter::Rewind ( )
finalvirtual

Re-arm: Close then Open when currently armed.

Returns
true if Idle afterwards.

◆ Seek()

virtual Result StormByte::Buffer::IO::BufferedWriter::Seek ( std::ptrdiff_t  offset,
Position  mode 
)
virtual

Move the write cursor.

Parameters
offsetByte offset.
modePosition::Absolute or Position::Relative.
Returns
Status::Ok or Status::Failed.

Updates Tell only. Does not Flush. Does not call OriginSeek. Fails when the leaf OriginSeek cannot move the device (default hook). O(1) for a typical in-cache correction; may block later when a Write trips GC.

◆ SetState()

void StormByte::Buffer::IO::BufferedWriter::SetState ( enum State  state)
protectednoexcept

Publish session state from a leaf hook.

Parameters
stateNew State.

◆ SetTell()

void StormByte::Buffer::IO::BufferedWriter::SetTell ( StormByte::ByteSize  offset)
protectednoexcept

Publish the logical write offset from a leaf Seek.

Parameters
offsetNew Tell.

◆ Setup()

virtual void StormByte::Buffer::IO::BufferedWriter::Setup ( )
protectedvirtual

Leaf policy hook.

Called from Open before the origin.

Default does nothing. File uses it for the path-only ctor. The most-derived vtable is live.

Reimplemented in StormByte::Buffer::IO::BufferedLocationWriter.

◆ Size()

virtual StormByte::ByteSize StormByte::Buffer::IO::BufferedWriter::Size ( ) const
virtualnoexcept

Logical sink length in bytes.

Returns
Length. Default is Tell (includes dirty pages).

Not optional. A file leaf returns max(filesystem size, Tell). A remote leaf overrides this.

Reimplemented in StormByte::Buffer::IO::BufferedLocationWriter.

◆ State()

virtual enum State StormByte::Buffer::IO::BufferedWriter::State ( ) const
finalvirtualnoexcept

Session state.

Returns
Current State.

◆ Telemetry()

const StormByte::Shared< StormByte::Buffer::WriteTelemetry > StormByte::Buffer::IO::BufferedWriter::Telemetry ( ) const
noexcept

Shared write counters.

Same instance for the life of this writer.

Returns
Const handle. Empty if moved-from.

The user cannot reseat the handle. The office updates the same object. Survivors keep the last values.

◆ Tell()

virtual StormByte::ByteSize StormByte::Buffer::IO::BufferedWriter::Tell ( ) const
virtualnoexcept

Logical write offset.

Returns
Cursor published to the caller. Includes unflushed pages.

◆ Truncate()

virtual Result StormByte::Buffer::IO::BufferedWriter::Truncate ( )
finalvirtual

Drop dirty pages and the ring, then truncate the origin.

Returns
Status::Ok or Status::Failed.

Does not push. Sets Tell, HighWater and Materialized to 0.

◆ WillWrite()

virtual bool StormByte::Buffer::IO::BufferedWriter::WillWrite ( StormByte::ByteSize  n) const
protectedvirtual

Whether n more bytes can be accepted now.

Parameters
nByte count to probe.
Returns
true if the ring (or direct mode) can take n.

Indicative. Another writer, quotas or the filesystem can still reject the later Write. Override to tighten (disk space, socket window). Used by StormByte::Buffer::Backend::Bridge.

Reimplemented in StormByte::Buffer::IO::BufferedFileWriter.

◆ Write() [1/3]

virtual Result StormByte::Buffer::IO::BufferedWriter::Write ( const FIFO &  src)
finalvirtual

Write every unread byte of src.

Parameters
srcSource FIFO. Read from the current position.
Returns
Status and bytes accepted. Source untouched unless Ok.

◆ Write() [2/3]

virtual Result StormByte::Buffer::IO::BufferedWriter::Write ( FIFO &  src)
finalvirtual

Write every unread byte of src.

Parameters
srcSource FIFO. Read from the current position.
Returns
Status and bytes accepted. Source untouched unless Ok.

◆ Write() [3/3]

virtual Result StormByte::Buffer::IO::BufferedWriter::Write ( std::span< const std::byte >  src)
finalvirtual

Write the whole span.

Parameters
srcOctets to copy.
Returns
Status and bytes accepted. Source untouched unless Ok.

◆ WriteChunk() [1/2]

virtual StormByte::ByteSize StormByte::Buffer::IO::BufferedWriter::WriteChunk ( ) const
virtualnoexcept

Configured origin push unit.

Returns
Bytes. 0 disables the ring (with BackPressure 0).

◆ WriteChunk() [2/2]

virtual void StormByte::Buffer::IO::BufferedWriter::WriteChunk ( StormByte::ByteSize  bytes)
virtual

Set origin push unit.

Takes effect immediately.

Parameters
bytesChunk size. 0 disables the ring.

May block. A zero value or a smaller unit that now meets dirty bytes drains the ring through Flush / the worker before the setter returns. Not deferred to the next Write.

Friends And Related Symbol Documentation

◆ StormByte::Buffer::Backend::Bridge

friend class StormByte::Buffer::Backend::Bridge
friend

◆ StormByte::Buffer::Backend::IO::BufferedWriter

friend class StormByte::Buffer::Backend::IO::BufferedWriter
friend

The documentation for this class was generated from the following file: