…er clear/rollback
Senders cache designated-timestamp ColumnBuffer refs and derive
bookkeeping from their table buffers. rollbackUncommittedColumns()
(failed at()) and QwpTableBuffer.clear() close those columns, leaving
dangling refs that NPE on the next at() and corrupt pending accounting.
- Invalidate WebSocket timestamp caches in rollbackRow(); cancelRow()
now routes through it.
- Add QwpTableBuffer.Owner: clear() notifies the owning sender before
releasing columns. WebSocket subtracts the buffer's exact accounted
share (committedBytes - new baselineBytes, seed offsets excluded);
UDP resets transient row state, datagram estimate, and headroom
state (its base-estimate cache is keyed by column count alone).
- Unify flush snapshot anchoring at post-reset storage so per-table
contributions are exact under any reset/switch/flush history.
Hot path unchanged. Regressions: clear between rows (both units, both
senders), non-current/mid-row clear, accounting locality, stale
headroom estimate.
After rejecting an oversized timestamped row, a QWP sender could fail subsequent rows with a
NullPointerException. This fix keeps the sender usable after rollback and ensures auto-flush and UDP size calculations remain accurate after buffers are cleared or flushed.