feat(sparql-anything): chunk a stream of lines, not only a file - #865
Merged
Merged
Conversation
- Accept an AsyncIterable<string> of lines next to a path, so a caller that filters rows or adds a column no longer writes a table to disk only for chunk() to read it back and write the same bytes again - Add ‘name’ to ChunkOptions: what the chunks are called after, defaulting to a path input's file name and required for a stream, which has none - Stop pulling lines once a write has failed, so a producer that is itself a pipeline does not keep reading long after there is anywhere to put it
- Refuse a value that carries a line ending of its own, naming it, rather than writing it as the several rows it would become – which would put more in a chunk than ‘rows’ says it holds - Drop a trailing ‘\r’, the normalisation a file already gets from readline - Name the mistake of handing chunk() a byte stream, whose values fall where the reads did rather than on lines, and which satisfies the type - Require ‘extension’ for a stream, as ‘name’ already is: defaulting to none hands back chunks SPARQL Anything cannot classify
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
chunk()took a path, so a caller with work to do before chunking – filtering rows out, adding a column – had to write its result to disk only forchunk()to read it back and write the same bytes again. In geonames-rdf that is about 2.4 GB written and read per weekly run, with peak disk holding a table and its chunks at once.It now takes a stream of lines as well:
Anything that yields lines will do: an async generator, or a
Readablein string mode.What a stream has to say for itself
ChunkOptionsgainsname, andextensionloses its default for a stream. Both are required of one, and the overload asks for them:nameis what the chunks are called after. It defaults to a path input's file name, which is where chunk names came from until now. A stream has none, and a call that leaves it out anyway is rejected with a message rather than producing-0000files. A name that is a path is rejected too, since it would write chunks outsideinto.extensiondecides how a chunk is read – SPARQL Anything takes the format from the name – so defaulting it to none for a stream would hand back chunks this package's own converter cannot classify.''says none, explicitly.One value, one row
A value carrying a line ending of its own is counted as one row and written as several, so a chunk would hold more than
rowssays – the number a conversion's memory is sized against (ADR 12). It is now refused, naming the value, and a trailing\ris dropped, which is the normalisation a file already gets fromreadline.That check also catches a byte stream.
createReadStream()yields buffers that fall wherever the reads did rather than on lines, and aReadablesatisfies the type, so without it the records would be cut at a 64 KB boundary and nothing would say so.Failing
A write that fails now stops the lines being pulled. For a file that was already the case, by closing the reader; a stream is pulled a value at a time, so the loop checks and breaks instead, and a producer that is itself a pipeline is not left reading its own input long after there is anywhere to put it.
Everything else is unchanged: the loop body,
removeChunksOf()keying on the name, the refusal of an input with no rows. Chunking a path keeps working exactly as before.Fix #830