Skip to content

DatasetReader holds back a complete row on a live stream #171

Closed

Description

@bfrancojr

On a stream that stays open (a pipe, a socket, a file still being appended to), DatasetReader can hold a complete row until more bytes arrive or the stream ends. protowire-go returns the row as soon as its ) has been read. Go pins this in TestDatasetReader_CompleteRowIsNotHeldBack (encoding/pxf/dataset_scan_linear_test.go, #149 there): it writes a header and one row into a pipe one byte at a time, leaves the pipe open, and requires Next to return within 10 s for 16 row shapes.

Two causes, both from reading the code (not measured with a pipe)

  1. The read blocks for a full chunk. DatasetReader::Pull calls std::istream::read(buf, 4096), which returns only once it has 4096 bytes or the input has ended. Go's io.Reader.Read returns whatever is there. So on a live stream, cpp waits for 4096 more bytes, or the end, even when the buffer already holds a complete row.
  2. The scan's lookahead (PR pxf: DatasetReader ends a table only at the end of input or a directive (#164) #167). cpp's lexer has no sawEnd, so DatasetReader::Complete takes a token as complete only once four bytes follow it or the source has ended. A row whose ) is the last byte read waits for four more bytes. Go's lexer knows a one-byte token such as ) is complete. The fast path (TryWholeRow) covers a row that is already whole when Next starts. The scan path, for a row that arrived across reads, does not.

On input that ends, neither changes a result, only when the row is returned. The 590-case sweep in #167 matches Go.

Done when

  • Pull returns what the stream has without waiting for a full chunk, e.g. readsome, or rdbuf()->sgetn after in_avail, with a blocking read of at least one byte only when nothing is buffered. Which of these is a design choice to make in the PR.
  • A token whose end the lexer did not need to look past is complete at once. At least the one-byte punctuation tokens are, and ideally the lexer gets Go's sawEnd.
  • A test in the shape of Go's: one row per case, fed byte by byte through a stream that stays open, returned by Next without the stream ending.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions